| 720 | } |
| 721 | |
| 722 | void Encoder::endCollection(tags tag) { |
| 723 | if (_usuallyFalse(_items->tag != tag)) { |
| 724 | if (_items->tag == kSpecialTag) |
| 725 | FleeceException::_throw(EncodeError, "endCollection: not in a collection"); |
| 726 | else |
| 727 | FleeceException::_throw(EncodeError, "ending wrong type of collection"); |
| 728 | } |
| 729 | |
| 730 | // Pop _items off the stack: |
| 731 | valueArray *items = _items; |
| 732 | pop(); |
| 733 | _writingKey = _blockedOnKey = false; |
| 734 | |
| 735 | auto nValues = items->size(); // includes keys if this is a dict! |
| 736 | auto count = (uint32_t)nValues; |
| 737 | if (_usuallyTrue(count > 0)) { |
| 738 | if (_usuallyTrue(tag == kDictTag)) { |
| 739 | count /= 2; |
| 740 | sortDict(*items); |
| 741 | } |
| 742 | |
| 743 | // Write the array/dict header to the outer Value: |
| 744 | size_t bufLen = 2; |
| 745 | if (count >= kLongArrayCount) |
| 746 | bufLen += SizeOfVarInt(count - kLongArrayCount); |
| 747 | uint32_t inlineCount = std::min(count, (uint32_t)kLongArrayCount); |
| 748 | byte *buf = placeValue<false>(tag, byte(inlineCount >> 8), bufLen); |
| 749 | buf[1] = (byte)(inlineCount & 0xFF); |
| 750 | if (count >= kLongArrayCount) |
| 751 | PutUVarInt(&buf[2], count - kLongArrayCount); |
| 752 | |
| 753 | checkPointerWidths(items, nextWritePos()); |
| 754 | if (items->wide) |
| 755 | buf[0] |= 0x08; // "wide" flag |
| 756 | |
| 757 | fixPointers(items); |
| 758 | |
| 759 | // Write the values: |
| 760 | if (items->wide) { |
| 761 | _out.write(&(*items)[0], kWide*nValues); |
| 762 | } else { |
| 763 | auto narrow = _out.reserveSpace<uint16_t>(nValues); |
| 764 | for (auto &v : *items) |
| 765 | ::memcpy(narrow++, &v, kNarrow); |
| 766 | } |
| 767 | } else { |
| 768 | byte *buf = placeValue<true>(tag, 0, 2); |
| 769 | buf[1] = 0; |
| 770 | } |
| 771 | |
| 772 | #ifndef NDEBUG |
| 773 | if (items->wide) { |
| 774 | _numWide++; |
| 775 | _wideCount += count; |
| 776 | } else { |
| 777 | _numNarrow++; |
| 778 | _narrowCount += count; |
| 779 | } |
nothing calls this directly
no test coverage detected