Ticket #6256: archiving.3.patch
File archiving.3.patch, 26.2 KB (added by , 13 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 13 14 class BMessage; 14 15 16 15 17 namespace BPrivate { 16 18 namespace Archiving { 17 19 class BArchiveManager; … … 38 40 virtual status_t AllArchived(BMessage* archive) const; 39 41 40 42 private: 43 friend class BUnarchiveManager; 44 41 45 virtual void _ReservedArchivable3(); 42 46 43 uint32 _reserved[2]; 47 int32 fArchivingToken; 48 uint32 _reserved; 44 49 }; 45 50 46 51 … … 52 57 status_t AddArchivable(const char* name, 53 58 BArchivable* archivable, bool deep = true); 54 59 60 inline status_t GetTokenForArchivable(BArchivable* archivable, 61 int32& _token); 55 62 status_t GetTokenForArchivable(BArchivable* archivable, 56 int32& _token, bool deep = true);63 bool deep, int32& _token); 57 64 58 65 bool IsArchived(BArchivable* archivable); 59 status_t Finish( );66 status_t Finish(status_t err = B_OK); 60 67 BMessage* ArchiveMessage() const; 61 68 62 69 private: … … 71 78 BArchiveManager* fManager; 72 79 BMessage* fArchive; 73 80 bool fFinished; 81 uint32 _reserved[2]; 74 82 }; 75 83 76 84 77 85 class BUnarchiver { 78 86 public: 87 enum ownership_policy { 88 B_ASSUME_OWNERSHIP, 89 B_DONT_ASSUME_OWNERSHIP 90 }; 79 91 BUnarchiver(const BMessage* archive); 80 92 ~BUnarchiver(); 81 93 82 status_t GetArchivable(int32 token,83 BArchivable** archivable);94 template<class T> 95 inline status_t GetObject(int32 token, T*& object); 84 96 85 status_t FindArchivable(const char* name, 86 BArchivable** archivable); 97 template<class T> 98 status_t GetObject(int32 token, ownership_policy owning, 99 T*& object); 87 100 88 status_t FindArchivable(const char* name, int32 index,89 BArchivable** archivable);101 template<class T> 102 inline status_t FindObject(const char* name, T*& object); 90 103 91 status_t EnsureUnarchived(const char* name, 104 template<class T> 105 inline status_t FindObject(const char* name, 106 ownership_policy owning, 107 T*& object); 108 109 template<class T> 110 inline status_t FindObject(const char* name, 111 int32 index, T*& object); 112 113 template<class T> 114 status_t FindObject(const char* name, int32 index, 115 ownership_policy owning, T*& object); 116 117 inline status_t EnsureUnarchived(const char* name, 92 118 int32 index = 0); 93 119 inline status_t EnsureUnarchived(int32 token); 94 120 95 121 bool IsInstantiated(int32 token); 96 122 bool IsInstantiated(const char* name, 97 123 int32 index = 0); 98 124 99 status_t Finish( );125 status_t Finish(status_t err = B_OK); 100 126 const BMessage* ArchiveMessage() const; 101 127 128 void AssumeOwnership(BArchivable* archivable); 129 void RelinquishOwnership(BArchivable* archivable); 130 102 131 static bool IsArchiveManaged(BMessage* archive); 103 132 static BMessage* PrepareArchive(BMessage*& archive); 104 133 134 template<class T> 135 static status_t InstantiateObject(BMessage* archive, 136 T*& object); 137 105 138 private: 106 139 friend class BArchivable; 107 140 … … 110 143 111 144 void RegisterArchivable(BArchivable* archivable); 112 145 113 146 inline void _CallDebuggerIfManagerNull(); 114 147 115 148 BUnarchiveManager* fManager; 116 149 const BMessage* fArchive; 117 150 bool fFinished; 151 uint32 _reserved[2]; 118 152 }; 119 153 120 154 … … 131 165 instantiation_func find_instantiation_func(const char* className); 132 166 instantiation_func find_instantiation_func(BMessage* archive); 133 167 168 169 status_t 170 BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token) 171 { 172 return GetTokenForArchivable(archivable, true, _token); 173 } 174 175 176 template<> 177 status_t BUnarchiver::FindObject<BArchivable>(const char* name, int32 index, 178 ownership_policy owning, BArchivable*& archivable); 179 180 181 template<class T> 182 status_t 183 BUnarchiver::FindObject(const char* name, int32 index, 184 ownership_policy owning, T*& object) 185 { 186 object = NULL; 187 188 BArchivable* interim; 189 status_t err = FindObject(name, index, owning, interim); 190 191 if (err == B_OK && interim) { 192 object = dynamic_cast<T*>(interim); 193 if (!object) { 194 err = B_BAD_TYPE; 195 // we will not be deleting this item, but it must be deleted 196 if (owning == B_ASSUME_OWNERSHIP) 197 RelinquishOwnership(interim); 198 } 199 } 200 return err; 201 } 202 203 204 template<> 205 status_t 206 BUnarchiver::GetObject<BArchivable>(int32 token, 207 ownership_policy owning, BArchivable*& object); 208 209 210 template<class T> 211 status_t 212 BUnarchiver::GetObject(int32 token, ownership_policy owning, T*& object) 213 { 214 object = NULL; 215 216 BArchivable* interim; 217 status_t err = GetObject(token, owning, interim); 218 219 if (err == B_OK && interim) { 220 object = dynamic_cast<T*>(interim); 221 if (!object) { 222 err = B_BAD_TYPE; 223 // we will not be deleting this item, but it must be deleted 224 if (owning == B_ASSUME_OWNERSHIP) 225 RelinquishOwnership(interim); 226 } 227 } 228 return err; 229 } 230 231 232 template<class T> 233 status_t 234 BUnarchiver::GetObject(int32 token, T*& object) 235 { 236 return GetObject<T>(token, B_ASSUME_OWNERSHIP, object); 237 } 238 239 240 template<class T> 241 status_t 242 BUnarchiver::FindObject(const char* name, ownership_policy owning, T*& object) 243 { 244 return FindObject(name, 0, owning, object); 245 } 246 247 248 template<class T> 249 status_t 250 BUnarchiver::FindObject(const char* name, T*& object) 251 { 252 return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object); 253 } 254 255 256 template<class T> 257 status_t 258 BUnarchiver::FindObject(const char* name, 259 int32 index, T*& object) 260 { 261 return FindObject(name, index, B_ASSUME_OWNERSHIP, object); 262 } 263 264 265 status_t 266 BUnarchiver::EnsureUnarchived(int32 token) 267 { 268 BArchivable* dummy; 269 return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy); 270 } 271 272 273 status_t 274 BUnarchiver::EnsureUnarchived(const char* name, int32 index) 275 { 276 BArchivable* dummy; 277 return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy); 278 } 279 280 281 template<> 282 status_t 283 BUnarchiver::InstantiateObject<BArchivable>(BMessage* from, 284 BArchivable*& object); 285 286 287 template<class T> 288 status_t 289 BUnarchiver::InstantiateObject(BMessage* archive, T*& object) 290 { 291 object = NULL; 292 BArchivable* interim; 293 status_t err = InstantiateObject(archive, interim); 294 if (err == B_OK && interim) { 295 object = dynamic_cast<T*>(interim); 296 if (!object) 297 err = B_BAD_TYPE; 298 } 299 300 if (err != B_OK) 301 delete interim; 302 303 return err; 304 } 305 306 134 307 #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_policy 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_policy 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; 495 489 } 496 490 497 491 492 template<> 493 status_t 494 BUnarchiver::InstantiateObject<BArchivable>(BMessage* from, 495 BArchivable*& object) 496 { 497 BUnarchiver unarchiver(BUnarchiver::PrepareArchive(from)); 498 object = instantiate_object(from); 499 return unarchiver.Finish(); 500 } 501 502 498 503 BMessage* 499 504 BUnarchiver::PrepareArchive(BMessage*& archive) 500 505 { -
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 16 15 namespace BPrivate { 17 16 namespace Archiving { 18 const char* kArchiveCountField = "_managed_archive_count";19 17 const char* kArchivableField = "_managed_archivable"; 20 const char* k TokenField = "_managed_token";18 const char* kManagedField = "_managed_archive"; 21 19 } 22 20 } 23 21 … … 50 48 if (manager->fType == UNARCHIVE_MANAGER) 51 49 return static_cast<BUnarchiveManager*>(manager); 52 50 53 debugger("More calls to BUnarchiver::Prepare Message()"51 debugger("More calls to BUnarchiver::PrepareArchive()" 54 52 " than BUnarchivers created."); 55 53 56 54 return NULL; … … 84 82 : 85 83 BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER), 86 84 fTokenMap(), 87 fCreator(creator) 85 fCreator(creator), 86 fError(B_OK) 88 87 { 89 88 } 90 89 91 90 92 91 BArchiveManager::~BArchiveManager() 93 92 { 94 fTopLevelArchive->Add Int32(kArchiveCountField, fTokenMap.size());93 fTopLevelArchive->AddBool(kManagedField, true); 95 94 } 96 95 97 96 … … 99 98 BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token) 100 99 { 101 100 if (!archivable) { 102 _token = -42;101 _token = NULL_TOKEN; 103 102 return B_OK; 104 103 } 105 104 … … 114 113 115 114 116 115 status_t 117 BArchiveManager::ArchiveObject(BArchivable* archivable, bool deep) 116 BArchiveManager::ArchiveObject(BArchivable* archivable, 117 bool deep, int32& _token) 118 118 { 119 if ( IsArchived(archivable)){120 debugger("BArchivable requested to be archived"121 " was previously archived.");119 if (!archivable) { 120 _token = NULL_TOKEN; 121 return B_OK; 122 122 } 123 123 124 124 ArchiveInfo& info = fTokenMap[archivable]; 125 125 126 info.archive = new BMessage(); 127 info.token = fTokenMap.size() - 1; 126 status_t err = B_OK; 128 127 129 MarkArchive(info.archive); 130 status_t err = archivable->Archive(info.archive, deep); 128 if (!info.archive) { 129 info.archive = new BMessage(); 130 info.token = fTokenMap.size() - 1; 131 132 MarkArchive(info.archive); 133 err = archivable->Archive(info.archive, deep); 134 } 131 135 132 136 if (err != B_OK) { 133 137 fTokenMap.erase(archivable); 134 138 // info.archive gets deleted here 135 } 139 _token = NULL_TOKEN; 140 } else 141 _token = info.token; 136 142 137 143 return err; 138 144 } … … 149 155 150 156 151 157 status_t 152 BArchiveManager::ArchiverLeaving(const BArchiver* archiver )158 BArchiveManager::ArchiverLeaving(const BArchiver* archiver, status_t err) 153 159 { 154 if (archiver == fCreator) { 160 if (fError == B_OK) 161 fError = err; 162 163 if (archiver == fCreator && fError == B_OK) { 155 164 // first, we must sort the objects into the order they were archived in 156 165 typedef std::pair<BMessage*, const BArchivable*> ArchivePair; 157 166 ArchivePair pairs[fTokenMap.size()]; … … 167 176 info.archive = NULL; 168 177 } 169 178 170 status_t err = B_ERROR;171 179 int32 count = fTokenMap.size(); 172 180 for (int32 i = 0; i < count; i++) { 173 181 const ArchivePair& pair = pairs[i]; 174 err = pair.second->AllArchived(pair.first);182 fError = pair.second->AllArchived(pair.first); 175 183 176 if ( err == B_OK && i > 0) {177 err = fTopLevelArchive->AddMessage(kArchivableField,184 if (fError == B_OK && i > 0) { 185 fError = fTopLevelArchive->AddMessage(kArchivableField, 178 186 pair.first); 179 187 } 180 188 181 if ( err != B_OK) {189 if (fError != B_OK) { 182 190 syslog(LOG_ERR, "AllArchived failed for object of type %s.", 183 191 typeid(*pairs[i].second).name()); 184 192 break; 185 193 } 186 194 } 187 195 } 196 197 if (archiver == fCreator) 188 198 delete this; 189 return err;190 }191 199 192 return B_OK;200 return fError; 193 201 } 194 202 195 203 … … 211 219 ArchiveInfo() 212 220 : 213 221 archivable(NULL), 214 archive() 222 archive(), 223 adopted(false) 215 224 { 216 225 } 217 226 … … 223 232 224 233 BArchivable* archivable; 225 234 BMessage archive; 235 bool adopted; 226 236 }; 227 237 228 238 … … 235 245 fObjects(NULL), 236 246 fObjectCount(0), 237 247 fTokenInProgress(0), 238 fRefCount(0) 248 fRefCount(0), 249 fError(B_OK) 239 250 { 240 archive->FindInt32(kArchiveCountField, &fObjectCount); 251 archive->GetInfo(kArchivableField, NULL, &fObjectCount); 252 fObjectCount++; 253 // root object needs a spot too 241 254 fObjects = new ArchiveInfo[fObjectCount]; 242 255 243 256 // fObjects[0] is a placeholder for the object that started … … 260 273 261 274 262 275 status_t 263 BUnarchiveManager::ArchivableForToken(BArchivable** _archivable, int32 token) 276 BUnarchiveManager::GetArchivableForToken(int32 token, 277 BUnarchiver::ownership_policy owning, BArchivable*& _archivable) 264 278 { 265 if ( !_archivable ||token > fObjectCount)279 if (token > fObjectCount) 266 280 return B_BAD_VALUE; 267 281 268 282 if (token < 0) { 269 *_archivable = NULL;283 _archivable = NULL; 270 284 return B_OK; 271 285 } 272 286 273 287 status_t err = B_OK; 274 if (!fObjects[token].archivable) { 275 if (fRefCount > 0) 276 err = _InstantiateObjectForToken(token); 277 else { 288 ArchiveInfo& info = fObjects[token]; 289 if (!info.archivable) { 290 if (fRefCount > 0) { 291 fTokenInProgress = token; 292 if(!instantiate_object(&info.archive)) 293 err = B_ERROR; 294 } else { 278 295 syslog(LOG_ERR, "Object requested from AllUnarchived()" 279 296 " was not previously instantiated"); 280 297 err = B_ERROR; 281 298 } 282 299 } 283 300 284 *_archivable = fObjects[token].archivable; 301 if (!info.adopted && owning == BUnarchiver::B_ASSUME_OWNERSHIP) 302 info.adopted = true; 303 else if (info.adopted && owning == BUnarchiver::B_ASSUME_OWNERSHIP) 304 debugger("Cannot assume ownership of an object that is already owned"); 305 306 _archivable = info.archivable; 285 307 return err; 286 308 } 287 309 … … 302 324 debugger("Cannot register NULL pointer"); 303 325 304 326 fObjects[fTokenInProgress].archivable = archivable; 327 archivable->fArchivingToken = fTokenInProgress; 305 328 } 306 329 307 330 308 331 status_t 309 BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver) 332 BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver, 333 status_t err) 310 334 { 311 if (--fRefCount == 0) { 312 fRefCount = -1; 313 // make sure we de not end up here again! 335 if (--fRefCount >= 0 && fError == B_OK) 336 fError = err; 314 337 338 if (fRefCount != 0) 339 return fError; 340 341 if (fError == B_OK) { 315 342 BArchivable* archivable = fObjects[0].archivable; 316 status_t err = archivable->AllUnarchived(fTopLevelArchive); 343 if (archivable) { 344 fError = archivable->AllUnarchived(fTopLevelArchive); 345 archivable->fArchivingToken = NULL_TOKEN; 346 } 317 347 318 for (int32 i = 1; i < fObjectCount; i++) { 319 if (err != B_OK) 320 break; 321 348 for (int32 i = 1; i < fObjectCount && fError == B_OK; i++) { 322 349 archivable = fObjects[i].archivable; 323 err = archivable->AllUnarchived(&fObjects[i].archive); 350 if (archivable) { 351 fError = archivable->AllUnarchived(&fObjects[i].archive); 352 archivable->fArchivingToken = NULL_TOKEN; 353 } 324 354 } 355 if (fError != B_OK) { 356 syslog(LOG_ERR, "Error in AllUnarchived" 357 " method of object of type %s", typeid(*archivable).name()); 358 } 359 } 325 360 326 if (err != B_OK) { 327 syslog(LOG_ERR, "AllUnarchived failed for object of type %s.", 328 typeid(*archivable).name()); 361 if (fError != B_OK) { 362 syslog(LOG_ERR, "An error occured during unarchival, cleaning up."); 363 for (int32 i = 1; i < fObjectCount; i++) { 364 if (!fObjects[i].adopted) 365 delete fObjects[i].archivable; 329 366 } 330 331 delete this;332 return err;333 367 } 334 368 335 return B_OK; 369 delete this; 370 return fError; 336 371 } 337 372 338 373 339 374 void 340 BUnarchiveManager:: Acquire()375 BUnarchiveManager::RelinquishOwnership(BArchivable* archivable) 341 376 { 342 if (fRefCount >= 0) 343 fRefCount++; 377 int32 token = NULL_TOKEN; 378 if (archivable) 379 token = archivable->fArchivingToken; 380 381 if (token < 0 || token >= fObjectCount 382 || fObjects[token].archivable != archivable) 383 return; 384 385 fObjects[token].adopted = false; 344 386 } 345 387 346 388 347 status_t 348 BUnarchiveManager:: _InstantiateObjectForToken(int32 token)389 void 390 BUnarchiveManager::AssumeOwnership(BArchivable* archivable) 349 391 { 350 fTokenInProgress = token; 351 if(!instantiate_object(&fObjects[token].archive)) 352 return B_ERROR; 353 return B_OK; 392 int32 token = NULL_TOKEN; 393 if (archivable) 394 token = archivable->fArchivingToken; 395 396 if (token < 0 || token >= fObjectCount 397 || fObjects[token].archivable != archivable) 398 return; 399 400 if (!fObjects[token].adopted) 401 fObjects[token].adopted = true; 402 else { 403 debugger("Cannot assume ownership of an object that is already owned"); 404 } 354 405 } 355 406 407 408 void 409 BUnarchiveManager::Acquire() 410 { 411 if (fRefCount >= 0) 412 fRefCount++; 413 } -
src/kits/support/ArchivingManagers.h
15 15 #include <Archivable.h> 16 16 17 17 18 #define NULL_TOKEN -42 19 20 18 21 namespace BPrivate { 19 22 namespace Archiving { 20 23 21 extern const char* kArchiveCountField; 22 extern const char* kArchivableField; 23 extern const char* kTokenField; 24 extern const char* kManagedField; 24 25 25 26 26 27 class BManagerBase { … … 101 102 int32& _token); 102 103 103 104 status_t ArchiveObject(BArchivable* archivable, 104 bool deep );105 bool deep, int32& _token); 105 106 106 107 bool IsArchived(BArchivable* archivable); 107 108 108 status_t ArchiverLeaving(const BArchiver* archiver); 109 status_t ArchiverLeaving(const BArchiver* archiver, 110 status_t err); 111 109 112 void Acquire(); 110 113 void RegisterArchivable( 111 114 const BArchivable* archivable); … … 118 121 119 122 TokenMap fTokenMap; 120 123 const BArchiver* fCreator; 124 status_t fError; 121 125 }; 122 126 123 127 … … 127 131 public: 128 132 BUnarchiveManager(BMessage* topLevelArchive); 129 133 130 status_t ArchivableForToken(BArchivable** archivable, 131 int32 token); 134 status_t GetArchivableForToken(int32 token, 135 BUnarchiver::ownership_policy owning, 136 BArchivable*& _archivable); 132 137 133 138 bool IsInstantiated(int32 token); 134 139 135 140 void RegisterArchivable(BArchivable* archivable); 136 status_t UnarchiverLeaving(const BUnarchiver* archiver); 141 status_t UnarchiverLeaving(const BUnarchiver* archiver, 142 status_t err); 137 143 void Acquire(); 138 144 145 void RelinquishOwnership(BArchivable* archivable); 146 void AssumeOwnership(BArchivable* archivable); 139 147 private: 140 148 ~BUnarchiveManager(); 141 149 142 150 status_t _ExtractArchiveAt(int32 index); 143 status_t _InstantiateObjectForToken(int32 token);144 151 145 152 struct ArchiveInfo; 146 153 … … 148 155 int32 fObjectCount; 149 156 int32 fTokenInProgress; 150 157 int32 fRefCount; 158 status_t fError; 151 159 }; 152 160 153 161 -
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 item->SetLayout(this); 250 err = ItemUnarchived(from, item, i); 251 } else 252 err = B_NO_MEMORY; 262 253 } 263 264 if (err != B_OK)265 return err;266 254 } 267 255 268 return B_OK;256 return err; 269 257 } 270 258 271 259 272 260 status_t 273 BLayout:: ArchiveLayoutData(BMessage* into, const BLayoutItem* of) const261 BLayout::ItemArchived(BMessage* into, BLayoutItem* of, int32 index) const 274 262 { 275 263 return B_OK; 276 264 } 277 265 278 266 279 267 status_t 280 BLayout:: RestoreItemAndData(const BMessage* from, BLayoutItem* item)268 BLayout::ItemUnarchived(const BMessage* from, BLayoutItem* item, int32 index) 281 269 { 282 if (item && AddItem(item)) 283 return B_OK; 284 return B_ERROR; 270 return B_OK; 285 271 } 286 272 287 273 -
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. -
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 };