| 99 | } |
| 100 | |
| 101 | bool Tuple::TryDeepCopyCollections(uint8_t** data, const uint8_t* data_end, int* offset, |
| 102 | const TupleDescriptor& desc, bool convert_ptrs) { |
| 103 | vector<SlotDescriptor*>::const_iterator slot = desc.collection_slots().begin(); |
| 104 | for (; slot != desc.collection_slots().end(); ++slot) { |
| 105 | DCHECK((*slot)->type().IsCollectionType()); |
| 106 | if (IsNull((*slot)->null_indicator_offset())) continue; |
| 107 | |
| 108 | CollectionValue* coll_value = GetCollectionSlot((*slot)->tuple_offset()); |
| 109 | const TupleDescriptor& item_desc = *(*slot)->children_tuple_descriptor(); |
| 110 | int coll_byte_size = coll_value->num_tuples * item_desc.byte_size(); |
| 111 | if (!TryMemCopy(*data, data_end, coll_byte_size, coll_value->ptr)) return false; |
| 112 | uint8_t* coll_data = reinterpret_cast<uint8_t*>(*data); |
| 113 | |
| 114 | coll_value->ptr = convert_ptrs ? reinterpret_cast<uint8_t*>(*offset) : coll_data; |
| 115 | |
| 116 | *data += coll_byte_size; |
| 117 | *offset += coll_byte_size; |
| 118 | |
| 119 | // Copy per-tuple varlen data if necessary. |
| 120 | if (!item_desc.HasVarlenSlots()) continue; |
| 121 | for (int i = 0; i < coll_value->num_tuples; ++i) { |
| 122 | Tuple* dst_item = reinterpret_cast<Tuple*>(coll_data); |
| 123 | if(!dst_item->TryDeepCopyStrings(data, data_end, offset, item_desc, convert_ptrs)) { |
| 124 | return false; |
| 125 | } |
| 126 | if(!dst_item->TryDeepCopyCollections( |
| 127 | data, data_end, offset, item_desc, convert_ptrs)) { |
| 128 | return false; |
| 129 | } |
| 130 | coll_data += item_desc.byte_size(); |
| 131 | } |
| 132 | } |
| 133 | return true; |
| 134 | } |
| 135 | |
| 136 | } |
no test coverage detected