| // Copyright 2011 Google Inc. All Rights Reserved. |
| // Author: qianzhang@google.com (ken Zhang) |
| #define _GNU_SOURCE |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include "channel_buffer.h" |
| |
| #include "utility.h" |
| #define sage_log(x) _sagelog x |
| void _sagelog( int type, int level, const char* cstr, ... ); |
| |
| static const char* delimiter = " \t,;\r\n:=|'\"#"; |
| |
| static int is_delimiter( char ch ) |
| { |
| int i; |
| if ( ch == 0 ) return 1; |
| for ( i = 0; delimiter[i]; i++ ) |
| if ( ch == delimiter[i] ) return 1; |
| return 0; |
| } |
| |
| //format name:zzz (or name=zzzz) |
| int get_string_by_name( char*p, const char* name, char* string, int max_len, char **next ) |
| { |
| char *s, *e; |
| e = p; |
| |
| while ( e != NULL && *e ) { |
| s = strstr( e, name ); |
| if ( s == NULL ) |
| return 0; |
| //is a token name |
| if ( ((s > p && is_delimiter(*(s-1))) || s == p ) && is_delimiter( *(s+strlen(name)) ) ) { |
| s += (int)strlen(name); |
| while( *s && ( *s == ' ' || *s == '\t' ) ) |
| s++; //skip white space |
| if ( *s == '=' || *s == ':' ) { |
| s++; |
| while( *s && ( *s == ' ' || *s == '\t' ) ) |
| s++; //skip white space |
| if ( *s ) { |
| int i=0; |
| while ( i++<max_len && *s && *s != ' ' && *s != '\t' && *s != '\n' && *s != '\r') |
| *string++ = *s++; |
| |
| *string = 0x0; //terminator |
| if ( next != NULL ) { |
| while ( *s && *s != ' ' && *s != '\t' && *s != '\n' && *s != '\r') |
| s++; |
| *next = s; |
| } |
| return 1; |
| } |
| } |
| } |
| e = ++s; |
| } |
| return 0; |
| } |
| |
| //format name:zzz (or name=zzzz) |
| int get_string_by_token( char*p, int num, char* string, int max_len, char **next ) |
| { |
| int count = 0; |
| char *s; |
| s = p; |
| if ( s == NULL ) |
| return 0; |
| while ( *s ) { |
| while( *s && ( *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ) ) |
| s++; //skip white space |
| if ( *s == 0 ) |
| break; |
| |
| if ( count++ != num ) { |
| while( *s && !( *s == ' ' || *s == '\t' || *s == ';' || *s == ',' || *s == '\r' || *s == '\n' ) ) |
| s++; //skip a token |
| } else { |
| if ( *s ) { |
| int i=0; |
| while ( i++<max_len && *s && !( *s == ' ' || *s == '\t' || *s == ';' || *s == ',' || *s == '\r' || *s == '\n' ) ) |
| *string++ = *s++; |
| |
| *string = 0x0; //terminator |
| if ( next != NULL ) { |
| while ( *s && !( *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ) ) |
| s++; |
| *next = s; |
| } |
| return 1; |
| } |
| } |
| if ( *s ) |
| s++; |
| } |
| return 0; |
| } |
| |
| //format name:"zzz" (or name="zzzz") |
| int get_quote_string_by_name( char*p, const char* name, char* string, int max_len, char **next ) |
| { |
| char *s, *e; |
| e = p; |
| |
| while ( e != NULL && *e ) { |
| s = strstr( e, name ); |
| if ( s == NULL ) return 0; |
| //is a token name |
| if ( ((s > p && is_delimiter(*(s-1))) || s == p ) && is_delimiter( *(s+strlen(name)) ) ) { |
| s += (int)strlen(name); |
| while( *s && ( *s == ' ' || *s == '\t' ) ) |
| s++; //skip white space |
| if ( *s == '=' || *s == ':' ) { |
| s++; |
| while( *s && ( *s == ' ' || *s == '\t' ) ) |
| s++; //skip white space |
| if ( *s == '\"' ) { |
| int i=0; |
| s++; |
| while ( i++<max_len && *s && *s != '\"' ) |
| *string++ = *s++; |
| |
| *string = 0x0; //terminator |
| |
| if ( next != NULL) { |
| while ( *s && *s != '\"' ) |
| s++; |
| *next = s+1; |
| } |
| return 1; |
| } else |
| return 0; |
| } |
| } |
| e = ++s; |
| } |
| return 0; |
| } |
| |
| int get_int_val_by_name( char*p, const char* name, int* val, char** next ) |
| { |
| char *s, *e; |
| e = p; |
| while( e != NULL && *e ) { |
| s = strstr( e, name ); |
| if ( s == NULL ) |
| return 0; |
| //is a token name |
| if ( ( (s > p && is_delimiter(*(s-1)) ) || s == p ) && is_delimiter( *(s+strlen(name)) ) ) { |
| s += strlen(name); |
| while( *s && ( *s == ' ' || *s == '\t' ) ) |
| s++; //skip white space |
| if ( *s == '=' || *s == ':' ) { |
| s++; |
| while( *s && ( *s == ' ' || *s == '\t' ) ) |
| s++; //skip white space |
| if ( *s ) { |
| *val = atoi( s ); |
| if (*val < 0 && *s == '-' ) |
| s++; |
| while( *s >= '0' && *s <= '9') |
| s++; |
| if ( next != NULL ) |
| *next = s; |
| return 1; |
| } |
| } |
| } |
| e = ++s; |
| } |
| return 0; |
| } |
| struct channel_list_t* _create_channel_list( int num ) |
| { |
| if ( num <= 0 ) |
| return NULL; |
| struct channel_list_t *cl = malloc( sizeof( struct channel_list_t)); |
| if ( cl == NULL ) |
| return NULL; |
| cl->num = num; |
| cl->channel_num = 0; |
| cl->ce = malloc( sizeof(struct channel_entry_t)*num ); |
| if ( cl->ce == NULL ) { |
| free( cl ); |
| return NULL; |
| } |
| memset( cl->ce, 0x0, sizeof(struct channel_entry_t)*num ); |
| return cl; |
| } |
| |
| void _release_channel_list( struct channel_list_t *cl ) |
| { |
| if ( cl ) { |
| if ( cl->ce ) |
| free( cl->ce ); |
| free( cl ); |
| } |
| } |
| |
| struct channel_list_t* _joint_channel_list( struct channel_list_t* cl1, struct channel_list_t* cl2 ) |
| { |
| int i, n, channel_num; |
| if ( cl1 == NULL ) |
| return cl2; |
| if ( cl2 == NULL ) |
| return cl1; |
| |
| channel_num = cl1->channel_num + cl2->channel_num; |
| if ( channel_num < cl1->num ) { |
| n = 0; |
| for ( i = cl1->channel_num; i<channel_num; i++ ) |
| cl1->ce[i] = cl2->ce[n++]; |
| cl2->channel_num = channel_num; |
| _release_channel_list( cl2 ); |
| return cl1; |
| } else if ( channel_num < cl2->num ) { |
| n = 0; |
| for ( i = cl2->channel_num; i<channel_num; i++ ) |
| cl2->ce[i] = cl1->ce[n++]; |
| cl2->channel_num = channel_num; |
| _release_channel_list( cl1 ); |
| return cl2; |
| } else { |
| struct channel_list_t* cl = _create_channel_list( channel_num ); |
| for ( i = 0; i<cl1->channel_num; i++ ) |
| cl->ce[i] = cl1->ce[i]; |
| for ( n = 0; n<cl2->channel_num; n++ ) |
| cl->ce[i++] = cl2->ce[n]; |
| _release_channel_list( cl1 ); |
| _release_channel_list( cl2 ); |
| cl->channel_num = channel_num; |
| return cl; |
| } |
| return NULL; |
| } |
| |
| |
| |