| // 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" |
| |
| 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; |
| } |