| 472 | |
| 473 | |
| 474 | void Encoder::writeValue(const Value *value, |
| 475 | const SharedKeys* &sk, |
| 476 | const WriteValueFunc *writeNestedValue) |
| 477 | { |
| 478 | if (valueIsInBase(value) && !isNarrowValue(value)) { |
| 479 | auto minVal = minUsed(value); |
| 480 | if (minVal >= _baseCutoff) { |
| 481 | // Value is in the base data, and close enough; I can just emit a pointer to it: |
| 482 | writePointer( (ssize_t)value - (ssize_t)_base.end() ); |
| 483 | if (minVal && minVal < _baseMinUsed) |
| 484 | _baseMinUsed = minVal; |
| 485 | return; |
| 486 | } |
| 487 | } |
| 488 | switch (value->tag()) { |
| 489 | case kShortIntTag: |
| 490 | case kIntTag: |
| 491 | case kFloatTag: |
| 492 | case kSpecialTag: { |
| 493 | size_t size = value->dataSize(); |
| 494 | memcpy(placeValue<true>(size), value, size); |
| 495 | break; |
| 496 | } |
| 497 | case kStringTag: |
| 498 | writeString(value->asString()); |
| 499 | break; |
| 500 | case kBinaryTag: |
| 501 | writeData(value->asData()); |
| 502 | break; |
| 503 | case kArrayTag: { |
| 504 | ++_copyingCollection; |
| 505 | auto iter = value->asArray()->begin(); |
| 506 | beginArray(iter.count()); |
| 507 | for (; iter; ++iter) { |
| 508 | if (!writeNestedValue || !(*writeNestedValue)(nullptr, iter.value())) |
| 509 | writeValue(iter.value(), sk, writeNestedValue); |
| 510 | } |
| 511 | endArray(); |
| 512 | --_copyingCollection; |
| 513 | break; |
| 514 | } |
| 515 | case kDictTag: { |
| 516 | ++_copyingCollection; |
| 517 | auto dict = (const Dict*)value; |
| 518 | if (dict->isMutable()) { |
| 519 | dict->heapDict()->writeTo(*this/*, writeNestedValue*/); |
| 520 | } else { |
| 521 | auto iter = dict->begin(); |
| 522 | beginDictionary(iter.count()); |
| 523 | for (; iter; ++iter) { |
| 524 | if (!writeNestedValue || !(*writeNestedValue)(iter.key(), iter.value())) { |
| 525 | if (!sk && iter.key()->isInteger()) |
| 526 | sk = value->sharedKeys(); |
| 527 | writeKey(iter.key(), sk); |
| 528 | writeValue(iter.value(), sk, writeNestedValue); |
| 529 | } |
| 530 | } |
| 531 | endDictionary(); |
no test coverage detected