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
7 http://www.apache.org/licenses/LICENSE-2.0
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 ------------------------------------------- */
16 #include "rts_external.h"
26 gs_retval_t str_assign_with_copy(struct FTA * f, struct gs_string * dest, struct gs_string * src)
28 if ((dest->data = fta_alloc(f,src->length))==0) {
31 dest->length=src->length;
33 memcpy(dest->data,src->data,src->length);
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)
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;
48 memcpy(buf,src->data,src->length);
54 gs_retval_t str_replace( struct FTA * f, struct gs_string * dest, struct gs_string * src )
57 return str_assign_with_copy(f, dest, src);
60 // ---------------------------------------------------
61 /* Searching within a string */
64 gs_retval_t str_exists_substr( struct gs_string * s1, struct gs_string * s2)
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;
75 for (x=0; x<len1 ; x++)
78 for (y=0; y<len2 && st1[x+y]==st2[y];y++);
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;
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;
111 gs_retval_t str_compare( struct gs_string * str1, struct gs_string * str2)
115 len = (str1->length>str2->length)?str2->length:str1->length;
117 if (ret = (str1->data[x]-str2->data[x]))
121 if (str1->length>str2->length) {
124 if (str2->length>str1->length) {
130 gs_retval_t str_equal( struct gs_string * str1, struct gs_string * str2)
134 if (str1->length != str2->length)
137 for(x=0;x<str1->length;x++) {
138 if (str1->data[x]!=str2->data[x]) {
146 ////////////////////////////////////
147 // Substring functions
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;
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){
166 ret->data = l->data; // empty return string
170 if(sep->length > 0){ // get the sep char, ensure the string is nonempty
176 for(c=0;c < l->length && pos>0; ++c){
182 if(pos>0 || c >= l->length-1){ // not enough seps, or final string is empty
186 ret->data = l->data + c;
187 for(; c<l->length && l->data[c] != s; ++c, ++ret->length);
193 // ------------------------------------------------------
195 gs_retval_t str_constructor(struct gs_string *s, gs_csp_t l){
196 s->data = (gs_sp_t)l;
198 while(l[s->length] != '\0') s->length++;
204 gs_param_handle_t register_handle_for_str_regex_match_slot_1(struct FTA * f,
205 struct gs_string* pattern) {
207 if ((reg=(regex_t *) fta_alloc(0,sizeof(regex_t)))==0) {
210 if (regcomp(reg,(gs_sp_t)(pattern->data), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
213 return (gs_param_handle_t) reg;
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);
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);
227 if ((d=(gs_sp_t)fta_alloc(0,str->length+1))==0) return 0;
231 if (str->length==0) return 0;
233 // copy the string and 0 terminate it
234 memcpy((void *)d,(void *) str->data, str->length);
238 res = regexec(reg, d, 0, NULL, 0);
239 return (res==REG_NOMATCH)?0:1;
243 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
244 regex_t * x = (regex_t *) handle;
246 if (x!=0) fta_free(0,(void *)x);
250 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(struct FTA * f,
251 struct gs_string* pattern) {
253 if ((reg=(regex_t *) fta_alloc(0,sizeof(regex_t)))==0) {
256 if (regcomp(reg,(gs_sp_t)(pattern->data), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
259 return (gs_param_handle_t) reg;
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);
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);
276 if ((d=(gs_sp_t)fta_alloc(0,str->length+1))==0) return 0;
280 if (str->length==0) return 0;
282 end=(maxlen>(str->length))?(str->length):maxlen;
284 // copy the string and 0 terminate it
285 memcpy((void *)d,(void *) str->data, end);
288 /* HACK ALERT: commented out regnexec invocations to unbreak the build */
290 res = regexec(reg,d, 0, NULL, 0);
291 return (res==REG_NOMATCH)?0:1;
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;
299 if (x!=0) fta_free(0,(void *)x);
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);
309 while(*offset<str->length) {
310 if ((s[*offset]>='0') && (s[*offset]<='9')) {
312 *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
314 if (v!=0) { // got some valid result
316 } // otherwise skip leading grabage
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;
327 if (nextint(istr,&offset,&r)!=0)
328 return (gs_param_handle_t) r;
329 return (gs_param_handle_t) 0;
331 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
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;
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;
345 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
350 ///////////////////////////////////////////////////
355 gs_retval_t ipv6_compare( struct ipv6_str i1, struct ipv6_str i2){
356 if(i1.v[0] > i2.v[0])
358 if(i1.v[0] < i2.v[0])
360 if(i1.v[1] > i2.v[1])
362 if(i1.v[1] < i2.v[1])
364 if(i1.v[2] > i2.v[2])
366 if(i1.v[2] < i2.v[2])
368 if(i1.v[3] > i2.v[3])
370 if(i1.v[3] < i2.v[3])
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);
386 struct ipv6_str And_Ipv6(const struct ipv6_str i1, const struct ipv6_str i2){
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];
395 struct ipv6_str Or_Ipv6(const struct ipv6_str i1, const struct ipv6_str i2){
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];
403 struct ipv6_str hton_ipv6(struct ipv6_str s){
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]);
416 struct ipv6_str ntoh_ipv6(struct ipv6_str s){
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]);