]> gitweb.factorcode.org Git - factor.git/blob - vmpp/strings.cpp
Remove cruddy string encoding/decoding code from VM
[factor.git] / vmpp / strings.cpp
1 #include "master.hpp"
2
3 CELL string_nth(F_STRING* string, CELL index)
4 {
5         /* If high bit is set, the most significant 16 bits of the char
6         come from the aux vector. The least significant bit of the
7         corresponding aux vector entry is negated, so that we can
8         XOR the two components together and get the original code point
9         back. */
10         CELL ch = bget(SREF(string,index));
11         if((ch & 0x80) == 0)
12                 return ch;
13         else
14         {
15                 F_BYTE_ARRAY *aux = untag_byte_array_fast(string->aux);
16                 return (cget(BREF(aux,index * sizeof(u16))) << 7) ^ ch;
17         }
18 }
19
20 void set_string_nth_fast(F_STRING *string, CELL index, CELL ch)
21 {
22         bput(SREF(string,index),ch);
23 }
24
25 void set_string_nth_slow(F_STRING *string_, CELL index, CELL ch)
26 {
27         gc_root<F_STRING> string(string_);
28
29         F_BYTE_ARRAY *aux;
30
31         bput(SREF(string.untagged(),index),(ch & 0x7f) | 0x80);
32
33         if(string->aux == F)
34         {
35                 /* We don't need to pre-initialize the
36                 byte array with any data, since we
37                 only ever read from the aux vector
38                 if the most significant bit of a
39                 character is set. Initially all of
40                 the bits are clear. */
41                 aux = allot_array_internal<F_BYTE_ARRAY>(
42                         untag_fixnum_fast(string->length)
43                         * sizeof(u16));
44
45                 write_barrier(string.value());
46                 string->aux = tag_object(aux);
47         }
48         else
49                 aux = untag_byte_array_fast(string->aux);
50
51         cput(BREF(aux,index * sizeof(u16)),(ch >> 7) ^ 1);
52 }
53
54 /* allocates memory */
55 void set_string_nth(F_STRING* string, CELL index, CELL ch)
56 {
57         if(ch <= 0x7f)
58                 set_string_nth_fast(string,index,ch);
59         else
60                 set_string_nth_slow(string,index,ch);
61 }
62
63 /* Allocates memory */
64 F_STRING *allot_string_internal(CELL capacity)
65 {
66         F_STRING *string = allot<F_STRING>(string_size(capacity));
67
68         string->length = tag_fixnum(capacity);
69         string->hashcode = F;
70         string->aux = F;
71
72         return string;
73 }
74
75 /* Allocates memory */
76 void fill_string(F_STRING *string_, CELL start, CELL capacity, CELL fill)
77 {
78         gc_root<F_STRING> string(string_);
79
80         if(fill <= 0x7f)
81                 memset((void *)SREF(string.untagged(),start),fill,capacity - start);
82         else
83         {
84                 CELL i;
85
86                 for(i = start; i < capacity; i++)
87                         set_string_nth(string.untagged(),i,fill);
88         }
89 }
90
91 /* Allocates memory */
92 F_STRING *allot_string(CELL capacity, CELL fill)
93 {
94         gc_root<F_STRING> string(allot_string_internal(capacity));
95         fill_string(string.untagged(),0,capacity,fill);
96         return string.untagged();
97 }
98
99 void primitive_string(void)
100 {
101         CELL initial = to_cell(dpop());
102         CELL length = unbox_array_size();
103         dpush(tag_object(allot_string(length,initial)));
104 }
105
106 static bool reallot_string_in_place_p(F_STRING *string, CELL capacity)
107 {
108         return in_zone(&nursery,(CELL)string) && capacity <= string_capacity(string);
109 }
110
111 F_STRING* reallot_string(F_STRING *string_, CELL capacity)
112 {
113         gc_root<F_STRING> string(string_);
114
115         if(reallot_string_in_place_p(string.untagged(),capacity))
116         {
117                 string->length = tag_fixnum(capacity);
118
119                 if(string->aux != F)
120                 {
121                         F_BYTE_ARRAY *aux = untag_byte_array_fast(string->aux);
122                         aux->capacity = tag_fixnum(capacity * 2);
123                 }
124
125                 return string.untagged();
126         }
127         else
128         {
129                 CELL to_copy = string_capacity(string.untagged());
130                 if(capacity < to_copy)
131                         to_copy = capacity;
132
133                 gc_root<F_STRING> new_string(allot_string_internal(capacity));
134
135                 memcpy(new_string.untagged() + 1,string.untagged() + 1,to_copy);
136
137                 if(string->aux != F)
138                 {
139                         F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16));
140
141                         write_barrier(new_string.value());
142                         new_string->aux = tag_object(new_aux);
143
144                         F_BYTE_ARRAY *aux = untag_byte_array_fast(string->aux);
145                         memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16));
146                 }
147
148                 fill_string(new_string.untagged(),to_copy,capacity,'\0');
149                 return new_string.untagged();
150         }
151 }
152
153 void primitive_resize_string(void)
154 {
155         F_STRING* string = untag_string(dpop());
156         CELL capacity = unbox_array_size();
157         dpush(tag_object(reallot_string(string,capacity)));
158 }
159
160 void primitive_string_nth(void)
161 {
162         F_STRING *string = untag_string_fast(dpop());
163         CELL index = untag_fixnum_fast(dpop());
164         dpush(tag_fixnum(string_nth(string,index)));
165 }
166
167 void primitive_set_string_nth(void)
168 {
169         F_STRING *string = untag_string_fast(dpop());
170         CELL index = untag_fixnum_fast(dpop());
171         CELL value = untag_fixnum_fast(dpop());
172         set_string_nth(string,index,value);
173 }
174
175 void primitive_set_string_nth_fast(void)
176 {
177         F_STRING *string = untag_string_fast(dpop());
178         CELL index = untag_fixnum_fast(dpop());
179         CELL value = untag_fixnum_fast(dpop());
180         set_string_nth_fast(string,index,value);
181 }
182
183 void primitive_set_string_nth_slow(void)
184 {
185         F_STRING *string = untag_string_fast(dpop());
186         CELL index = untag_fixnum_fast(dpop());
187         CELL value = untag_fixnum_fast(dpop());
188         set_string_nth_slow(string,index,value);
189 }