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 }