Helper function for temporary implementation of Clone by Object and subclasses. Should be eliminated once revision of the object model is complete.
| 172 | // Helper function for temporary implementation of Clone by Object and subclasses. |
| 173 | // Should be eliminated once revision of the object model is complete. |
| 174 | Object *Object::CloneTo(Object &obj) |
| 175 | { |
| 176 | // Allocate space in destination object. |
| 177 | auto field_count = mFields.Length(); |
| 178 | if (!obj.SetInternalCapacity(field_count)) |
| 179 | { |
| 180 | obj.Release(); |
| 181 | return NULL; |
| 182 | } |
| 183 | |
| 184 | int failure_count = 0; // See comment below. |
| 185 | index_t i; |
| 186 | |
| 187 | obj.mFields.Length() = field_count; |
| 188 | |
| 189 | for (i = 0; i < field_count; ++i) |
| 190 | { |
| 191 | FieldType &dst = obj.mFields[i]; |
| 192 | FieldType &src = mFields[i]; |
| 193 | |
| 194 | // Copy name. |
| 195 | dst.key_c = src.key_c; |
| 196 | if ( !(dst.name = _tcsdup(src.name)) ) |
| 197 | { |
| 198 | // Rather than trying to set up the object so that what we have |
| 199 | // so far is valid in order to break out of the loop, continue, |
| 200 | // make all fields valid and then allow them to be freed. |
| 201 | ++failure_count; |
| 202 | } |
| 203 | |
| 204 | // Copy value. |
| 205 | if (!dst.InitCopy(src)) |
| 206 | ++failure_count; |
| 207 | } |
| 208 | if (failure_count) |
| 209 | { |
| 210 | // One or more memory allocations failed. It seems best to return a clear failure |
| 211 | // indication rather than an incomplete copy. Now that the loop above has finished, |
| 212 | // the object's contents are at least valid and it is safe to free the object: |
| 213 | obj.Release(); |
| 214 | return NULL; |
| 215 | } |
| 216 | if (mBase) |
| 217 | obj.SetBase(mBase); |
| 218 | return &obj; |
| 219 | } |
| 220 | |
| 221 | Map *Map::CloneTo(Map &obj) |
| 222 | { |