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