| 83 | BAIDU_CASSERT(sizeof(IsoItemsHead) == 1, size_assert); |
| 84 | |
| 85 | void ObjectIterator::operator++() { |
| 86 | if (_stream->popped_bytes() != _expected_popped_bytes) { |
| 87 | if (_stream->popped_bytes() + _current_field.value.size() == |
| 88 | _expected_popped_bytes) { |
| 89 | // skipping untouched values is acceptible. |
| 90 | _stream->popn(_current_field.value.size()); |
| 91 | } else if (_stream->popped_bytes() < _expected_popped_bytes) { |
| 92 | CHECK(false) << "value of name=" << _current_field.name |
| 93 | << " is not fully consumed, expected=" |
| 94 | << _expected_popped_bytes << " actually=" |
| 95 | << _stream->popped_bytes(); |
| 96 | return set_bad(); |
| 97 | } else { |
| 98 | CHECK(false) << "Over popped in value of name=" << _current_field.name |
| 99 | << " expected=" << _expected_popped_bytes << " actually=" |
| 100 | << _stream->popped_bytes(); |
| 101 | return set_bad(); |
| 102 | } |
| 103 | } |
| 104 | if (_expected_popped_bytes >= _expected_popped_end) { |
| 105 | return set_end(); |
| 106 | } |
| 107 | const uint8_t first_byte = _stream->peek1(); |
| 108 | if (first_byte & FIELD_FIXED_MASK) { |
| 109 | FieldFixedHead head; |
| 110 | if (_stream->cut_packed_pod(&head) != sizeof(FieldFixedHead) || |
| 111 | left_size() < head.full_size()) { |
| 112 | CHECK(false) << "buffer(size=" << left_size() << ") is not enough"; |
| 113 | return set_bad(); |
| 114 | } |
| 115 | _expected_popped_bytes = _stream->popped_bytes() + head.full_size() |
| 116 | - sizeof(FieldFixedHead); |
| 117 | if (!(head.type() & FIELD_NON_DELETED_MASK)) { |
| 118 | _stream->popn(head.full_size() - sizeof(FieldFixedHead)); |
| 119 | return operator++(); // tailr |
| 120 | } |
| 121 | _current_field.name = _stream->ref_cut(&_name_backup_string, head.name_size()); |
| 122 | if (!_current_field.name.empty()) { |
| 123 | _current_field.name.remove_suffix(1); |
| 124 | } |
| 125 | _current_field.value.set((FieldType)head.type(), _stream, head.value_size()); |
| 126 | } else if (first_byte & FIELD_SHORT_MASK) { |
| 127 | FieldShortHead head; |
| 128 | if (_stream->cut_packed_pod(&head) != sizeof(FieldShortHead) || |
| 129 | left_size() < head.full_size()) { |
| 130 | CHECK(false) << "buffer(size=" << left_size() << ") is not enough"; |
| 131 | return set_bad(); |
| 132 | } |
| 133 | _expected_popped_bytes = _stream->popped_bytes() + head.full_size() |
| 134 | - sizeof(FieldShortHead); |
| 135 | if (!(head.type() & FIELD_NON_DELETED_MASK)) { |
| 136 | // Skip deleted field. |
| 137 | _stream->popn(head.full_size() - sizeof(FieldShortHead)); |
| 138 | return operator++(); // tailr |
| 139 | } |
| 140 | // Remove FIELD_SHORT_MASK. |
| 141 | FieldType type = (FieldType)(head.type() & ~FIELD_SHORT_MASK); |
| 142 | _current_field.name = _stream->ref_cut(&_name_backup_string, head.name_size()); |
nothing calls this directly
no test coverage detected