8c3165767ba77ecb198ef897cc5c3e6deeda8233
[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 /* Searching within a string */
61
62
63 gs_retval_t str_exists_substr( struct gs_string * s1, struct gs_string * s2)
64 {
65   register gs_uint8_t * st1 = (gs_uint8_t *)(s1->data);
66   register gs_uint8_t * st2 = (gs_uint8_t *)(s2->data);
67   register gs_uint8_t s2f=st2[0];
68   register gs_int32_t len1 = s1->length-s2->length; /* the lates point I have to find
69                                                 a match of the first char */
70   register gs_int32_t len2 = s2->length;
71   register gs_int32_t x,y;
72
73
74   for (x=0; x<len1 ; x++)
75   {
76       if (st1[x]==s2f) {
77           for (y=0; y<len2 && st1[x+y]==st2[y];y++);
78           if (y==len2) {
79               return 1;
80           }
81       }
82   }
83   return 0;
84 }
85
86
87 gs_uint32_t str_match_offset( gs_uint32_t offset, struct gs_string * s1, struct gs_string * s2) {
88   register gs_uint8_t * st1 = (gs_uint8_t *)(s1->data);
89   register gs_uint8_t * st2 = (gs_uint8_t *)(&s2->data[offset]);
90   register gs_int32_t x;
91   register gs_int32_t len2 = s2->length-offset;
92   register gs_int32_t len1 = s1->length;
93   if (len2<len1) return 0;
94   for(x=0; x<len1; x++) {
95     if (st1[x]!=st2[x]) return 0;
96   }
97   return 1;
98 }
99
100
101 gs_uint32_t byte_match_offset( gs_uint32_t offset, gs_uint32_t val, struct gs_string * s2) {
102   register gs_uint8_t * st2 = (gs_uint8_t *)(s2->data);
103   register gs_uint8_t v = (unsigned char) val;
104 //  if ((s2->length <= offset)||(offset<0)) return 0;
105   if (s2->length <= offset) return 0;
106   return (st2[offset]==v)?1:0;
107 }
108
109
110 gs_retval_t str_compare( struct gs_string * str1, struct gs_string * str2)
111 {
112     gs_int32_t len;
113     gs_int32_t x;
114     len = (str1->length>str2->length)?str2->length:str1->length;
115     for(x=0;x<len;x++) {
116         if (str1->data[x]>str2->data[x]) {
117             return 1;
118         }
119         if (str1->data[x]<str2->data[x]) {
120             return -1;
121         }
122     }
123
124     if (str1->length>str2->length) {
125         return 1;
126     }
127     if (str2->length>str1->length) {
128         return -1;
129     }
130     return 0;
131 }
132
133 gs_retval_t str_constructor(struct gs_string *s, gs_sp_t l){
134     s->data =  l;
135     s->length = 0;
136     while(l[s->length] != '\0') s->length++;
137     s->owner = NULL;    
138     return(0);
139 }
140
141
142 gs_param_handle_t register_handle_for_str_regex_match_slot_1(struct FTA * f,
143                                         struct gs_string* pattern) {
144     regex_t * reg;
145     if ((reg=(regex_t *) fta_alloc(0,sizeof(regex_t)))==0)  {
146         return 0;
147     }
148     if (regcomp(reg,(gs_sp_t)(pattern->data), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
149         return 0;
150     }
151     return (gs_param_handle_t) reg;
152 }
153
154 gs_uint32_t str_regex_match(struct gs_string* str, gs_param_handle_t pattern_handle) {
155     regex_t * reg = (regex_t *) pattern_handle ;
156     gs_sp_t source = (gs_sp_t)(str->data);
157     int res;
158     static gs_sp_t d=0;
159     static gs_uint32_t dlen=0;
160     // grow our static buffer to the longest string we ever see
161     if ((str->length+1) >= dlen) {
162         if (d!=0) fta_free(0,(void*)d);
163         dlen=0;
164         d=0;
165         if ((d=(gs_sp_t)fta_alloc(0,str->length+1))==0) return 0;
166         dlen=str->length+1;
167     }
168     
169     if (str->length==0) return 0;
170
171     // copy the string and 0 terminate it
172     memcpy((void *)d,(void *) str->data, str->length);
173     d[str->length]=0;
174     
175     res = REG_NOMATCH;
176     res = regexec(reg, d, 0, NULL, 0);
177     return (res==REG_NOMATCH)?0:1;
178 }
179
180
181 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
182     regex_t * x = (regex_t *) handle;
183     regfree(x);
184     if (x!=0) fta_free(0,(void *)x);
185     return 0;
186 }
187
188 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(struct FTA * f,
189                                         struct gs_string* pattern) {
190     regex_t * reg;
191     if ((reg=(regex_t *) fta_alloc(0,sizeof(regex_t)))==0)  {
192         return 0;
193     }
194     if (regcomp(reg,(gs_sp_t)(pattern->data), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
195         return 0;
196     }
197     return (gs_param_handle_t) reg;
198 }
199
200 gs_uint32_t str_partial_regex_match(struct gs_string* str,
201                              gs_param_handle_t pattern_handle,
202                              gs_uint32_t maxlen) {
203     regex_t * reg = (regex_t *) pattern_handle ;
204     gs_sp_t source = (gs_sp_t)(str->data);
205     gs_int32_t res;
206     gs_int32_t end;
207     static gs_sp_t d=0;
208     static gs_uint32_t dlen=0;
209     // grow our static buffer to the longest string we ever see
210     if ((str->length+1) >= dlen) {
211         if (d!=0) fta_free(0,d);
212         dlen=0;
213         d=0;
214         if ((d=(gs_sp_t)fta_alloc(0,str->length+1))==0) return 0;
215         dlen=str->length+1;
216     }
217     
218     if (str->length==0) return 0;
219     
220     end=(maxlen>(str->length))?(str->length):maxlen;
221  
222     // copy the string and 0 terminate it
223     memcpy((void *)d,(void *) str->data, end);
224     d[str->length]=0;
225  
226      /* HACK ALERT: commented out regnexec invocations to unbreak the build */
227     res = REG_NOMATCH;
228     res = regexec(reg,d, 0, NULL, 0);
229     return (res==REG_NOMATCH)?0:1;
230 }
231
232
233 gs_retval_t deregister_handle_for_str_partial_regex_match_slot_1(
234                                   gs_param_handle_t handle) {
235     regex_t * x = (regex_t *) handle;
236     regfree(x);
237     if (x!=0) fta_free(0,(void *)x);
238     return 0;
239 }
240
241
242
243 static gs_uint32_t nextint(struct gs_string *str , gs_uint32_t * offset, gs_uint32_t *res) {
244         gs_uint8_t * s = (gs_uint8_t *)(str->data);
245         gs_int32_t v = 0;
246         *res = 0;
247         while(*offset<str->length) {
248                 if ((s[*offset]>='0') && (s[*offset]<='9')) {
249                         v=1;
250                         *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
251                 } else {
252                         if (v!=0) { // got some valid result
253                                 return 1;
254                         } // otherwise skip leading grabage
255                 }
256                 (*offset)++;
257         }
258         return v;
259 }
260
261
262 gs_param_handle_t register_handle_for_strtoi_c_slot_0(struct FTA * f, struct gs_string* istr) {
263         gs_uint32_t offset,r;
264         offset=0;
265         if (nextint(istr,&offset,&r)!=0)
266                 return (gs_param_handle_t) r;
267         return (gs_param_handle_t) 0;
268 }
269 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
270         return 0;
271 }
272
273 gs_param_handle_t register_handle_for_strtoip_c_slot_0(struct FTA * f, struct gs_string* istr) {
274         gs_uint32_t ip1,ip2,ip3,ip4,offset,r;
275         offset=0;
276         if (nextint(istr,&offset,&ip1)==0) return (gs_param_handle_t)0;
277         if (nextint(istr,&offset,&ip2)==0) return (gs_param_handle_t)0;
278         if (nextint(istr,&offset,&ip3)==0) return (gs_param_handle_t)0;
279         if (nextint(istr,&offset,&ip4)==0) return (gs_param_handle_t)0;
280         r=ip1<<24|ip2<<16|ip3<<8|ip4;
281                 return (gs_param_handle_t)r;
282 }
283 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
284         return 0;
285 }
286
287
288 ///////////////////////////////////////////////////
289 //      ipv6 procedures
290
291
292
293 gs_retval_t ipv6_compare( struct ipv6_str i1, struct ipv6_str i2){
294     if(i1.v[0] > i2.v[0])
295         return 1;
296     if(i1.v[0] < i2.v[0])
297         return -1;
298     if(i1.v[1] > i2.v[1])
299         return 1;
300     if(i1.v[1] < i2.v[1])
301         return -1;
302     if(i1.v[2] > i2.v[2])
303         return 1;
304     if(i1.v[2] < i2.v[2])
305         return -1;
306     if(i1.v[3] > i2.v[3])
307         return 1;
308     if(i1.v[3] < i2.v[3])
309         return -1;
310
311     return 0;
312 }
313
314 gs_retval_t Ipv6_Constructor(struct ipv6_str *s, gs_sp_t l){
315         gs_uint32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0;
316         sscanf(l,"%x:%x:%x:%x:%x:%x:%x:%x",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
317         s->v[0] = ((i0 & 0xffff) << 16) | (i1 & 0xffff);
318         s->v[1] = ((i2 & 0xffff) << 16) | (i3 & 0xffff);
319         s->v[2] = ((i4 & 0xffff) << 16) | (i5 & 0xffff);
320         s->v[3] = ((i6 & 0xffff) << 16) | (i7 & 0xffff);
321     return(0);
322 }
323
324 struct ipv6_str And_Ipv6(const struct ipv6_str i1, const struct ipv6_str i2){
325         struct ipv6_str ret;
326         ret.v[0] = i1.v[0] & i2.v[0];
327         ret.v[1] = i1.v[1] & i2.v[1];
328         ret.v[2] = i1.v[2] & i2.v[2];
329         ret.v[3] = i1.v[3] & i2.v[3];
330         return ret;
331 }
332
333 struct ipv6_str Or_Ipv6(const struct ipv6_str i1, const struct ipv6_str i2){
334         struct ipv6_str ret;
335         ret.v[0] = i1.v[0] | i2.v[0];
336         ret.v[1] = i1.v[1] | i2.v[1];
337         ret.v[2] = i1.v[2] | i2.v[2];
338         ret.v[3] = i1.v[3] | i2.v[3];
339         return ret;
340 }
341 struct ipv6_str hton_ipv6(struct ipv6_str s){
342         struct ipv6_str ret;
343 //        ret.v[0] = htonl(s.v[0]);
344 //        ret.v[1] = htonl(s.v[1]);
345 //        ret.v[2] = htonl(s.v[2]);
346 //        ret.v[3] = htonl(s.v[3]);
347         ret.v[0] = s.v[0];
348         ret.v[1] = s.v[1];
349         ret.v[2] = s.v[2];
350         ret.v[3] = s.v[3];
351         return ret;
352 }
353
354 struct ipv6_str ntoh_ipv6(struct ipv6_str s){
355         struct ipv6_str ret;
356 //        ret.v[0] = ntohl(s.v[0]);
357 //        ret.v[1] = ntohl(s.v[1]);
358 //        ret.v[2] = ntohl(s.v[2]);
359 //        ret.v[3] = ntohl(s.v[3]);
360         ret.v[0] = s.v[0];
361         ret.v[1] = s.v[1];
362         ret.v[2] = s.v[2];
363         ret.v[3] = s.v[3];
364         return ret;
365 }
366
367