e9f457dc4d1b07036cc7105228cd27976154c459
[com/gs-lite.git] / src / lib / gscplftaaux / rts_string.c
1 /* ------------------------------------------------
2 Copyright 2014 AT&T Intellectual Property
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7      http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License.
14  ------------------------------------------- */
15
16 #include "rts_external.h"
17 #include <stdio.h>
18 #include <regex.h>
19 #include "gsconfig.h"
20 #include "gstypes.h"
21
22
23 #include "stdlib.h"
24
25
26 gs_retval_t str_assign_with_copy(struct FTA * f, struct gs_string * dest, struct gs_string * src)
27 {
28     if ((dest->data = fta_alloc(f,src->length))==0) {
29         return -1;
30     }
31     dest->length=src->length;
32     dest->owner=f;    
33     memcpy(dest->data,src->data,src->length);
34     return 0;
35 }
36
37 gs_retval_t str_assign_with_copy_in_tuple(struct string32 * dest, struct gs_string * src,
38                                   gs_sp_t start, gs_sp_t buf)
39 {
40     gs_uint32_t st;
41     st=(unsigned int)(buf-start);
42 //    dest->length=htonl(src->length);
43 //    dest->reserved=htonl(0);
44 //    dest->offset=htonl(st);
45     dest->length=src->length;
46     dest->reserved=0;
47     dest->offset=st;
48     memcpy(buf,src->data,src->length);
49     return 0;
50 }
51
52
53
54 gs_retval_t str_replace( struct FTA * f, struct gs_string * dest, struct gs_string * src )
55 {
56     str_destroy(dest);
57     return str_assign_with_copy(f, dest, src);
58 }
59
60 // ---------------------------------------------------
61 /* Searching within a string */
62
63
64 gs_retval_t str_exists_substr( struct gs_string * s1, struct gs_string * s2)
65 {
66   register gs_uint8_t * st1 = (gs_uint8_t *)(s1->data);
67   register gs_uint8_t * st2 = (gs_uint8_t *)(s2->data);
68   register gs_uint8_t s2f=st2[0];
69   register gs_int32_t len1 = s1->length-s2->length; /* the lates point I have to find
70                                                 a match of the first char */
71   register gs_int32_t len2 = s2->length;
72   register gs_int32_t x,y;
73
74
75   for (x=0; x<len1 ; x++)
76   {
77       if (st1[x]==s2f) {
78           for (y=0; y<len2 && st1[x+y]==st2[y];y++);
79           if (y==len2) {
80               return 1;
81           }
82       }
83   }
84   return 0;
85 }
86
87
88 gs_uint32_t str_match_offset( gs_uint32_t offset, struct gs_string * s1, struct gs_string * s2) {
89   register gs_uint8_t * st1 = (gs_uint8_t *)(s1->data);
90   register gs_uint8_t * st2 = (gs_uint8_t *)(&s2->data[offset]);
91   register gs_int32_t x;
92   register gs_int32_t len2 = s2->length-offset;
93   register gs_int32_t len1 = s1->length;
94   if (len2<len1) return 0;
95   for(x=0; x<len1; x++) {
96     if (st1[x]!=st2[x]) return 0;
97   }
98   return 1;
99 }
100
101
102 gs_uint32_t byte_match_offset( gs_uint32_t offset, gs_uint32_t val, struct gs_string * s2) {
103   register gs_uint8_t * st2 = (gs_uint8_t *)(s2->data);
104   register gs_uint8_t v = (unsigned char) val;
105 //  if ((s2->length <= offset)||(offset<0)) return 0;
106   if (s2->length <= offset) return 0;
107   return (st2[offset]==v)?1:0;
108 }
109
110
111 gs_retval_t str_compare( struct gs_string * str1, struct gs_string * str2)
112 {
113     gs_int32_t len;
114     gs_int32_t x, ret;
115     len = (str1->length>str2->length)?str2->length:str1->length;
116     for(x=0;x<len;x++) {
117         if (ret = (str1->data[x]-str2->data[x]))
118             return ret;
119     }
120
121     if (str1->length>str2->length) {
122         return 1;
123     }
124     if (str2->length>str1->length) {
125         return -1;
126     }
127     return 0;
128 }
129
130 gs_retval_t str_equal( struct gs_string * str1, struct gs_string * str2)
131 {
132     gs_int32_t x;
133
134     if (str1->length != str2->length)
135         return -1;
136
137     for(x=0;x<str1->length;x++) {
138         if (str1->data[x]!=str2->data[x]) {
139             return -1;
140         }
141     }
142     
143     return 0;
144 }
145
146 ////////////////////////////////////
147 //      Substring functions
148
149 //       get last n bytes, if available
150 //       getting the prefix is done by str_truncate, defined in the include file
151 gs_retval_t str_suffix(struct gs_string * ret, struct gs_string *s, gs_uint32_t n){
152   register gs_uint8_t * st = s->data; 
153   int prefix = (n > s->length) ? 0 : s->length-n;  
154   ret->data = st + prefix;
155   ret->length = s->length-prefix;
156   ret->owner = 0;
157   return 0;
158 }
159
160
161 //      Split the string on sep, get the i'th substring, if any
162 gs_retval_t get_list_entry(struct gs_string * ret, struct gs_string *l, struct gs_string *sep, gs_uint32_t pos){
163         char s;
164         gs_int32_t c;
165
166         ret->data = l->data;    // empty return string
167         ret->owner=0;
168         ret->length = 0;
169
170         if(sep->length > 0){    // get the sep char, ensure the string is nonempty
171                 s = sep->data[0];
172         }else{
173                 return 0;
174         }
175
176         for(c=0;c < l->length && pos>0; ++c){
177                 if(l->data[c] == s){
178                         pos--;
179                 }
180         }
181
182         if(pos>0 || c >= l->length-1){ // not enough seps, or final string is empty
183                 return 0;
184         }
185         
186         ret->data = l->data + c;
187         for(; c<l->length && l->data[c] != s; ++c, ++ret->length);
188         
189         return 0;
190 }
191         
192
193 // ------------------------------------------------------
194
195 gs_retval_t str_constructor(struct gs_string *s, gs_csp_t l){
196     s->data =  (gs_sp_t)l;
197     s->length = 0;
198     while(l[s->length] != '\0') s->length++;
199     s->owner = NULL;    
200     return(0);
201 }
202
203
204 gs_param_handle_t register_handle_for_str_regex_match_slot_1(struct FTA * f,
205                                         struct gs_string* pattern) {
206     regex_t * reg;
207     if ((reg=(regex_t *) fta_alloc(0,sizeof(regex_t)))==0)  {
208         return 0;
209     }
210     if (regcomp(reg,(gs_sp_t)(pattern->data), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
211         return 0;
212     }
213     return (gs_param_handle_t) reg;
214 }
215
216 gs_uint32_t str_regex_match(struct gs_string* str, gs_param_handle_t pattern_handle) {
217     regex_t * reg = (regex_t *) pattern_handle ;
218     gs_sp_t source = (gs_sp_t)(str->data);
219     int res;
220     static gs_sp_t d=0;
221     static gs_uint32_t dlen=0;
222     // grow our static buffer to the longest string we ever see
223     if ((str->length+1) >= dlen) {
224         if (d!=0) fta_free(0,(void*)d);
225         dlen=0;
226         d=0;
227         if ((d=(gs_sp_t)fta_alloc(0,str->length+1))==0) return 0;
228         dlen=str->length+1;
229     }
230     
231     if (str->length==0) return 0;
232
233     // copy the string and 0 terminate it
234     memcpy((void *)d,(void *) str->data, str->length);
235     d[str->length]=0;
236     
237     res = REG_NOMATCH;
238     res = regexec(reg, d, 0, NULL, 0);
239     return (res==REG_NOMATCH)?0:1;
240 }
241
242
243 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
244     regex_t * x = (regex_t *) handle;
245     regfree(x);
246     if (x!=0) fta_free(0,(void *)x);
247     return 0;
248 }
249
250 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(struct FTA * f,
251                                         struct gs_string* pattern) {
252     regex_t * reg;
253     if ((reg=(regex_t *) fta_alloc(0,sizeof(regex_t)))==0)  {
254         return 0;
255     }
256     if (regcomp(reg,(gs_sp_t)(pattern->data), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
257         return 0;
258     }
259     return (gs_param_handle_t) reg;
260 }
261
262 gs_uint32_t str_partial_regex_match(struct gs_string* str,
263                              gs_param_handle_t pattern_handle,
264                              gs_uint32_t maxlen) {
265     regex_t * reg = (regex_t *) pattern_handle ;
266     gs_sp_t source = (gs_sp_t)(str->data);
267     gs_int32_t res;
268     gs_int32_t end;
269     static gs_sp_t d=0;
270     static gs_uint32_t dlen=0;
271     // grow our static buffer to the longest string we ever see
272     if ((str->length+1) >= dlen) {
273         if (d!=0) fta_free(0,d);
274         dlen=0;
275         d=0;
276         if ((d=(gs_sp_t)fta_alloc(0,str->length+1))==0) return 0;
277         dlen=str->length+1;
278     }
279     
280     if (str->length==0) return 0;
281     
282     end=(maxlen>(str->length))?(str->length):maxlen;
283  
284     // copy the string and 0 terminate it
285     memcpy((void *)d,(void *) str->data, end);
286     d[str->length]=0;
287  
288      /* HACK ALERT: commented out regnexec invocations to unbreak the build */
289     res = REG_NOMATCH;
290     res = regexec(reg,d, 0, NULL, 0);
291     return (res==REG_NOMATCH)?0:1;
292 }
293
294
295 gs_retval_t deregister_handle_for_str_partial_regex_match_slot_1(
296                                   gs_param_handle_t handle) {
297     regex_t * x = (regex_t *) handle;
298     regfree(x);
299     if (x!=0) fta_free(0,(void *)x);
300     return 0;
301 }
302
303
304
305 static gs_uint32_t nextint(struct gs_string *str , gs_uint32_t * offset, gs_uint32_t *res) {
306         gs_uint8_t * s = (gs_uint8_t *)(str->data);
307         gs_int32_t v = 0;
308         *res = 0;
309         while(*offset<str->length) {
310                 if ((s[*offset]>='0') && (s[*offset]<='9')) {
311                         v=1;
312                         *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
313                 } else {
314                         if (v!=0) { // got some valid result
315                                 return 1;
316                         } // otherwise skip leading grabage
317                 }
318                 (*offset)++;
319         }
320         return v;
321 }
322
323
324 gs_param_handle_t register_handle_for_strtoi_c_slot_0(struct FTA * f, struct gs_string* istr) {
325         gs_uint32_t offset,r;
326         offset=0;
327         if (nextint(istr,&offset,&r)!=0)
328                 return (gs_param_handle_t) r;
329         return (gs_param_handle_t) 0;
330 }
331 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
332         return 0;
333 }
334
335 gs_param_handle_t register_handle_for_strtoip_c_slot_0(struct FTA * f, struct gs_string* istr) {
336         gs_uint32_t ip1,ip2,ip3,ip4,offset,r;
337         offset=0;
338         if (nextint(istr,&offset,&ip1)==0) return (gs_param_handle_t)0;
339         if (nextint(istr,&offset,&ip2)==0) return (gs_param_handle_t)0;
340         if (nextint(istr,&offset,&ip3)==0) return (gs_param_handle_t)0;
341         if (nextint(istr,&offset,&ip4)==0) return (gs_param_handle_t)0;
342         r=ip1<<24|ip2<<16|ip3<<8|ip4;
343                 return (gs_param_handle_t)r;
344 }
345 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
346         return 0;
347 }
348
349
350 ///////////////////////////////////////////////////
351 //      ipv6 procedures
352
353
354
355 gs_retval_t ipv6_compare( struct ipv6_str i1, struct ipv6_str i2){
356     if(i1.v[0] > i2.v[0])
357         return 1;
358     if(i1.v[0] < i2.v[0])
359         return -1;
360     if(i1.v[1] > i2.v[1])
361         return 1;
362     if(i1.v[1] < i2.v[1])
363         return -1;
364     if(i1.v[2] > i2.v[2])
365         return 1;
366     if(i1.v[2] < i2.v[2])
367         return -1;
368     if(i1.v[3] > i2.v[3])
369         return 1;
370     if(i1.v[3] < i2.v[3])
371         return -1;
372
373     return 0;
374 }
375
376 gs_retval_t Ipv6_Constructor(struct ipv6_str *s, gs_sp_t l){
377         gs_uint32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0;
378         sscanf(l,"%x:%x:%x:%x:%x:%x:%x:%x",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
379         s->v[0] = ((i0 & 0xffff) << 16) | (i1 & 0xffff);
380         s->v[1] = ((i2 & 0xffff) << 16) | (i3 & 0xffff);
381         s->v[2] = ((i4 & 0xffff) << 16) | (i5 & 0xffff);
382         s->v[3] = ((i6 & 0xffff) << 16) | (i7 & 0xffff);
383     return(0);
384 }
385
386 struct ipv6_str And_Ipv6(const struct ipv6_str i1, const struct ipv6_str i2){
387         struct ipv6_str ret;
388         ret.v[0] = i1.v[0] & i2.v[0];
389         ret.v[1] = i1.v[1] & i2.v[1];
390         ret.v[2] = i1.v[2] & i2.v[2];
391         ret.v[3] = i1.v[3] & i2.v[3];
392         return ret;
393 }
394
395 struct ipv6_str Or_Ipv6(const struct ipv6_str i1, const struct ipv6_str i2){
396         struct ipv6_str ret;
397         ret.v[0] = i1.v[0] | i2.v[0];
398         ret.v[1] = i1.v[1] | i2.v[1];
399         ret.v[2] = i1.v[2] | i2.v[2];
400         ret.v[3] = i1.v[3] | i2.v[3];
401         return ret;
402 }
403 struct ipv6_str hton_ipv6(struct ipv6_str s){
404         struct ipv6_str ret;
405 //        ret.v[0] = htonl(s.v[0]);
406 //        ret.v[1] = htonl(s.v[1]);
407 //        ret.v[2] = htonl(s.v[2]);
408 //        ret.v[3] = htonl(s.v[3]);
409         ret.v[0] = s.v[0];
410         ret.v[1] = s.v[1];
411         ret.v[2] = s.v[2];
412         ret.v[3] = s.v[3];
413         return ret;
414 }
415
416 struct ipv6_str ntoh_ipv6(struct ipv6_str s){
417         struct ipv6_str ret;
418 //        ret.v[0] = ntohl(s.v[0]);
419 //        ret.v[1] = ntohl(s.v[1]);
420 //        ret.v[2] = ntohl(s.v[2]);
421 //        ret.v[3] = ntohl(s.v[3]);
422         ret.v[0] = s.v[0];
423         ret.v[1] = s.v[1];
424         ret.v[2] = s.v[2];
425         ret.v[3] = s.v[3];
426         return ret;
427 }
428
429