Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkPDFCatalog.h" | 10 #include "SkPDFCatalog.h" |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 SkPDFDict::~SkPDFDict() { | 395 SkPDFDict::~SkPDFDict() { |
| 396 clear(); | 396 clear(); |
| 397 } | 397 } |
| 398 | 398 |
| 399 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 399 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 400 bool indirect) { | 400 bool indirect) { |
| 401 if (indirect) { | 401 if (indirect) { |
| 402 return emitIndirectObject(stream, catalog); | 402 return emitIndirectObject(stream, catalog); |
| 403 } | 403 } |
| 404 | 404 |
| 405 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a | |
| 406 // resize while this thread is in | |
| 407 // the for-loop, we can be left | |
| 408 // with a bad fValue[i] reference. | |
| 405 stream->writeText("<<"); | 409 stream->writeText("<<"); |
| 406 for (int i = 0; i < fValue.count(); i++) { | 410 for (int i = 0; i < fValue.count(); i++) { |
| 411 SkASSERT(fValue[i].key); | |
| 412 SkASSERT(fValue[i].value); | |
| 407 fValue[i].key->emitObject(stream, catalog, false); | 413 fValue[i].key->emitObject(stream, catalog, false); |
| 408 stream->writeText(" "); | 414 stream->writeText(" "); |
| 409 fValue[i].value->emit(stream, catalog, false); | 415 fValue[i].value->emit(stream, catalog, false); |
| 410 stream->writeText("\n"); | 416 stream->writeText("\n"); |
| 411 } | 417 } |
| 412 stream->writeText(">>"); | 418 stream->writeText(">>"); |
| 413 } | 419 } |
| 414 | 420 |
| 415 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 421 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
| 416 if (indirect) { | 422 if (indirect) { |
| 417 return getIndirectOutputSize(catalog); | 423 return getIndirectOutputSize(catalog); |
| 418 } | 424 } |
| 419 | 425 |
| 426 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a | |
| 427 // resize while this thread is in | |
| 428 // the for-loop, we can be left | |
| 429 // with a bad fValue[i] reference. | |
| 420 size_t result = strlen("<<>>") + (fValue.count() * 2); | 430 size_t result = strlen("<<>>") + (fValue.count() * 2); |
| 421 for (int i = 0; i < fValue.count(); i++) { | 431 for (int i = 0; i < fValue.count(); i++) { |
| 432 SkASSERT(fValue[i].key); | |
| 433 SkASSERT(fValue[i].value); | |
| 422 result += fValue[i].key->getOutputSize(catalog, false); | 434 result += fValue[i].key->getOutputSize(catalog, false); |
| 423 result += fValue[i].value->getOutputSize(catalog, false); | 435 result += fValue[i].value->getOutputSize(catalog, false); |
| 424 } | 436 } |
| 425 return result; | 437 return result; |
| 426 } | 438 } |
| 427 | 439 |
| 428 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) { | 440 SkPDFObject* SkPDFDict::appendRec(SkPDFName* key, SkPDFObject* value) { |
| 429 key->ref(); | 441 SkASSERT(key); |
| 430 value->ref(); | 442 SkASSERT(value); |
| 431 struct Rec* newEntry = fValue.append(); | 443 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while |
| 432 newEntry->key = key; | 444 // two threads access array, one |
| 433 newEntry->value = value; | 445 // is left with a bad pointer. |
| 446 *(fValue.append()) = Rec(key, value); | |
| 434 return value; | 447 return value; |
| 435 } | 448 } |
| 436 | 449 |
| 450 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) { | |
| 451 return this->appendRec(SkRef(key), SkRef(value)); | |
| 452 } | |
| 453 | |
| 437 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) { | 454 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) { |
| 438 value->ref(); | 455 return this->appendRec(new SkPDFName(key), SkRef(value)); |
| 439 struct Rec* newEntry = fValue.append(); | |
| 440 newEntry->key = new SkPDFName(key); | |
| 441 newEntry->value = value; | |
| 442 return value; | |
| 443 } | 456 } |
| 444 | 457 |
| 445 void SkPDFDict::insertInt(const char key[], int32_t value) { | 458 void SkPDFDict::insertInt(const char key[], int32_t value) { |
| 446 struct Rec* newEntry = fValue.append(); | 459 (void)this->appendRec(new SkPDFName(key), new SkPDFInt(value)); |
| 447 newEntry->key = new SkPDFName(key); | |
| 448 newEntry->value = new SkPDFInt(value); | |
| 449 } | 460 } |
| 450 | 461 |
| 451 void SkPDFDict::insertScalar(const char key[], SkScalar value) { | 462 void SkPDFDict::insertScalar(const char key[], SkScalar value) { |
| 452 struct Rec* newEntry = fValue.append(); | 463 (void)this->appendRec(new SkPDFName(key), new SkPDFScalar(value)); |
| 453 newEntry->key = new SkPDFName(key); | |
| 454 newEntry->value = new SkPDFScalar(value); | |
| 455 } | 464 } |
| 456 | 465 |
| 457 void SkPDFDict::insertName(const char key[], const char name[]) { | 466 void SkPDFDict::insertName(const char key[], const char name[]) { |
| 458 struct Rec* newEntry = fValue.append(); | 467 (void)this->appendRec(new SkPDFName(key), new SkPDFName(name)); |
| 459 newEntry->key = new SkPDFName(key); | |
| 460 newEntry->value = new SkPDFName(name); | |
| 461 } | 468 } |
| 462 | 469 |
| 463 void SkPDFDict::clear() { | 470 void SkPDFDict::clear() { |
| 471 SkAutoMutexAcquire lock(fMutex); | |
| 464 for (int i = 0; i < fValue.count(); i++) { | 472 for (int i = 0; i < fValue.count(); i++) { |
| 473 SkASSERT(fValue[i].key); | |
| 474 SkASSERT(fValue[i].value); | |
| 465 fValue[i].key->unref(); | 475 fValue[i].key->unref(); |
| 466 fValue[i].value->unref(); | 476 fValue[i].value->unref(); |
| 467 } | 477 } |
| 468 fValue.reset(); | 478 fValue.reset(); |
| 469 } | 479 } |
| 470 | 480 |
| 471 SkPDFDict::Iter::Iter(const SkPDFDict& dict) | 481 void SkPDFDict::remove(const char key[]) { |
| 472 : fIter(dict.fValue.begin()), | 482 SkASSERT(key); |
| 473 fStop(dict.fValue.end()) { | 483 SkPDFName name(key); |
| 484 SkAutoMutexAcquire lock(fMutex); | |
| 485 for (int i = 0; i < fValue.count(); i++) { | |
| 486 SkASSERT(fValue[i].key); | |
| 487 if (*(fValue[i].key) == name) { | |
| 488 fValue[i].key->unref(); | |
| 489 SkASSERT(fValue[i].value); | |
| 490 fValue[i].value->unref(); | |
| 491 fValue.removeShuffle(i); | |
| 492 return; | |
| 493 } | |
| 494 } | |
| 474 } | 495 } |
| 475 | 496 |
| 476 SkPDFName* SkPDFDict::Iter::next(SkPDFObject** value) { | 497 void SkPDFDict::insertDict(const SkPDFDict& other) { |
| 477 if (fIter != fStop) { | 498 SkAutoMutexAcquire lockOther(const_cast<SkMutex&>(other.fMutex)); |
|
mtklein
2014/06/27 15:26:51
fMutex should probably be mutable
hal.canary
2014/06/27 16:03:27
Done.
| |
| 478 const Rec* cur = fIter; | 499 SkAutoMutexAcquire lock(fMutex); |
|
mtklein
2014/06/27 15:26:51
Locking more than one lock should terrify you. We
hal.canary
2014/06/27 16:03:27
Done.
| |
| 479 fIter++; | 500 for (int i = 0; i < other.fValue.count(); i++) { |
| 480 *value = cur->value; | 501 *(fValue.append()) |
| 481 return cur->key; | 502 = Rec(SkRef(other.fValue[i].key), SkRef(other.fValue[i].value)); |
| 482 } | 503 } |
| 483 *value = NULL; | |
| 484 return NULL; | |
| 485 } | 504 } |
| OLD | NEW |