Skip to content

Commit fc18a8b

Browse files
author
runrevali
committed
Improve map native code
1 parent 63e8b08 commit fc18a8b

4 files changed

Lines changed: 244 additions & 5 deletions

File tree

libfoundation/include/foundation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,11 @@ bool MCArrayIsMutable(MCArrayRef array);
20192019
// Returns the number of elements in the array.
20202020
uindex_t MCArrayGetCount(MCArrayRef array);
20212021

2022+
// Returns whether the keys of the array have been predesignated case sensitive or not.
2023+
bool MCArrayIsCaseSensitive(MCArrayRef array);
2024+
// Returns whether the keys of the array have been predesignated form sensitive or not.
2025+
bool MCArrayIsFormSensitive(MCArrayRef array);
2026+
20222027
// Fetch the value from the array with the given key. The returned value is
20232028
// not retained. If being stored elsewhere ValueCopy should be used to make an
20242029
// immutable copy first. If 'false' is returned it means the key was not found

libfoundation/src/foundation-array.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ bool MCArrayCreateMutable(MCArrayRef& r_array)
8888
return true;
8989
}
9090

91+
bool MCArrayCreateMutableWithOptions(MCArrayRef& r_array, bool p_case_sensitive, bool p_form_sensitive)
92+
{
93+
if (!__MCValueCreate(kMCValueTypeCodeArray, r_array))
94+
return false;
95+
96+
r_array -> flags |= kMCArrayFlagIsMutable;
97+
98+
if (p_case_sensitive)
99+
r_array -> flags |= kMCArrayFlagIsCaseSensitive;
100+
101+
if (p_case_sensitive)
102+
r_array -> flags |= kMCArrayFlagIsFormSensitive;
103+
104+
return true;
105+
}
106+
91107
bool MCArrayCopy(MCArrayRef self, MCArrayRef& r_new_array)
92108
{
93109
// If we aren't mutable, then we can just copy directly.
@@ -276,6 +292,16 @@ uindex_t MCArrayGetCount(MCArrayRef self)
276292
return self -> contents -> key_value_count;
277293
}
278294

295+
bool MCArrayIsCaseSensitive(MCArrayRef self)
296+
{
297+
return (self -> flags & kMCArrayFlagIsCaseSensitive) != 0;
298+
}
299+
300+
bool MCArrayIsFormSensitive(MCArrayRef self)
301+
{
302+
return (self -> flags & kMCArrayFlagIsFormSensitive) != 0;
303+
}
304+
279305
////////////////////////////////////////////////////////////////////////////////
280306

281307
bool MCArrayFetchValue(MCArrayRef self, bool p_case_sensitive, MCNameRef p_key, MCValueRef& r_value)

libfoundation/src/foundation-private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ enum
221221
// If set then the array is indirect (i.e. contents is within another
222222
// immutable array).
223223
kMCArrayFlagIsIndirect = 1 << 7,
224+
// If set then the array keys are case sensitive.
225+
kMCArrayFlagIsCaseSensitive = 1 << 8,
226+
// If set the the array keys are form sensitive.
227+
kMCArrayFlagIsFormSensitive = 1 << 9,
224228
};
225229

226230
struct __MCArrayKeyValue

modular/library/src/module-map.cpp

Lines changed: 209 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,99 @@
1515
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1616

1717
#include <foundation.h>
18+
#include <foundation-auto.h>
1819

19-
void MCMapEvalKeysOf(MCArrayRef p_target, MCProperListRef& r_output)
20+
static bool create_key_for_array(MCStringRef p_string, MCArrayRef p_target, MCNameRef& r_key)
21+
{
22+
MCAutoStringRef t_key_string;
23+
24+
bool t_success;
25+
t_success = true;
26+
27+
if (MCArrayIsFormSensitive(p_target) && !MCStringIsNative(p_string))
28+
{
29+
t_success = MCStringCreateWithBytes((const byte_t *)MCStringGetCharPtr(p_string), MCStringGetLength(p_string) * 2, kMCStringEncodingNative, false, &t_key_string);
30+
}
31+
else
32+
t_key_string = p_string;
33+
34+
35+
if (t_success)
36+
t_success = MCNameCreate(*t_key_string, r_key);
37+
38+
return t_success;
39+
}
40+
41+
static bool create_key_for_matrix(MCProperListRef p_list, MCNameRef*& r_path, uindex_t& r_length)
2042
{
43+
bool t_success;
44+
t_success = true;
2145

46+
MCAutoArray<MCNameRef> t_path;
47+
for (uindex_t i = 0; t_success && i < MCProperListGetLength(p_list); i++)
48+
{
49+
MCValueRef t_list_element;
50+
t_list_element = MCProperListFetchElementAtIndex(p_list, i);
51+
52+
t_success = MCValueGetTypeCode(t_list_element) == kMCValueTypeCodeNumber
53+
&& MCNumberIsInteger((MCNumberRef)t_list_element);
54+
55+
MCAutoStringRef t_string;
56+
MCNameRef t_key;
57+
t_key = nil;
58+
if (t_success)
59+
t_success = MCStringFormat(&t_string, "%d", MCNumberFetchAsInteger((MCNumberRef)t_list_element))
60+
&& MCNameCreate(*t_string, t_key);
61+
62+
if (t_success)
63+
t_success = t_path . Push(t_key);
64+
65+
if (!t_success)
66+
MCValueRelease(t_key);
67+
}
68+
69+
t_path . Take(r_path, r_length);
70+
return t_success;
71+
}
72+
73+
static bool is_not_among_the_elements_of(void *context, MCArrayRef p_target, MCNameRef p_key, MCValueRef p_value)
74+
{
75+
MCValueRef t_needle = (MCValueRef)context;
76+
return !MCValueIsEqualTo(t_needle, p_value);
77+
}
78+
79+
static bool list_array_keys(void *context, MCArrayRef p_target, MCNameRef p_key, MCValueRef p_value)
80+
{
81+
MCProperListRef t_list = (MCProperListRef)context;
82+
return MCProperListPushElement(t_list, p_key);
83+
}
84+
85+
static bool list_array_elements(void *context, MCArrayRef p_target, MCNameRef p_key, MCValueRef p_value)
86+
{
87+
MCProperListRef t_list = (MCProperListRef)context;
88+
return MCProperListPushElement(t_list, p_value);
89+
}
90+
91+
void MCMapEvalKeysOf(MCArrayRef p_target, MCProperListRef& r_output)
92+
{
93+
MCProperListRef t_list;
94+
if (MCProperListCreateMutable(t_list) &&
95+
MCArrayApply(p_target, list_array_keys, t_list) &&
96+
MCProperListCopyAndRelease(t_list, r_output))
97+
return;
98+
99+
// ctxt . Throw()
22100
}
23101

24102
void MCMapEvalElementsOf(MCArrayRef p_target, MCProperListRef& r_output)
25103
{
104+
MCProperListRef t_list;
105+
if (MCProperListCreateMutable(t_list) &&
106+
MCArrayApply(p_target, list_array_elements, t_list) &&
107+
MCProperListCopyAndRelease(t_list, r_output))
108+
return;
26109

110+
// ctxt . Throw()
27111
}
28112

29113
void MCMapEvalNumberOfElementsIn(MCArrayRef p_target, uindex_t& r_output)
@@ -33,50 +117,170 @@ void MCMapEvalNumberOfElementsIn(MCArrayRef p_target, uindex_t& r_output)
33117

34118
void MCMapEvalIsAmongTheElementsOf(MCValueRef p_needle, bool p_is_not, MCArrayRef p_target, bool& r_output)
35119
{
36-
120+
r_output = !MCArrayApply(p_target, is_not_among_the_elements_of, p_needle);
37121
}
38122

39-
void MCMapEvalIsAmongTheKeysOfCaseless(MCStringRef p_needle, bool p_is_not, MCArrayRef p_target, bool& r_output)
123+
void MCMapEvalIsAmongTheKeysOf(MCStringRef p_needle, bool p_is_not, MCArrayRef p_target, bool& r_output)
40124
{
125+
MCNewAutoNameRef t_key;
126+
create_key_for_array(p_needle, p_target, &t_key);
127+
128+
MCValueRef t_value;
129+
t_value = nil;
41130

131+
r_output = MCArrayFetchValue(p_target, MCArrayIsCaseSensitive(p_target), *t_key, t_value);
42132
}
43133

44134
void MCMapEvalIsAmongTheKeysOfNumeric(integer_t p_needle, bool p_is_not, MCArrayRef p_target, bool& r_output)
45135
{
136+
MCAutoStringRef t_string;
137+
if (MCStringFormat(&t_string, "%d", p_needle))
138+
{
139+
MCMapEvalIsAmongTheKeysOf(*t_string, p_is_not, p_target, r_output);
140+
return;
141+
}
46142

143+
// ctxt . Throw
47144
}
48145

49146
void MCMapEvalIsAmongTheKeysOfMatrix(MCProperListRef p_needle, bool p_is_not, MCArrayRef p_target, bool& r_output)
50147
{
148+
bool t_output;
149+
t_output = false;
150+
151+
MCNameRef *t_path;
152+
uindex_t t_path_length;
153+
if (create_key_for_matrix(p_needle, t_path, t_path_length))
154+
{
155+
MCValueRef t_value;
156+
t_value = nil;
157+
t_output = MCArrayFetchValueOnPath(p_target, true, t_path, t_path_length, t_value);
158+
}
159+
160+
for (uindex_t i = 0; i < t_path_length; i++)
161+
MCValueRelease(t_path[i]);
162+
163+
MCMemoryDeleteArray(t_path);
164+
165+
r_output = t_output;
166+
}
167+
168+
void MCMapFetchElementOfBinary(MCArrayRef p_target, MCDataRef p_key, MCValueRef& r_output)
169+
{
170+
MCAutoStringRef t_key_string;
171+
MCNewAutoNameRef t_key;
172+
173+
if (MCStringCreateWithBytes(MCDataGetBytePtr(p_key), MCDataGetLength(p_key), kMCStringEncodingNative, false, &t_key_string) &&
174+
MCNameCreate(*t_key_string, &t_key) &&
175+
MCArrayFetchValue(p_target, false, *t_key, r_output))
176+
{
177+
MCValueRetain(r_output);
178+
return;
179+
}
180+
}
181+
182+
void MCMapStoreElementOfBinary(MCValueRef p_value, MCArrayRef& x_target, MCDataRef p_key)
183+
{
184+
MCAutoStringRef t_key_string;
185+
MCNewAutoNameRef t_key;
186+
187+
if (MCStringCreateWithBytes(MCDataGetBytePtr(p_key), MCDataGetLength(p_key), kMCStringEncodingNative, false, &t_key_string) &&
188+
MCNameCreate(*t_key_string, &t_key) &&
189+
MCArrayStoreValue(x_target, false, *t_key, p_value))
190+
return;
51191

192+
// ctxt . Throw()
52193
}
53194

54-
void MCMapFetchElementOfCaseless(MCArrayRef p_target, MCStringRef p_key, MCValueRef& r_output)
195+
void MCMapFetchElementOf(MCArrayRef p_target, MCStringRef p_key, MCValueRef& r_output)
55196
{
197+
MCNewAutoNameRef t_key;
56198

199+
if (create_key_for_array(p_key, p_target, &t_key) &&
200+
MCArrayFetchValue(p_target, MCArrayIsCaseSensitive(p_target), *t_key, r_output))
201+
{
202+
MCValueRetain(r_output);
203+
return;
204+
205+
}
206+
207+
// ctxt . Throw();
57208
}
58209

59-
void MCMapStoreElementOfCaseless(MCValueRef p_value, MCArrayRef& x_target, MCStringRef p_key)
210+
void MCMapStoreElementOf(MCValueRef p_value, MCArrayRef& x_target, MCStringRef p_key)
60211
{
212+
MCNewAutoNameRef t_key;
61213

214+
if (create_key_for_array(p_key, x_target, &t_key) &&
215+
MCArrayStoreValue(x_target, MCArrayIsCaseSensitive(x_target), *t_key, p_value))
216+
return;
217+
218+
// ctxt . Throw();
62219
}
63220

64221
void MCMapFetchElementOfNumeric(MCArrayRef p_target, integer_t p_key, MCValueRef& r_output)
65222
{
223+
MCAutoStringRef t_string;
224+
if (MCStringFormat(&t_string, "%d", p_key))
225+
{
226+
MCMapFetchElementOf(p_target, *t_string, r_output);
227+
return;
228+
}
66229

230+
// ctxt . Throw
67231
}
68232

69233
void MCMapStoreElementOfNumeric(MCValueRef p_value, MCArrayRef& x_target, integer_t p_key)
70234
{
235+
MCAutoStringRef t_string;
236+
if (MCStringFormat(&t_string, "%d", p_key))
237+
{
238+
MCMapStoreElementOf(p_value, x_target, *t_string);
239+
return;
240+
}
71241

242+
// ctxt . Throw
72243
}
73244

74245
void MCMapFetchElementOfMatrix(MCArrayRef p_target, MCProperListRef p_key, MCValueRef& r_output)
75246
{
247+
bool t_found;
248+
249+
MCNameRef *t_path;
250+
uindex_t t_path_length;
251+
t_found = create_key_for_matrix(p_key, t_path, t_path_length) &&
252+
MCArrayFetchValueOnPath(p_target, true, t_path, t_path_length, r_output);
253+
254+
for (uindex_t i = 0; i < t_path_length; i++)
255+
MCValueRelease(t_path[i]);
76256

257+
MCMemoryDeleteArray(t_path);
258+
259+
if (t_found)
260+
{
261+
MCValueRetain(r_output);
262+
return;
263+
}
264+
265+
// ctxt . Throw()
77266
}
78267

79268
void MCMapStoreElementOfMatrix(MCValueRef p_value, MCArrayRef& x_target, MCProperListRef p_key)
80269
{
270+
bool t_success;
271+
272+
MCNameRef *t_path;
273+
uindex_t t_path_length;
274+
t_success = create_key_for_matrix(p_key, t_path, t_path_length) &&
275+
MCArrayStoreValueOnPath(x_target, true, t_path, t_path_length, p_value);
276+
277+
for (uindex_t i = 0; i < t_path_length; i++)
278+
MCValueRelease(t_path[i]);
279+
280+
MCMemoryDeleteArray(t_path);
281+
282+
if (t_success)
283+
return;
81284

285+
// ctxt . Throw()
82286
}

0 commit comments

Comments
 (0)