4 F_STRING* allot_string(CELL capacity)
6 F_STRING* string = allot_object(STRING_TYPE,
7 sizeof(F_STRING) + (capacity + 1) * CHARS);
8 /* strings are null-terminated in memory, even though they also
9 have a length field. The null termination allows us to add
10 the sizeof(F_STRING) to a Factor string to get a C-style
11 UTF16 string for C library calls. */
12 cput(SREF(string,capacity),(u16)'\0');
13 string->length = tag_fixnum(capacity);
17 /* call this after constructing a string */
18 void rehash_string(F_STRING* str)
22 CELL capacity = string_capacity(str);
23 for(i = 0; i < capacity; i++)
24 hash = 31*hash + string_nth(str,i);
25 str->hashcode = tag_fixnum(hash);
28 void primitive_rehash_string(void)
30 rehash_string(untag_string(dpop()));
34 F_STRING *string(CELL capacity, CELL fill)
38 F_STRING* string = allot_string(capacity);
40 for(i = 0; i < capacity; i++)
41 cput(SREF(string,i),fill);
43 rehash_string(string);
48 F_STRING* resize_string(F_STRING* string, F_FIXNUM capacity, u16 fill)
50 /* later on, do an optimization: if end of array is here, just grow */
52 CELL to_copy = string_capacity(string);
54 if(capacity < to_copy)
57 F_STRING* new_string = allot_string(capacity);
59 memcpy(new_string + 1,string + 1,to_copy * CHARS);
61 for(i = to_copy; i < capacity; i++)
62 cput(SREF(new_string,i),fill);
67 void primitive_resize_string(void)
70 CELL capacity = to_fixnum(dpeek2());
71 maybe_gc(string_size(capacity));
72 string = untag_string_fast(dpop());
73 drepl(tag_object(resize_string(string,capacity,F)));
76 F_STRING *memory_to_string(const BYTE* string, CELL length)
78 F_STRING* s = allot_string(length);
81 for(i = 0; i < length; i++)
83 cput(SREF(s,i),*string);
92 void primitive_memory_to_string(void)
94 CELL length = unbox_unsigned_cell();
95 BYTE *string = (BYTE*)unbox_unsigned_cell();
96 dpush(tag_object(memory_to_string(string,length)));
100 F_STRING *from_c_string(const char *c_string)
102 return memory_to_string((BYTE*)c_string,strlen(c_string));
106 void box_c_string(const char *c_string)
108 dpush(c_string ? tag_object(from_c_string(c_string)) : F);
112 char *to_c_string(F_STRING *s)
115 CELL capacity = string_capacity(s);
116 for(i = 0; i < capacity; i++)
118 u16 ch = string_nth(s,i);
119 if(ch == '\0' || ch > 255)
120 general_error(ERROR_C_STRING,tag_object(s));
123 return to_c_string_unchecked(s);
126 void string_to_memory(F_STRING *s, BYTE *string)
129 CELL capacity = string_capacity(s);
130 for(i = 0; i < capacity; i++)
131 string[i] = string_nth(s,i);
134 void primitive_string_to_memory(void)
136 BYTE *address = (BYTE*)unbox_unsigned_cell();
137 F_STRING *str = untag_string(dpop());
138 string_to_memory(str,address);
142 char *to_c_string_unchecked(F_STRING *s)
144 CELL capacity = string_capacity(s);
145 F_STRING *_c_str = allot_string(capacity / CHARS + 1);
146 BYTE *c_str = (BYTE*)(_c_str + 1);
147 string_to_memory(s,c_str);
148 c_str[capacity] = '\0';
153 char *unbox_c_string(void)
156 return (str ? to_c_string(untag_string(str)) : NULL);
160 u16* unbox_utf16_string(void)
162 /* Return pointer to first character */
163 return (u16*)(untag_string(dpop()) + 1);
166 void primitive_char_slot(void)
168 F_STRING* string = untag_string_fast(dpop());
169 CELL index = untag_fixnum_fast(dpop());
170 dpush(tag_fixnum(string_nth(string,index)));
173 void primitive_set_char_slot(void)
175 F_STRING* string = untag_string_fast(dpop());
176 CELL index = untag_fixnum_fast(dpop());
177 CELL value = untag_fixnum_fast(dpop());
178 set_string_nth(string,index,value);
181 F_FIXNUM string_compare(F_STRING* s1, F_STRING* s2)
183 CELL len1 = string_capacity(s1);
184 CELL len2 = string_capacity(s2);
186 CELL limit = (len1 < len2 ? len1 : len2);
191 u16 c1 = string_nth(s1,i);
192 u16 c2 = string_nth(s2,i);
201 void primitive_string_compare(void)
203 F_STRING* s2 = untag_string(dpop());
204 F_STRING* s1 = untag_string(dpop());
206 dpush(tag_fixnum(string_compare(s1,s2)));