2020
2121// //////////////////////////////////////////////////////////////////////////////
2222
23+ static bool __check_conformance (MCTypeInfoRef p_typeinfo, const MCValueRef *p_values, uindex_t p_value_count, uindex_t & x_offset)
24+ {
25+ if (p_typeinfo -> record . base != kMCNullTypeInfo )
26+ {
27+ MCTypeInfoRef t_resolved_typeinfo;
28+ t_resolved_typeinfo = __MCTypeInfoResolve (p_typeinfo);
29+ if (!__check_conformance (t_resolved_typeinfo, p_values, p_value_count, x_offset))
30+ return false ;
31+ }
32+
33+ if (x_offset + p_typeinfo -> record . field_count > p_value_count)
34+ return MCErrorThrowGeneric ();
35+
36+ for (uindex_t i = 0 ; i < p_typeinfo -> record . field_count; i++)
37+ if (MCTypeInfoConforms (MCValueGetTypeInfo (p_values[x_offset + i]), p_typeinfo -> record . fields[i] . type))
38+ return MCErrorThrowGeneric ();
39+
40+ return true ;
41+ }
42+
43+ static uindex_t __count_fields (MCTypeInfoRef p_typeinfo)
44+ {
45+ uindex_t t_count;
46+ if (p_typeinfo -> record . base != kMCNullTypeInfo )
47+ {
48+ MCTypeInfoRef t_resolved_typeinfo;
49+ t_resolved_typeinfo = __MCTypeInfoResolve (p_typeinfo);
50+ t_count = __count_fields (t_resolved_typeinfo);
51+ }
52+ else
53+ t_count = 0 ;
54+
55+ return t_count + p_typeinfo -> record . field_count;
56+ }
57+
2358bool MCRecordCreate (MCTypeInfoRef p_typeinfo, const MCValueRef *p_values, uindex_t p_value_count, MCRecordRef& r_record)
2459{
2560 bool t_success;
@@ -28,20 +63,18 @@ bool MCRecordCreate(MCTypeInfoRef p_typeinfo, const MCValueRef *p_values, uindex
2863 MCTypeInfoRef t_resolved_typeinfo;
2964 t_resolved_typeinfo = __MCTypeInfoResolve (p_typeinfo);
3065
31- if (p_value_count != t_resolved_typeinfo -> record . field_count)
32- return MCErrorThrowGeneric ();
33-
34- for (uindex_t i = 0 ; i < p_value_count; i++)
35- if (MCTypeInfoConforms (MCValueGetTypeInfo (p_values[i]), t_resolved_typeinfo -> record . fields[i] . type))
36- return MCErrorThrowGeneric ();
66+ uindex_t t_offset;
67+ if (!__check_conformance (t_resolved_typeinfo, p_values, p_value_count, t_offset))
68+ return false ;
3769
3870 __MCRecord *self;
3971 self = nil;
4072 if (t_success)
4173 t_success = __MCValueCreate (kMCValueTypeCodeRecord , self);
4274
75+ // Here 'offset' will be the total count of all fields.
4376 if (t_success)
44- t_success = MCMemoryNewArray (p_value_count , self -> fields);
77+ t_success = MCMemoryNewArray (t_offset , self -> fields);
4578
4679 if (t_success)
4780 {
@@ -70,17 +103,20 @@ bool MCRecordCreateMutable(MCTypeInfoRef p_typeinfo, MCRecordRef& r_record)
70103 MCTypeInfoRef t_resolved_typeinfo;
71104 t_resolved_typeinfo = __MCTypeInfoResolve (p_typeinfo);
72105
106+ uindex_t t_field_count;
107+ t_field_count = __count_fields (t_resolved_typeinfo);
108+
73109 __MCRecord *self;
74110 self = nil;
75111 if (t_success)
76112 t_success = __MCValueCreate (kMCValueTypeCodeRecord , self);
77113
78114 if (t_success)
79- t_success = MCMemoryNewArray (t_resolved_typeinfo -> record . field_count , self -> fields);
115+ t_success = MCMemoryNewArray (t_field_count , self -> fields);
80116
81117 if (t_success)
82118 {
83- for (uindex_t i = 0 ; i < t_resolved_typeinfo -> record . field_count ; i++)
119+ for (uindex_t i = 0 ; i < t_field_count ; i++)
84120 self -> fields[i] = MCValueRetain (kMCNull );
85121
86122 self -> flags |= kMCRecordFlagIsMutable ;
@@ -108,7 +144,7 @@ bool MCRecordCopy(MCRecordRef self, MCRecordRef& r_new_record)
108144 MCTypeInfoRef t_resolved_typeinfo;
109145 t_resolved_typeinfo = __MCTypeInfoResolve (self -> typeinfo);
110146
111- return MCRecordCreate (self -> typeinfo, self -> fields, t_resolved_typeinfo -> record . field_count , r_new_record);
147+ return MCRecordCreate (self -> typeinfo, self -> fields, __count_fields ( t_resolved_typeinfo) , r_new_record);
112148}
113149
114150bool MCRecordCopyAndRelease (MCRecordRef self, MCRecordRef& r_new_record)
@@ -133,7 +169,7 @@ bool MCRecordCopyAndRelease(MCRecordRef self, MCRecordRef& r_new_record)
133169
134170 // Otherwise make a copy of the data and then release the original
135171 bool t_success;
136- t_success = MCRecordCreate (self -> typeinfo, self -> fields, t_resolved_typeinfo -> record . field_count , r_new_record);
172+ t_success = MCRecordCreate (self -> typeinfo, self -> fields, __count_fields ( t_resolved_typeinfo) , r_new_record);
137173 MCValueRelease (self);
138174
139175 return t_success;
@@ -145,7 +181,7 @@ bool MCRecordMutableCopy(MCRecordRef self, MCRecordRef& r_new_record)
145181 t_resolved_typeinfo = __MCTypeInfoResolve (self -> typeinfo);
146182
147183 MCRecordRef t_new_self;
148- if (!MCRecordCreate (self -> typeinfo, self -> fields, t_resolved_typeinfo -> record . field_count , t_new_self))
184+ if (!MCRecordCreate (self -> typeinfo, self -> fields, __count_fields ( t_resolved_typeinfo) , t_new_self))
149185 return false ;
150186
151187 t_new_self -> flags |= kMCRecordFlagIsMutable ;
@@ -171,7 +207,7 @@ bool MCRecordIsMutable(MCRecordRef self)
171207 return (self -> flags & kMCRecordFlagIsMutable ) != 0 ;
172208}
173209
174- bool MCRecordFetchValue ( MCRecordRef self, MCNameRef p_field, MCValueRef& r_value)
210+ static bool __fetch_value (MCTypeInfoRef p_typeinfo, MCRecordRef self, MCNameRef p_field, MCValueRef& r_value)
175211{
176212 MCTypeInfoRef t_resolved_typeinfo;
177213 t_resolved_typeinfo = __MCTypeInfoResolve (self -> typeinfo);
@@ -183,10 +219,18 @@ bool MCRecordFetchValue(MCRecordRef self, MCNameRef p_field, MCValueRef& r_value
183219 return true ;
184220 }
185221
222+ if (p_typeinfo -> record . base != kMCNullTypeInfo )
223+ return __fetch_value (p_typeinfo -> record . base, self, p_field, r_value);
224+
186225 return false ;
187226}
188227
189- bool MCRecordStoreValue (MCRecordRef self, MCNameRef p_field, MCValueRef p_value)
228+ bool MCRecordFetchValue (MCRecordRef self, MCNameRef p_field, MCValueRef& r_value)
229+ {
230+ return __fetch_value (self -> typeinfo, self, p_field, r_value);
231+ }
232+
233+ static bool __store_value (MCTypeInfoRef p_typeinfo, MCRecordRef self, MCNameRef p_field, MCValueRef p_value)
190234{
191235 MCTypeInfoRef t_resolved_typeinfo;
192236 t_resolved_typeinfo = __MCTypeInfoResolve (self -> typeinfo);
@@ -200,18 +244,26 @@ bool MCRecordStoreValue(MCRecordRef self, MCNameRef p_field, MCValueRef p_value)
200244 self -> fields[i] = MCValueRetain (p_value);
201245 return true ;
202246 }
203-
247+
248+ if (p_typeinfo -> record . base != kMCNullTypeInfo )
249+ return __store_value (p_typeinfo -> record . base, self, p_field, p_value);
250+
204251 return false ;
205252}
206253
254+ bool MCRecordStoreValue (MCRecordRef self, MCNameRef p_field, MCValueRef p_value)
255+ {
256+ return __store_value (self -> typeinfo, self, p_field, p_value);
257+ }
258+
207259// //////////////////////////////////////////////////////////////////////////////
208260
209261void __MCRecordDestroy (__MCRecord *self)
210262{
211263 MCTypeInfoRef t_resolved_typeinfo;
212264 t_resolved_typeinfo = __MCTypeInfoResolve (self -> typeinfo);
213265
214- for (uindex_t i = 0 ; i < t_resolved_typeinfo -> record . field_count ; i++)
266+ for (uindex_t i = 0 ; i < __count_fields ( t_resolved_typeinfo) ; i++)
215267 MCValueRelease (self -> fields[i]);
216268 MCMemoryDelete (self -> fields);
217269}
@@ -223,7 +275,7 @@ hash_t __MCRecordHash(__MCRecord *self)
223275
224276 hash_t t_hash;
225277 t_hash = 0 ;
226- for (uindex_t i = 0 ; i < t_resolved_typeinfo -> record . field_count ; i++)
278+ for (uindex_t i = 0 ; i < __count_fields ( t_resolved_typeinfo) ; i++)
227279 {
228280 hash_t t_element_hash;
229281 t_element_hash = MCValueHash (self -> fields[i]);
@@ -242,7 +294,7 @@ bool __MCRecordIsEqualTo(__MCRecord *self, __MCRecord *other_self)
242294 t_resolved_typeinfo = __MCTypeInfoResolve (self -> typeinfo);
243295
244296 // Each field within the record must be equal to be equal.
245- for (uindex_t i = 0 ; i < t_resolved_typeinfo -> record . field_count ; i++)
297+ for (uindex_t i = 0 ; i < __count_fields ( t_resolved_typeinfo) ; i++)
246298 if (!MCValueIsEqualTo (self -> fields[i], other_self -> fields[i]))
247299 return false ;
248300
0 commit comments