Ticket #6256: archiving.2.patch
File archiving.2.patch, 26.0 KB (added by , 14 years ago) |
---|
-
headers/os/support/Archivable.h
7 7 8 8 9 9 #include <image.h> 10 #include <Message.h> 10 11 #include <SupportDefs.h> 11 12 12 13 14 #define NULL_TOKEN -42 15 13 16 class BMessage; 14 17 15 18 namespace BPrivate { … … 38 41 virtual status_t AllArchived(BMessage* archive) const; 39 42 40 43 private: 44 friend class BUnarchiveManager; 45 41 46 virtual void _ReservedArchivable3(); 42 47 43 uint32 _reserved[2]; 48 int32 fArchivingToken; 49 uint32 _reserved; 44 50 }; 45 51 46 52 … … 52 58 status_t AddArchivable(const char* name, 53 59 BArchivable* archivable, bool deep = true); 54 60 61 inline status_t GetTokenForArchivable(BArchivable* archivable, 62 int32& _token); 55 63 status_t GetTokenForArchivable(BArchivable* archivable, 56 int32& _token, bool deep = true);64 bool deep, int32& _token); 57 65 58 66 bool IsArchived(BArchivable* archivable); 59 status_t Finish( );67 status_t Finish(status_t err = B_OK); 60 68 BMessage* ArchiveMessage() const; 61 69 62 70 private: … … 71 79 BArchiveManager* fManager; 72 80 BMessage* fArchive; 73 81 bool fFinished; 82 uint32 _reserved[2]; 74 83 }; 75 84 76 85 … … 79 88 BUnarchiver(const BMessage* archive); 80 89 ~BUnarchiver(); 81 90 82 status_t GetArchivable(int32 token,83 BArchivable** archivable);91 template<class T> 92 inline status_t GetObject(int32 token, T*& object); 84 93 85 status_t FindArchivable(const char* name, 86 BArchivable** archivable); 94 template<class T> 95 status_t GetObject(int32 token, ownership owning, 96 T*& object); 87 97 88 status_t FindArchivable(const char* name, int32 index,89 BArchivable** archivable);98 template<class T> 99 inline status_t FindObject(const char* name, T*& object); 90 100 91 status_t EnsureUnarchived(const char* name, 101 template<class T> 102 inline status_t FindObject(const char* name, ownership owning, 103 T*& object); 104 105 template<class T> 106 inline status_t FindObject(const char* name, 107 int32 index, T*& object); 108 109 template<class T> 110 status_t FindObject(const char* name, int32 index, 111 ownership owning, T*& object); 112 113 inline status_t EnsureUnarchived(const char* name, 92 114 int32 index = 0); 93 115 inline status_t EnsureUnarchived(int32 token); 94 116 95 117 bool IsInstantiated(int32 token); 96 118 bool IsInstantiated(const char* name, 97 119 int32 index = 0); 98 120 99 status_t Finish( );121 status_t Finish(status_t err = B_OK); 100 122 const BMessage* ArchiveMessage() const; 101 123 124 void AssumeOwnership(BArchivable* archivable); 125 void RelinquishOwnership(BArchivable* archivable); 126 102 127 static bool IsArchiveManaged(BMessage* archive); 103 128 static BMessage* PrepareArchive(BMessage*& archive); 104 129 130 template<class T> 131 static status_t InstantiateObject(BMessage* archive, 132 T*& object); 133 105 134 private: 106 135 friend class BArchivable; 107 136 … … 110 139 111 140 void RegisterArchivable(BArchivable* archivable); 112 141 113 142 inline void _CallDebuggerIfManagerNull(); 114 143 115 144 BUnarchiveManager* fManager; 116 145 const BMessage* fArchive; 117 146 bool fFinished; 147 uint32 _reserved[2]; 118 148 }; 119 149 120 150 … … 131 161 instantiation_func find_instantiation_func(const char* className); 132 162 instantiation_func find_instantiation_func(BMessage* archive); 133 163 164 165 status_t 166 BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token) 167 { 168 return GetTokenForArchivable(archivable, true, _token); 169 } 170 171 172 template<> 173 status_t BUnarchiver::FindObject<BArchivable>(const char* name, int32 index, 174 ownership owning, BArchivable*& archivable); 175 176 177 template<class T> 178 status_t 179 BUnarchiver::FindObject(const char* name, int32 index, 180 ownership owning, T*& object) 181 { 182 object = NULL; 183 184 BArchivable* interim; 185 status_t err = FindObject(name, index, owning, interim); 186 187 if (err == B_OK && interim) { 188 object = dynamic_cast<T*>(interim); 189 if (!object) { 190 err = B_BAD_TYPE; 191 // we will not be deleting this item, but it must be deleted 192 if (owning == B_ASSUME_OWNERSHIP) 193 RelinquishOwnership(interim); 194 } 195 } 196 return err; 197 } 198 199 200 template<> 201 status_t 202 BUnarchiver::GetObject<BArchivable>(int32 token, 203 ownership owning, BArchivable*& object); 204 205 206 template<class T> 207 status_t 208 BUnarchiver::GetObject(int32 token, ownership owning, T*& object) 209 { 210 object = NULL; 211 212 BArchivable* interim; 213 status_t err = GetObject(token, owning, interim); 214 215 if (err == B_OK && interim) { 216 object = dynamic_cast<T*>(interim); 217 if (!object) { 218 err = B_BAD_TYPE; 219 // we will not be deleting this item, but it must be deleted 220 if (owning == B_ASSUME_OWNERSHIP) 221 RelinquishOwnership(interim); 222 } 223 } 224 return err; 225 } 226 227 228 template<class T> 229 status_t 230 BUnarchiver::GetObject(int32 token, T*& object) 231 { 232 return GetObject<T>(token, B_ASSUME_OWNERSHIP, object); 233 } 234 235 236 template<class T> 237 status_t 238 BUnarchiver::FindObject(const char* name, ownership owning, T*& object) 239 { 240 return FindObject(name, 0, owning, object); 241 } 242 243 244 template<class T> 245 status_t 246 BUnarchiver::FindObject(const char* name, T*& object) 247 { 248 return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object); 249 } 250 251 252 template<class T> 253 status_t 254 BUnarchiver::FindObject(const char* name, 255 int32 index, T*& object) 256 { 257 return FindObject(name, index, B_ASSUME_OWNERSHIP, object); 258 } 259 260 261 status_t 262 BUnarchiver::EnsureUnarchived(int32 token) 263 { 264 BArchivable* dummy; 265 return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy); 266 } 267 268 269 status_t 270 BUnarchiver::EnsureUnarchived(const char* name, int32 index) 271 { 272 BArchivable* dummy; 273 return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy); 274 } 275 276 277 template<class T> 278 status_t 279 BUnarchiver::InstantiateObject(BMessage* archive, T*& object) 280 { 281 object = NULL; 282 BUnarchiver unarchiver(BUnarchiver::PrepareArchive(archive)); 283 BArchivable* archivable = instantiate_object(archive); 284 status_t err = unarchiver.Finish(); 285 if (err == B_OK && archivable) { 286 object = dynamic_cast<T*>(archivable); 287 if (!object) 288 err = B_BAD_TYPE; 289 } 290 291 if (err != B_OK) 292 delete archivable; 293 294 return err; 295 } 296 297 134 298 #endif // _ARCHIVABLE_H -
headers/private/binary_compatibility/Support.h
2 2 * Copyright 2010, Haiku, Inc. 3 3 * Distributed under the terms of the MIT License. 4 4 */ 5 #ifndef _BINARY_COMPATIBILITY_SUPPORT_H 6 #define _BINARY_COMPATIBILITY_SUPPORT_H 5 #ifndef _BINARY_COMPATIBILITY_SUPPORT_H_ 6 #define _BINARY_COMPATIBILITY_SUPPORT_H_ 7 7 8 8 9 9 #include <binary_compatibility/Global.h> … … 20 20 status_t return_value; 21 21 }; 22 22 23 #endif /* _BINARY_COMPATIBILITY_ INTERFACE_H_ */23 #endif /* _BINARY_COMPATIBILITY_SUPPORT_H_ */ -
src/kits/support/Archivable.cpp
210 210 211 211 212 212 BArchivable::BArchivable() 213 : 214 fArchivingToken(NULL_TOKEN) 213 215 { 214 216 } 215 217 216 218 217 219 BArchivable::BArchivable(BMessage* from) 220 : 221 fArchivingToken(NULL_TOKEN) 218 222 { 219 223 if (BUnarchiver::IsArchiveManaged(from)) { 220 224 BUnarchiver::PrepareArchive(from); … … 313 317 BArchiver::~BArchiver() 314 318 { 315 319 if (!fFinished) 316 fManager->ArchiverLeaving(this );320 fManager->ArchiverLeaving(this, B_OK); 317 321 } 318 322 319 323 … … 321 325 BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep) 322 326 { 323 327 int32 token; 324 status_t err = GetTokenForArchivable(archivable, token, deep);328 status_t err = GetTokenForArchivable(archivable, deep, token); 325 329 326 330 if (err != B_OK) 327 331 return err; … … 332 336 333 337 status_t 334 338 BArchiver::GetTokenForArchivable(BArchivable* archivable, 335 int32& _token, bool deep)339 bool deep, int32& _token) 336 340 { 337 status_t err = B_OK; 338 339 if (!IsArchived(archivable)) 340 err = fManager->ArchiveObject(archivable, deep); 341 342 if (err == B_OK) 343 return fManager->GetTokenForArchivable(archivable, _token); 344 345 return err; 341 return fManager->ArchiveObject(archivable, deep, _token); 346 342 } 347 343 348 344 … … 354 350 355 351 356 352 status_t 357 BArchiver::Finish( )353 BArchiver::Finish(status_t err) 358 354 { 359 355 if (fFinished) 360 356 debugger("Finish() called multiple times on same BArchiver."); 361 357 362 358 fFinished = true; 363 return fManager->ArchiverLeaving(this); 359 360 return fManager->ArchiverLeaving(this, err); 364 361 } 365 362 366 363 … … 393 390 BUnarchiver::~BUnarchiver() 394 391 { 395 392 if (!fFinished && fManager) 396 fManager->UnarchiverLeaving(this );393 fManager->UnarchiverLeaving(this, B_OK); 397 394 } 398 395 399 396 397 template<> 400 398 status_t 401 BUnarchiver::GetArchivable(int32 token, BArchivable** archivable) 399 BUnarchiver::GetObject<BArchivable>(int32 token, 400 ownership owning, BArchivable*& object) 402 401 { 403 402 _CallDebuggerIfManagerNull(); 404 405 if (archivable == NULL) 406 return B_BAD_VALUE; 407 408 return fManager->ArchivableForToken(archivable, token); 403 return fManager->GetArchivableForToken(token, owning, object); 409 404 } 410 405 411 406 407 template<> 412 408 status_t 413 BUnarchiver::FindArchivable(const char* name, BArchivable** archivable) 409 BUnarchiver::FindObject<BArchivable>(const char* name, 410 int32 index, ownership owning, BArchivable*& archivable) 414 411 { 415 return FindArchivable(name, 0, archivable); 416 } 417 418 419 status_t 420 BUnarchiver::FindArchivable(const char* name, 421 int32 index, BArchivable** archivable) 422 { 423 412 archivable = NULL; 424 413 int32 token; 425 414 status_t err = fArchive->FindInt32(name, index, &token); 426 415 if (err != B_OK) 427 416 return err; 428 417 429 return Get Archivable(token, archivable);418 return GetObject(token, owning, archivable); 430 419 } 431 420 432 421 433 status_t434 BUnarchiver::EnsureUnarchived(const char* name, int32 index)435 {436 BArchivable* dummy;437 return FindArchivable(name, index, &dummy);438 }439 440 441 status_t442 BUnarchiver::EnsureUnarchived(int32 token)443 {444 BArchivable* dummy;445 return GetArchivable(token, &dummy);446 }447 448 449 422 bool 450 423 BUnarchiver::IsInstantiated(int32 token) 451 424 { 452 425 return fManager->IsInstantiated(token); 453 426 } 454 427 428 455 429 bool 456 430 BUnarchiver::IsInstantiated(const char* field, int32 index) 457 431 { … … 461 435 return false; 462 436 } 463 437 438 464 439 status_t 465 BUnarchiver::Finish( )440 BUnarchiver::Finish(status_t err) 466 441 { 467 442 if (fFinished) 468 443 debugger("Finish() called multiple times on same BArchiver."); 469 444 470 445 fFinished = true; 471 return fManager->UnarchiverLeaving(this); 446 if (fManager) 447 return fManager->UnarchiverLeaving(this, err); 448 else 449 return B_OK; 472 450 } 473 451 474 452 … … 479 457 } 480 458 481 459 460 void 461 BUnarchiver::AssumeOwnership(BArchivable* archivable) 462 { 463 _CallDebuggerIfManagerNull(); 464 fManager->AssumeOwnership(archivable); 465 } 466 467 468 void 469 BUnarchiver::RelinquishOwnership(BArchivable* archivable) 470 { 471 _CallDebuggerIfManagerNull(); 472 fManager->RelinquishOwnership(archivable); 473 } 474 475 482 476 bool 483 477 BUnarchiver::IsArchiveManaged(BMessage* archive) 484 478 { … … 487 481 return true; 488 482 489 483 // managed top level archives return here 490 int32dummy;491 if (archive->Find Int32(kArchiveCountField, &dummy) == B_OK)484 bool dummy; 485 if (archive->FindBool(kManagedField, &dummy) == B_OK) 492 486 return true; 493 487 494 488 return false; -
src/kits/support/ArchivingManagers.cpp
6 6 * Alex Wilson (yourpalal2@gmail.com) 7 7 */ 8 8 9 #include "ArchivingManagers.h" 9 10 10 11 #include <syslog.h> 11 12 #include <typeinfo> 12 13 13 #include "ArchivingManagers.h"14 14 15 #define NULL_TOKEN -42 15 16 17 16 18 namespace BPrivate { 17 19 namespace Archiving { 18 const char* kArchiveCountField = "_managed_archive_count";19 20 const char* kArchivableField = "_managed_archivable"; 20 const char* k TokenField = "_managed_token";21 const char* kManagedField = "_managed_archive"; 21 22 } 22 23 } 23 24 … … 50 51 if (manager->fType == UNARCHIVE_MANAGER) 51 52 return static_cast<BUnarchiveManager*>(manager); 52 53 53 debugger("More calls to BUnarchiver::Prepare Message()"54 debugger("More calls to BUnarchiver::PrepareArchive()" 54 55 " than BUnarchivers created."); 55 56 56 57 return NULL; … … 84 85 : 85 86 BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER), 86 87 fTokenMap(), 87 fCreator(creator) 88 fCreator(creator), 89 fError(B_OK) 88 90 { 89 91 } 90 92 91 93 92 94 BArchiveManager::~BArchiveManager() 93 95 { 94 fTopLevelArchive->Add Int32(kArchiveCountField, fTokenMap.size());96 fTopLevelArchive->AddBool(kManagedField, true); 95 97 } 96 98 97 99 … … 99 101 BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token) 100 102 { 101 103 if (!archivable) { 102 _token = -42;104 _token = NULL_TOKEN; 103 105 return B_OK; 104 106 } 105 107 … … 114 116 115 117 116 118 status_t 117 BArchiveManager::ArchiveObject(BArchivable* archivable, bool deep) 119 BArchiveManager::ArchiveObject(BArchivable* archivable, 120 bool deep, int32& _token) 118 121 { 119 if ( IsArchived(archivable)){120 debugger("BArchivable requested to be archived"121 " was previously archived.");122 if (!archivable) { 123 _token = NULL_TOKEN; 124 return B_OK; 122 125 } 123 126 124 127 ArchiveInfo& info = fTokenMap[archivable]; 125 128 126 info.archive = new BMessage(); 127 info.token = fTokenMap.size() - 1; 129 status_t err = B_OK; 128 130 129 MarkArchive(info.archive); 130 status_t err = archivable->Archive(info.archive, deep); 131 if (!info.archive) { 132 info.archive = new BMessage(); 133 info.token = fTokenMap.size() - 1; 134 135 MarkArchive(info.archive); 136 err = archivable->Archive(info.archive, deep); 137 } 131 138 132 139 if (err != B_OK) { 133 140 fTokenMap.erase(archivable); 134 141 // info.archive gets deleted here 135 } 142 _token = NULL_TOKEN; 143 } else 144 _token = info.token; 136 145 137 146 return err; 138 147 } … … 149 158 150 159 151 160 status_t 152 BArchiveManager::ArchiverLeaving(const BArchiver* archiver )161 BArchiveManager::ArchiverLeaving(const BArchiver* archiver, status_t err) 153 162 { 154 if (archiver == fCreator) { 163 if (fError == B_OK) 164 fError = err; 165 166 if (archiver == fCreator && fError == B_OK) { 155 167 // first, we must sort the objects into the order they were archived in 156 168 typedef std::pair<BMessage*, const BArchivable*> ArchivePair; 157 169 ArchivePair pairs[fTokenMap.size()]; … … 167 179 info.archive = NULL; 168 180 } 169 181 170 status_t err = B_ERROR;171 182 int32 count = fTokenMap.size(); 172 183 for (int32 i = 0; i < count; i++) { 173 184 const ArchivePair& pair = pairs[i]; 174 err = pair.second->AllArchived(pair.first);185 fError = pair.second->AllArchived(pair.first); 175 186 176 if ( err == B_OK && i > 0) {177 err = fTopLevelArchive->AddMessage(kArchivableField,187 if (fError == B_OK && i > 0) { 188 fError = fTopLevelArchive->AddMessage(kArchivableField, 178 189 pair.first); 179 190 } 180 191 181 if ( err != B_OK) {192 if (fError != B_OK) { 182 193 syslog(LOG_ERR, "AllArchived failed for object of type %s.", 183 194 typeid(*pairs[i].second).name()); 184 195 break; 185 196 } 186 197 } 187 198 } 199 200 if (archiver == fCreator) 188 201 delete this; 189 return err;190 }191 202 192 return B_OK;203 return fError; 193 204 } 194 205 195 206 … … 211 222 ArchiveInfo() 212 223 : 213 224 archivable(NULL), 214 archive() 225 archive(), 226 adopted(false) 215 227 { 216 228 } 217 229 … … 223 235 224 236 BArchivable* archivable; 225 237 BMessage archive; 238 bool adopted; 226 239 }; 227 240 228 241 … … 235 248 fObjects(NULL), 236 249 fObjectCount(0), 237 250 fTokenInProgress(0), 238 fRefCount(0) 251 fRefCount(0), 252 fError(B_OK) 239 253 { 240 archive->FindInt32(kArchiveCountField, &fObjectCount); 254 archive->GetInfo(kArchivableField, NULL, &fObjectCount); 255 fObjectCount++; 256 // root object needs a spot too 241 257 fObjects = new ArchiveInfo[fObjectCount]; 242 258 243 259 // fObjects[0] is a placeholder for the object that started … … 260 276 261 277 262 278 status_t 263 BUnarchiveManager::ArchivableForToken(BArchivable** _archivable, int32 token) 279 BUnarchiveManager::GetArchivableForToken(int32 token, 280 ownership owning, BArchivable*& _archivable) 264 281 { 265 if ( !_archivable ||token > fObjectCount)282 if (token > fObjectCount) 266 283 return B_BAD_VALUE; 267 284 268 285 if (token < 0) { 269 *_archivable = NULL;286 _archivable = NULL; 270 287 return B_OK; 271 288 } 272 289 273 290 status_t err = B_OK; 274 if (!fObjects[token].archivable) { 275 if (fRefCount > 0) 276 err = _InstantiateObjectForToken(token); 277 else { 291 ArchiveInfo& info = fObjects[token]; 292 if (!info.archivable) { 293 if (fRefCount > 0) { 294 fTokenInProgress = token; 295 if(!instantiate_object(&info.archive)) 296 err = B_ERROR; 297 } else { 278 298 syslog(LOG_ERR, "Object requested from AllUnarchived()" 279 299 " was not previously instantiated"); 280 300 err = B_ERROR; 281 301 } 282 302 } 283 303 284 *_archivable = fObjects[token].archivable; 304 if (!info.adopted && owning == B_ASSUME_OWNERSHIP) 305 info.adopted = true; 306 else if (info.adopted && owning == B_ASSUME_OWNERSHIP) 307 debugger("Cannot assume ownership of an object that is already owned"); 308 309 _archivable = info.archivable; 285 310 return err; 286 311 } 287 312 … … 302 327 debugger("Cannot register NULL pointer"); 303 328 304 329 fObjects[fTokenInProgress].archivable = archivable; 330 archivable->fArchivingToken = fTokenInProgress; 305 331 } 306 332 307 333 308 334 status_t 309 BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver) 335 BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver, 336 status_t err) 310 337 { 311 if (--fRefCount == 0) { 312 fRefCount = -1; 313 // make sure we de not end up here again! 338 if (--fRefCount >= 0 && fError == B_OK) 339 fError = err; 314 340 341 if (fRefCount != 0) 342 return fError; 343 344 if (fError == B_OK) { 315 345 BArchivable* archivable = fObjects[0].archivable; 316 status_t err = archivable->AllUnarchived(fTopLevelArchive); 346 if (archivable) { 347 fError = archivable->AllUnarchived(fTopLevelArchive); 348 archivable->fArchivingToken = NULL_TOKEN; 349 } 317 350 318 for (int32 i = 1; i < fObjectCount; i++) { 319 if (err != B_OK) 320 break; 321 351 for (int32 i = 1; i < fObjectCount && fError == B_OK; i++) { 322 352 archivable = fObjects[i].archivable; 323 err = archivable->AllUnarchived(&fObjects[i].archive); 353 if (archivable) { 354 fError = archivable->AllUnarchived(&fObjects[i].archive); 355 archivable->fArchivingToken = NULL_TOKEN; 356 } 324 357 } 358 if (fError != B_OK) { 359 syslog(LOG_ERR, "Error in AllUnarchived" 360 " method of object of type %s", typeid(*archivable).name()); 361 } 362 } 325 363 326 if (err != B_OK) { 327 syslog(LOG_ERR, "AllUnarchived failed for object of type %s.", 328 typeid(*archivable).name()); 364 if (fError != B_OK) { 365 syslog(LOG_ERR, "An error occured during unarchival, cleaning up."); 366 for (int32 i = 1; i < fObjectCount; i++) { 367 if (!fObjects[i].adopted) 368 delete fObjects[i].archivable; 329 369 } 330 331 delete this;332 return err;333 370 } 334 371 335 return B_OK; 372 delete this; 373 return fError; 336 374 } 337 375 338 376 339 377 void 340 BUnarchiveManager:: Acquire()378 BUnarchiveManager::RelinquishOwnership(BArchivable* archivable) 341 379 { 342 if (fRefCount >= 0) 343 fRefCount++; 380 int32 token = NULL_TOKEN; 381 if (archivable) 382 token = archivable->fArchivingToken; 383 384 if (token < 0 || token >= fObjectCount 385 || fObjects[token].archivable != archivable) 386 return; 387 388 fObjects[token].adopted = false; 344 389 } 345 390 346 391 347 status_t 348 BUnarchiveManager:: _InstantiateObjectForToken(int32 token)392 void 393 BUnarchiveManager::AssumeOwnership(BArchivable* archivable) 349 394 { 350 fTokenInProgress = token; 351 if(!instantiate_object(&fObjects[token].archive)) 352 return B_ERROR; 353 return B_OK; 395 int32 token = NULL_TOKEN; 396 if (archivable) 397 token = archivable->fArchivingToken; 398 399 if (token < 0 || token >= fObjectCount 400 || fObjects[token].archivable != archivable) 401 return; 402 403 if (!fObjects[token].adopted) 404 fObjects[token].adopted = true; 405 else { 406 debugger("Cannot assume ownership of an object that is already owned"); 407 } 354 408 } 355 409 410 411 void 412 BUnarchiveManager::Acquire() 413 { 414 if (fRefCount >= 0) 415 fRefCount++; 416 } -
src/kits/support/ArchivingManagers.h
18 18 namespace BPrivate { 19 19 namespace Archiving { 20 20 21 extern const char* kArchiveCountField; 22 extern const char* kArchivableField; 23 extern const char* kTokenField; 21 extern const char* kManagedField; 24 22 25 23 26 24 class BManagerBase { … … 101 99 int32& _token); 102 100 103 101 status_t ArchiveObject(BArchivable* archivable, 104 bool deep );102 bool deep, int32& _token); 105 103 106 104 bool IsArchived(BArchivable* archivable); 107 105 108 status_t ArchiverLeaving(const BArchiver* archiver); 106 status_t ArchiverLeaving(const BArchiver* archiver, 107 status_t err); 108 109 109 void Acquire(); 110 110 void RegisterArchivable( 111 111 const BArchivable* archivable); … … 118 118 119 119 TokenMap fTokenMap; 120 120 const BArchiver* fCreator; 121 status_t fError; 121 122 }; 122 123 123 124 … … 127 128 public: 128 129 BUnarchiveManager(BMessage* topLevelArchive); 129 130 130 status_t ArchivableForToken(BArchivable** archivable, 131 int32 token); 131 status_t GetArchivableForToken(int32 token, 132 ownership owning, 133 BArchivable*& _archivable); 132 134 133 135 bool IsInstantiated(int32 token); 134 136 135 137 void RegisterArchivable(BArchivable* archivable); 136 status_t UnarchiverLeaving(const BUnarchiver* archiver); 138 status_t UnarchiverLeaving(const BUnarchiver* archiver, 139 status_t err); 137 140 void Acquire(); 138 141 142 void RelinquishOwnership(BArchivable* archivable); 143 void AssumeOwnership(BArchivable* archivable); 139 144 private: 140 145 ~BUnarchiveManager(); 141 146 142 147 status_t _ExtractArchiveAt(int32 index); 143 status_t _InstantiateObjectForToken(int32 token);144 148 145 149 struct ArchiveInfo; 146 150 … … 148 152 int32 fObjectCount; 149 153 int32 fTokenInProgress; 150 154 int32 fRefCount; 155 status_t fError; 151 156 }; 152 157 153 158 -
headers/os/interface/Layout.h
54 54 55 55 virtual status_t Archive(BMessage* into, bool deep = true) const; 56 56 virtual status_t AllUnarchived(const BMessage* from); 57 virtual status_t ArchiveLayoutData(BMessage* into,58 const BLayoutItem* of) const;59 virtual status_t RestoreItemAndData(const BMessage* from,60 BLayoutItem* item);61 57 58 virtual status_t ItemArchived(BMessage* into, BLayoutItem* item, 59 int32 index) const; 60 virtual status_t ItemUnarchived(const BMessage* from, 61 BLayoutItem* item, int32 index); 62 62 protected: 63 63 // TODO: Since memory allocations can fail, we should return a bool and 64 64 // undo the addition, if false. -
src/kits/interface/Layout.cpp
7 7 8 8 #include <Layout.h> 9 9 10 #include <syslog.h> 10 11 #include <new> 11 12 12 13 #include <Message.h> … … 19 20 20 21 namespace { 21 22 const char* kLayoutItemField = "BLayout:_items"; 22 const char* kLayoutDataField = "BLayout:_data";23 23 } 24 24 25 25 26 // constructor27 26 BLayout::BLayout() 28 27 : 29 28 fView(NULL), … … 211 210 BArchiver archiver(into); 212 211 status_t err = BArchivable::Archive(into, deep); 213 212 214 if (err != B_OK)215 return err;216 217 213 if (deep) { 218 214 int32 count = CountItems(); 219 for (int32 i = 0; i < count; i++) { 220 err = archiver.AddArchivable(kLayoutItemField, ItemAt(i), deep); 215 for (int32 i = 0; i < count && err == B_OK; i++) { 216 BLayoutItem* item = ItemAt(i); 217 err = archiver.AddArchivable(kLayoutItemField, item, deep); 221 218 222 219 if (err == B_OK) { 223 BMessage data; 224 err = ArchiveLayoutData(&data, ItemAt(i)); 225 if (err == B_OK) 226 err = into->AddMessage(kLayoutDataField, &data); 220 err = ItemArchived(into, item, i); 221 if (err != B_OK) 222 syslog(LOG_ERR, "ItemArchived() failed at index: %d.", i); 227 223 } 228 229 if (err != B_OK)230 return err;231 224 } 232 225 } 233 226 234 return archiver.Finish( );227 return archiver.Finish(err); 235 228 } 236 229 237 230 238 231 status_t 239 232 BLayout::AllUnarchived(const BMessage* from) 240 233 { 241 status_t err = BArchivable::AllUnarchived(from);242 234 BUnarchiver unarchiver(from); 235 status_t err = BArchivable::AllUnarchived(from); 243 236 244 237 if (err != B_OK) 245 238 return err; 246 239 247 for (int32 i = 0; ; i++) { 248 BArchivable* retriever; 249 err = unarchiver.FindArchivable(kLayoutItemField, i, &retriever); 240 int32 itemCount; 241 unarchiver.ArchiveMessage()->GetInfo(kLayoutItemField, NULL, &itemCount); 242 for (int32 i = 0; i < itemCount && err == B_OK; i++) { 243 BLayoutItem* item; 244 err = unarchiver.FindObject(kLayoutItemField, i, item); 250 245 251 if (err == B_BAD_INDEX) 252 break; 253 254 if (err == B_OK) { 255 BMessage layoutData; 256 err = from->FindMessage(kLayoutDataField, i, &layoutData); 257 258 if (err == B_OK) { 259 BLayoutItem* item = dynamic_cast<BLayoutItem*>(retriever); 260 err = RestoreItemAndData(&layoutData, item); 261 } 246 if (err == B_OK && item) { 247 if (fItems.AddItem(item)) { 248 ItemAdded(item); 249 err = ItemUnarchived(from, item, i); 250 } else 251 err = B_NO_MEMORY; 262 252 } 263 264 if (err != B_OK)265 return err;266 253 } 267 254 268 return B_OK;255 return err; 269 256 } 270 257 271 258 272 259 status_t 273 BLayout:: ArchiveLayoutData(BMessage* into, const BLayoutItem* of) const260 BLayout::ItemArchived(BMessage* into, BLayoutItem* of, int32 index) const 274 261 { 275 262 return B_OK; 276 263 } 277 264 278 265 279 266 status_t 280 BLayout:: RestoreItemAndData(const BMessage* from, BLayoutItem* item)267 BLayout::ItemUnarchived(const BMessage* from, BLayoutItem* item, int32 index) 281 268 { 282 if (item && AddItem(item)) 283 return B_OK; 284 return B_ERROR; 269 return B_OK; 285 270 } 286 271 287 272 -
headers/private/binary_compatibility/Global.h
4 4 * Distributed under the terms of the MIT License. 5 5 */ 6 6 #ifndef _BINARY_COMPATIBILITY_GLOBAL_H_ 7 #define _BINARY_COMPATIBILITY_ _GLOBAL_H_7 #define _BINARY_COMPATIBILITY_GLOBAL_H_ 8 8 9 9 10 10 // method codes … … 24 24 PERFORM_CODE_GET_TOOL_TIP_AT = 1009, 25 25 26 26 // support kit 27 28 27 PERFORM_CODE_ALL_ARCHIVED = 1010, 29 28 PERFORM_CODE_ALL_UNARCHIVED = 1011 30 29 }; -
headers/os/support/SupportDefs.h
63 63 typedef generic_addr_t generic_size_t; 64 64 65 65 66 /* enum types */ 67 enum ownership { 68 B_ASSUME_OWNERSHIP, 69 B_DONT_ASSUME_OWNERSHIP 70 }; 71 72 66 73 /* printf()/scanf() format strings for [u]int* types */ 67 74 #define B_PRId8 "d" 68 75 #define B_PRIi8 "i"