1 /*
2 * TurboXSL XML+XSLT processing library
3 * common string functions
4 *
5 *
6 * (c) Egor Voznessenski, voznyak@mail.ru
7 *
8 * $Id$
9 *
10 **/
11 #include "strings.h"
12
13 #include <stdio.h>
14 #include <string.h>
15
16 #include "ltr_xsl.h"
17
xml_strcmp(const char * l,const char * r)18 int xml_strcmp(const char *l, const char *r)
19 {
20 if(l==r) return 0;
21 if(l==NULL) return -1;
22 if(r==NULL) return 1;
23 return strcmp(l,r);
24 }
25
xml_strcasecmp(char * l,char * r)26 int xml_strcasecmp(char *l, char *r)
27 {
28 if(l==r) return 0;
29 if(l==NULL) return -1;
30 if(r==NULL) return 1;
31 return strcasecmp(l,r);
32 }
33
xml_strdup(const char * s)34 char *xml_strdup(const char *s)
35 {
36 if(s==NULL) return NULL;
37 return xml_new_string(s, strlen(s));
38 }
39
xml_new_string(const char * s,size_t length)40 char *xml_new_string(const char *s, size_t length)
41 {
42 if(s==NULL) return NULL;
43
44 char *result = memory_allocator_new(length + 1);
45 memcpy(result, s, length);
46 return result;
47 }
48
xml_process_string(TRANSFORM_CONTEXT * pctx,XMLNODE * locals,XMLNODE * context,XMLSTRING string)49 XMLSTRING xml_process_string(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *context, XMLSTRING string)
50 {
51 if(!string) return NULL;
52
53 if(!strchr(string->s,'{') && !strchr(string->s,'}')) {
54 return xmls_new_string_literal(string->s);
55 }
56
57 XMLSTRING res = xmls_new(100);
58 char *s = xml_strdup(string->s);
59 while(*s) {
60 if(*s == '{') { //evaluate
61 ++s;
62 if(*s=='{') {
63 xmls_add_char(res, *s++);
64 continue;
65 }
66 char *p=strchr(s,'}');
67 if(p)
68 *p=0;
69 char *r = xpath_eval_string(pctx, locals, context, xpath_find_expr(pctx,xmls_new_string_literal(s)));
70 if(r) {
71 xmls_add_str(res, r);
72 }
73 if(p) {
74 *p = '}';
75 s = p+1;
76 }
77 else break;
78 } else {
79 if(*s=='}' && s[1]=='}')
80 ++s;
81 xmls_add_char(res, *s++);
82 }
83 }
84
85 return res;
86 }
87
88 /***************************** XMLSTRINGS ****************************/
xmls_new(size_t bsize)89 XMLSTRING xmls_new(size_t bsize)
90 {
91 XMLSTRING ret;
92 ret = memory_allocator_new(sizeof(struct _xmls));
93 ret->allocated = bsize;
94 ret->len = 0;
95 ret->s = memory_allocator_new(bsize + 1);
96 return ret;
97 }
98
xmls_new_string(const char * s,size_t length)99 XMLSTRING xmls_new_string(const char *s, size_t length)
100 {
101 if(s==NULL) return NULL;
102
103 XMLSTRING result = xmls_new(length);
104 memcpy(result->s, s, length);
105 result->len = length;
106
107 return result;
108 }
109
xmls_new_string_literal(const char * s)110 XMLSTRING xmls_new_string_literal(const char *s)
111 {
112 if(s==NULL) return NULL;
113
114 return xmls_new_string(s, strlen(s));
115 }
116
xmls_add_char(XMLSTRING s,char c)117 void xmls_add_char(XMLSTRING s, char c)
118 {
119 if(s->len >= s->allocated-2) {
120 char *data = s->s;
121 size_t data_size = s->allocated;
122 s->allocated = s->allocated*2 + 1;
123 s->s = memory_allocator_new(s->allocated);
124 memcpy(s->s, data, data_size);
125 }
126 s->s[s->len++] = c;
127 s->s[s->len] = 0;
128 }
129
xmls_add_utf(XMLSTRING s,unsigned u)130 void xmls_add_utf(XMLSTRING s, unsigned u)
131 {
132 if(u<128)
133 xmls_add_char(s,u);
134 else if(u<0x800) {
135 xmls_add_char(s,0xC0|(u>>6));
136 xmls_add_char(s,0x80|(u&0x3F));
137 }
138 else if(u<0x10000) {
139 xmls_add_char(s,0xE0|(u>>12));
140 xmls_add_char(s,0x80|((u>>6)&0x3F));
141 xmls_add_char(s,0x80|(u&0x3F));
142 }
143 else if(u<0x200000) {
144 xmls_add_char(s,0xF0|(u>>18));
145 xmls_add_char(s,0x80|((u>>12)&0x3F));
146 xmls_add_char(s,0x80|((u>>6)&0x3F));
147 xmls_add_char(s,0x80|(u&0x3F));
148 }
149 }
150
xmls_append(XMLSTRING s,XMLSTRING value)151 void xmls_append(XMLSTRING s, XMLSTRING value)
152 {
153 if (value == NULL) return;
154 xmls_add_str(s, value->s);
155 }
156
xmls_add_str(XMLSTRING s,const char * d)157 void xmls_add_str(XMLSTRING s, const char *d)
158 {
159 unsigned l;
160
161 if(!d)
162 return;
163 l = strlen(d)+1;
164 if(l==0)
165 return;
166
167 if(s->len+l >= s->allocated) {
168 char *data = s->s;
169 size_t data_size = s->allocated;
170 s->allocated = s->allocated*2 + l;
171 s->s = memory_allocator_new(s->allocated);
172 memcpy(s->s, data, data_size);
173 }
174 memcpy(s->s+s->len,d,l); // end null included!
175 s->len = s->len+l-1;
176 }
177
xmls_detach(XMLSTRING s)178 char *xmls_detach(XMLSTRING s)
179 {
180 if(!s) return NULL;
181 return s->s;
182 }
183
xmls_equals(XMLSTRING a,XMLSTRING b)184 int xmls_equals(XMLSTRING a, XMLSTRING b)
185 {
186 if(a == NULL && b == NULL) return 1;
187
188 if(a == NULL || b == NULL) return 0;
189 if(a->len != b->len) return 0;
190
191 return bcmp(a->s, b->s, a->len) == 0;
192 }
193
utf2ws(char * s)194 short *utf2ws(char *s)
195 {
196 short *ws;
197 short u;
198 int i,j;
199
200 if(!s)
201 return NULL;
202 ws = memory_allocator_new((strlen(s) + 1) * sizeof(short));
203 for(i=j=0;s[i];++i) {
204 u = 0;
205 if(s[i]&0x80) {
206 if((s[i]&0xE0)==0xC0) {
207 u = ((s[i]&0x1F)<<6)|(s[i+1]&0x3F);
208 ++i;
209 } else if((s[i]&0xF0)==0xE0) {
210 u = ((s[i]&0x0F)<<12)|((s[i+1]&0x3F)<<6)|(s[i+2]&0x3F);
211 i+=2;
212 }
213 } else {
214 u = s[i];
215 }
216 ws[j++]=u;
217 }
218 ws[j] = 0;
219 return ws;
220 }