static void rtsp_decode_header (const char *line, rtsp_resp_t *response, rtsp_client_t* client) { int i; const char *after; i = 0; while (header_types[i].val != 0) { if (strncasecmp(line, header_types[i].val, header_types[i].val_length) == 0) { after = line + header_types[i].val_length; SKIP_SPACE(after); if (*after == ':') { after++; SKIP_SPACE(after); (header_types[i].parse_routine)(after, response,client); return; } } i++; } RTSP_ALERT("%s [not processing]\n", line); }
static int /* 0 | ply depth of pv ending with '#' */ epd_pv_plies( EpdJob* ejp ) { register char* p; register char* q; int plies; plies = 0; q = 0; p = epd_find_op_opnds(ejp, "pv"); if( p ) { SKIP_SPACE(p); while( *p ) { plies += 1; while( *p && !IS_SPACE(*p) ) { q = p; ++p; } SKIP_SPACE(p); } if( !q || (q[0] != '#') ) { /* no mate indicator at end ... */ plies = 0; /* ... so we know nothing */ } } return plies; }
/* * Internal buffer looks like this. * num[0] op[0] num[1] op[1] num[2] * If priority of op[0] is higher than op[1], (num[0] op[0] num[1]) is computed, * otherwise (num[1] op[1] num[2]) is computed. * Then, the next op and num is read from the script. * Num is an immediate value, a variable or a bracketed expression. */ void ScriptHandler::readNextOp(const char** buf, int* op, int* num) { bool minus_flag = false; SKIP_SPACE(*buf); const char* buf_start = *buf; if (op) { if ((*buf)[0] == '+') *op = OP_PLUS; else if ((*buf)[0] == '-') *op = OP_MINUS; else if ((*buf)[0] == '*') *op = OP_MULT; else if ((*buf)[0] == '/') *op = OP_DIV; else if ((*buf)[0] == 'm' && (*buf)[1] == 'o' && (*buf)[2] == 'd' && ((*buf)[3] == ' ' || (*buf)[3] == '\t' || (*buf)[3] == '$' || (*buf)[3] == '%' || (*buf)[3] == '?' || ((*buf)[3] >= '0' && (*buf)[3] <= '9'))) *op = OP_MOD; else { *op = OP_INVALID; return; } if (*op == OP_MOD) *buf += 3; else (*buf)++; SKIP_SPACE(*buf); } else { if ((*buf)[0] == '-') { minus_flag = true; (*buf)++; SKIP_SPACE(*buf); } } if ((*buf)[0] == '(') { (*buf)++; *num = parseIntExpression(buf); if (minus_flag) *num = -*num; SKIP_SPACE(*buf); if ((*buf)[0] != ')') errorAndExit(") is not found."); (*buf)++; } else { *num = parseInt(buf); if (minus_flag) *num = -*num; if (current_variable.type == VAR_NONE) { if (op) *op = OP_INVALID; *buf = buf_start; } } }
static void ImportLoadFile (void) { char *filename = NULL; char space[] = " \t\n"; char *IncPath[] = { ".", #define INC_PATH(path) path, #include "confg/inc_path.h" #undef INC_PATH NULL }; SKIP_SPACE (space); filename = CURRENT; while (';' != *CURRENT && END_OF_FILE != *CURRENT) CURRENT++; filename = InternStr (filename, (char*)CURRENT - filename); if (';' != *CURRENT) { Error (&TokenCoord, "Expect ;"); } else CURRENT++; /* 读到下一个不为空的字符 */ SKIP_SPACE (space); FindAndLoadFile (filename, IncPath); }
const char* ScriptHandler::checkComma(const char* buf) { SKIP_SPACE(buf); if (*buf == ',') { end_status |= END_COMMA; buf++; SKIP_SPACE(buf); } return buf; }
static void get_command(char *line, char *com, char *arg1, char *arg2) { char *s; *com = *arg1 = *arg2 = '\0'; SKIP_SPACE(); GET_ARG(com); SKIP_SPACE(); GET_ARG(arg1); SKIP_SPACE(); GET_ARG(arg2); }
static char *xml_meta_attr_value(ACL_XML3_ATTR *attr, char *data) { ACL_XML3 *xml = attr->node->xml; int ch; SKIP_SPACE(data); if (IS_QUOTE(*data)) attr->quote = *data++; if (*data == 0) return data; if (attr->value == xml->addr) attr->value = data; while ((ch = *data) != 0) { if (attr->quote && ch == attr->quote) { attr->value_size = data - attr->value; *data++ = 0; break; } else if (IS_SPACE(ch)) { attr->value_size = data - attr->value; *data++ = 0; break; } data++; } return data; }
static const char *xml_parse_left_tag(ACL_XML *xml, const char *data) { int ch; if (LEN(xml->curr_node->ltag) == 0) { SKIP_SPACE(data); } while ((ch = *data) != 0) { data++; if (ch == '>') { xml->curr_node->status = ACL_XML_S_LGT; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML_F_SELF_CL) && xml->curr_node->last_ch == '/') { acl_vstring_truncate(xml->curr_node->ltag, LEN(xml->curr_node->ltag) - 1); } break; } else if (IS_SPACE(ch)) { xml->curr_node->status = ACL_XML_S_ATTR; xml->curr_node->last_ch = ch; break; } else { ACL_VSTRING_ADDCH(xml->curr_node->ltag, ch); xml->curr_node->last_ch = ch; } } ACL_VSTRING_TERMINATE(xml->curr_node->ltag); return (data); }
static const char *json_element(ACL_JSON *json, const char *data) { /* 创建数组成员对象 */ ACL_JSON_NODE *element; SKIP_SPACE(data); if (*data == 0) return NULL; if (*data == '{') { data++; json->status = ACL_JSON_S_OBJ; return data; } else if (*data == '[') { data++; json->status = ACL_JSON_S_ARRAY; return data; } element = acl_json_node_alloc(json); element->type = ACL_JSON_T_ELEMENT; element->depth = json->curr_node->depth + 1; if (element->depth > json->depth) json->depth = element->depth; acl_json_node_add_child(json->curr_node, element); /* 将该数组成员对象置为当前 JSON 分析结点 */ json->curr_node = element; json->status = ACL_JSON_S_VALUE; return data; }
void ScriptHandler::skipToken() { SKIP_SPACE(current_script); const char* buf = current_script; bool quat_flag = false; bool text_flag = false; while (1) { if (*buf == 0x0a || (!quat_flag && !text_flag && (*buf == ':' || *buf == ';'))) break; if (*buf == '"') quat_flag = !quat_flag; const char bytes = file_encoding->NextCharSize(buf); // CHECKME: what exactly does this do? if (bytes > 1 && !quat_flag) text_flag = true; buf += bytes; } if (text_flag && *buf == 0x0a) ++buf; next_script = buf; }
static const char *json_obj(ACL_JSON *json, const char *data) { ACL_JSON_NODE *obj; SKIP_SPACE(data); if (*data == 0) return NULL; /* 创建对象 '{}' 子结点 */ obj = acl_json_node_alloc(json); obj->type = ACL_JSON_T_OBJ; obj->depth = json->curr_node->depth + 1; if (obj->depth > json->depth) json->depth = obj->depth; /* 根据 json 结点对象前缀的不同,记录不同的对象后缀 */ obj->left_ch = '{'; obj->right_ch = '}'; acl_json_node_add_child(json->curr_node, obj); if (LEN(json->curr_node->ltag) > 0) json->curr_node->tag_node = obj; json->curr_node = obj; json->status = ACL_JSON_S_MEMBER; return data; }
static const char *json_strend(ACL_JSON *json, const char *data) { ACL_JSON_NODE *parent; SKIP_SPACE(data); if (*data == 0) return NULL; if (*data == ',' || *data == ';') { json->status = ACL_JSON_S_NEXT; return data; } parent = acl_json_node_parent(json->curr_node); if (*data != parent->right_ch) { /* xxx */ data++; return data; } if (parent == json->root) { json->finish = 1; return NULL; } data++; json->curr_node = parent; json->status = ACL_JSON_S_NEXT; return data; }
static void xml_meta_attr(ACL_XML2_NODE *node) { ACL_XML2_ATTR *attr; char *ptr; int ch; if (node->text == node->xml->addr || *node->text == 0) return; ptr = node->text; SKIP_SPACE(ptr); if (*ptr == 0) return; while ((ch = *ptr) != 0) { attr = acl_xml2_attr_alloc(node); ptr = xml_meta_attr_name(attr, ptr); if (*ptr == 0) break; ptr = xml_meta_attr_value(attr, ptr); if (*ptr == 0) break; } node->text = node->xml->addr; node->text_size = 0; }
static const char *json_value(ACL_JSON *json, const char *data) { SKIP_SPACE(data); if (*data == 0) return NULL; /* 为 '{' 或 '[' 时说明遇到了当前结点的子结点 */ if (*data == '{') { data++; json->status = ACL_JSON_S_OBJ; } else if (*data == '[') { data++; json->status = ACL_JSON_S_ARRAY; } /* 兼容一下有些数据格式为 "xxx: ," 的方式 */ else if (*data == ',' || *data == ';') { data++; /* 切换至查询该结点的兄弟结点的过程 */ json->status = ACL_JSON_S_NEXT; } /* 说明标签名后面的标签值为字符串或数字 */ /* 如果标签值前有引号,记录下该引号 */ else if (IS_QUOTE(*data)) { /* && json->curr_node->quote == 0) { */ json->curr_node->quote = *data++; json->status = ACL_JSON_S_STRING; } else json->status = ACL_JSON_S_STRING; json->curr_node->type = ACL_JSON_T_LEAF; return data; }
static const char *json_array(ACL_JSON *json, const char *data) { ACL_JSON_NODE *array; SKIP_SPACE(data); if (*data == 0) return NULL; /* 创建数组对象 */ array = acl_json_node_alloc(json); array->left_ch = '['; array->right_ch = ']'; array->type = ACL_JSON_T_ARRAY; array->depth = json->curr_node->depth + 1; if (array->depth > json->depth) json->depth = array->depth; acl_json_node_add_child(json->curr_node, array); if (LEN(json->curr_node->ltag) > 0) json->curr_node->tag_node = array; json->curr_node = array; json->status = ACL_JSON_S_ELEMENT; return data; }
int ScriptHandler::parseIntExpression(const char** buf) { int num[3], op[2]; // internal buffer SKIP_SPACE(*buf); readNextOp(buf, NULL, &num[0]); readNextOp(buf, &op[0], &num[1]); if (op[0] == OP_INVALID) return num[0]; while (1) { readNextOp(buf, &op[1], &num[2]); if (op[1] == OP_INVALID) break; if (!(op[0] & 0x04) && (op[1] & 0x04)) { // if priority of op[1] is higher than op[0] num[1] = calcArithmetic(num[1], op[1], num[2]); } else { num[0] = calcArithmetic(num[0], op[0], num[1]); op[0] = op[1]; num[1] = num[2]; } } return calcArithmetic(num[0], op[0], num[1]); }
const char *ScriptHandler::readStr() { end_status = END_NONE; current_variable.type = VAR_NONE; current_script = next_script; SKIP_SPACE( current_script ); char *buf = current_script; string_buffer[0] = '\0'; string_counter = 0; while(1){ parseStr(&buf); buf = checkComma(buf); string_counter += strlen(str_string_buffer); if (string_counter+1 >= STRING_BUFFER_LENGTH) errorAndExit("readStr: string length exceeds 2048 bytes."); strcat(string_buffer, str_string_buffer); if (buf[0] != '+') break; buf++; } next_script = buf; return string_buffer; }
static char *xml_parse_text(ACL_XML3 *xml, char *data) { int ch; if (xml->curr_node->text == xml->addr) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->text == xml->addr) xml->curr_node->text = data; while ((ch = *data) != 0) { if (ch == '<') { xml->curr_node->text_size = data - xml->curr_node->text; xml->curr_node->status = ACL_XML3_S_RLT; *data++ = 0; /* 此处可对文本内容进行 xml 解码 */ break; } data++; } return data; }
static char *xml_meta_attr_name(ACL_XML2_ATTR *attr, char *data) { int ch; ACL_XML2 *xml = attr->node->xml; SKIP_SPACE(data); if (*data == 0) return data; if (attr->name == xml->addr) attr->name = data; while ((ch = *data) != 0) { if (ch == '=') { if (attr->name_size == 0) attr->name_size = data - attr->name; *data++ = 0; break; } if (IS_SPACE(ch)) { attr->name_size = data - attr->name; *data++ = 0; } else data++; } return data; }
static const char *xml_parse_left_tag(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->ltag == xml->dummy) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->ltag == xml->dummy) xml->curr_node->ltag = END(xml); while ((ch = *data) != 0) { if (ch == '>') { if (NO_SPACE(xml)) return data; xml->curr_node->ltag_size = END(xml) - xml->curr_node->ltag; ADD(xml, '\0'); data++; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { if (xml->curr_node->ltag_size > 0) { size_t n; xml->curr_node->ltag_size--; n = xml->curr_node->ltag_size; xml->curr_node->ltag[n] = 0; } xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; break; } else if (IS_SPACE(ch)) { if (NO_SPACE(xml)) return data; data++; xml->curr_node->ltag_size = END(xml) - xml->curr_node->ltag; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } else { if (NO_SPACE(xml)) return data; data++; ADD(xml, ch); xml->curr_node->last_ch = ch; } } return data; }
static const char *xml_parse_left_tag(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->ltag == xml->addr) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->ltag == xml->addr) xml->curr_node->ltag = xml->ptr; while ((ch = *data) != 0) { if (ch == '>') { if (xml->len < MIN_LEN) return data; data++; xml->len--; xml->curr_node->ltag_size = xml->ptr - xml->curr_node->ltag; *xml->ptr++ = 0; xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { size_t n = xml->curr_node->ltag_size; if (n >= 2) xml->curr_node->ltag[n - 2] = 0; xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; break; } else if (IS_SPACE(ch)) { if (xml->len < MIN_LEN) return data; data++; xml->len--; xml->curr_node->ltag_size = xml->ptr - xml->curr_node->ltag; *xml->ptr++ = 0; xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } else { if (xml->len < MIN_LEN) return data; data++; xml->len--; *xml->ptr++ = ch; xml->curr_node->last_ch = ch; } } return data; }
static void ScanPPEndif (void) { if (endifCnt <= 0) Error (&TokenCoord, "undef use error!"); else endifCnt--; SKIP_SPACE (" \t\n"); }
static char *xml_parse_meta_text(ACL_XML3 *xml, char *data) { int ch; if (xml->curr_node->text == xml->addr) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->text == xml->addr) xml->curr_node->text = data; while ((ch = *data) != 0) { if (xml->curr_node->quote) { if (ch == xml->curr_node->quote) xml->curr_node->quote = 0; } else if (IS_QUOTE(ch)) { if (xml->curr_node->quote == 0) xml->curr_node->quote = ch; } else if (ch == '<') { xml->curr_node->nlt++; } else if (ch != '>') { ; } else if (xml->curr_node->nlt == 0) { char *last; xml->curr_node->text_size = data - xml->curr_node->text; xml->curr_node->status = ACL_XML3_S_MEND; *data++ = 0; if ((xml->curr_node->flag & ACL_XML3_F_META_QM) == 0) break; last = data; while (last > xml->curr_node->text) { if (*last == '?') { xml->curr_node->text_size = last - xml->curr_node->text; *last = 0; break; } last--; } if (last == xml->curr_node->text) break; xml_meta_attr(xml->curr_node); break; } else { xml->curr_node->nlt--; } data++; } return data; }
/* * Read key blob from string buffer (null terminated) and convert it to * binary format. Returns xmallocated blob, and if blob_len, version_major, * version_minor, or is_public have non NULL value the length of blob, * major and minor version numbers of format, and whatever the blob was * private or public key are returned. */ unsigned char *ssh_key_blob_read_from_string(const char *str, size_t *blob_len, char **headers, unsigned int *version_major, unsigned int *version_minor, Boolean *is_public) { unsigned char *blob, *blob2; const char *base64blob, *crc64blob; unsigned int number; size_t base64blob_len, crc64blob_len; const char *p, *compare, *again, *headers_beg, *headers_end; unsigned char *p2; Boolean public; SshUInt32 crc32; if (version_major != NULL) *version_major = 0; if (version_minor != NULL) *version_minor = 0; if (blob_len != NULL) *blob_len = 0; p = str; #define SKIP_SPACE(p) \ do { while (isspace(*(p))) (p)++; } while (0) #define EXPECT_CHAR(p,ch) \ do { if (*(p) != (ch)) goto error; } while (0) #define SKIP_CHARS(p,ch) \ do { while (*(p) == (ch) || isspace(*(p))) (p)++; } while (0) #define MATCH_STRING(p,str) \ do { for(; *(p) && *(str) == tolower(*(p));(str)++) { (p)++; SKIP_SPACE(p);}\ } while (0) #define MATCH_STRING_GOTO_ERROR(p,str) \ do { MATCH_STRING((p),(str)); if (*(str)) goto error; } while (0) #define READ_NUMBER(p,n) \ do { (n) = 0; SKIP_SPACE(p); for(; isdigit(*(p)); ) \ { (n) = ((n) * 10) + (*(p) - '0'); (p)++; SKIP_SPACE(p); } } while (0) SKIP_SPACE(p); /* Read begin line */ EXPECT_CHAR(p, '-'); SKIP_CHARS(p, '-'); compare = "beginssh"; MATCH_STRING_GOTO_ERROR(p, compare); again = p; compare = "public"; MATCH_STRING(p, compare); if (*compare) { p = again; compare = "private"; MATCH_STRING_GOTO_ERROR(p, compare); public = FALSE; }
/* * Performs Solaris dependent mapping. Returns a zone ID if * found. Otherwise, NULL is returned. Solaris libc looks up * "/etc/default/init" to get the default TZ value if TZ is not defined * as an environment variable. */ static char * getPlatformTimeZoneID() { char *tz = NULL; FILE *fp; /* * Try the TZ entry in /etc/default/init. */ if ((fp = fileopen(SYS_INIT_FILE, "r")) != NULL) { char line[256]; char quote = '\0'; while (filegets(line, sizeof(line), fp) != NULL) { char *p = line; char *s; char c; /* quick check for comment lines */ if (*p == '#') { continue; } if (strncmp(p, "TZ=", 3) == 0) { p += 3; SKIP_SPACE(p); c = *p; if (c == '"' || c == '\'') { quote = c; p++; } /* * PSARC/2001/383: quoted string support */ for (s = p; (c = *s) != '\0' && c != '\n'; s++) { /* No '\\' is supported here. */ if (c == quote) { quote = '\0'; break; } if (c == ' ' && quote == '\0') { break; } } if (quote != '\0') { jio_fprintf(stderr, "ZoneInfo: unterminated time zone name in /etc/TIMEZONE\n"); } *s = '\0'; tz = strdup(p); break; } } (void) fileclose(fp); } return tz; }
static const char *xml_parse_next_left_lt(ACL_XML2 *xml, const char *data) { SKIP_SPACE(data); SKIP_WHILE(*data != '<', data); if (*data == 0) return data; data++; xml->curr_node->status = ACL_XML2_S_LLT; return data; }
static char *xml_parse_meta_comment(ACL_XML3 *xml, char *data) { int ch; if (xml->curr_node->text == xml->addr) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->text == xml->addr) xml->curr_node->text = data; while ((ch = *data) != 0) { if (xml->curr_node->quote) { if (ch == xml->curr_node->quote) xml->curr_node->quote = 0; } else if (IS_QUOTE(ch)) { if (xml->curr_node->quote == 0) xml->curr_node->quote = ch; } else if (ch == '<') { xml->curr_node->nlt++; } else if (ch == '>') { if (xml->curr_node->nlt == 0 && xml->curr_node->meta[0] == '-' && xml->curr_node->meta[1] == '-') { xml->curr_node->text_size = data - xml->curr_node->text; xml->curr_node->status = ACL_XML3_S_MEND; *data++ = 0; break; } xml->curr_node->nlt--; } else if (xml->curr_node->nlt > 0) { ; } else if (ch == '-') { if (xml->curr_node->meta[0] != '-') xml->curr_node->meta[0] = '-'; else if (xml->curr_node->meta[1] != '-') xml->curr_node->meta[1] = '-'; } else { if (xml->curr_node->meta[0] == '-') xml->curr_node->meta[0] = 0; if (xml->curr_node->meta[1] == '-') xml->curr_node->meta[1] = 0; } data++; } return data; }
static const char *xml_meta_attr_value(ACL_XML_ATTR *attr, const char *data) { int ch; SKIP_SPACE(data); if (*data == 0) return data; if (IS_QUOTE(*data)) attr->quote = *data++; while ((ch = *data) != 0) { if (attr->backslash) { if (ch == 'b') ADDCH(attr->value, '\b'); else if (ch == 'f') ADDCH(attr->value, '\f'); else if (ch == 'n') ADDCH(attr->value, '\n'); else if (ch == 'r') ADDCH(attr->value, '\r'); else if (ch == 't') ADDCH(attr->value, '\t'); else ADDCH(attr->value, ch); attr->backslash = 0; } else if (ch == '\\') { if (attr->part_word) { ADDCH(attr->value, ch); attr->part_word = 0; } else attr->backslash = 1; } else if (attr->quote) { if (ch == attr->quote) { data++; break; } ADDCH(attr->value, ch); } else if (IS_SPACE(ch)) { data++; break; } else { ADDCH(attr->value, ch); if ((attr->node->xml->flag & ACL_XML_FLAG_PART_WORD)) { if (attr->part_word) attr->part_word = 0; else if (ch < 0) attr->part_word = 1; } } data++; } ACL_VSTRING_TERMINATE(attr->value); return data; }
static const char *xml_parse_text(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->text == xml->dummy) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->text == xml->dummy) xml->curr_node->text = END(xml); while ((ch = *data) != 0) { if (ch == '<') { if (NO_SPACE(xml)) return data; data++; xml->curr_node->text_size = END(xml) - xml->curr_node->text; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_RLT; break; } if (NO_SPACE(xml)) return data; data++; ADD(xml, ch); } if (xml->curr_node->status == ACL_XML2_S_RLT && (xml->flag & ACL_XML2_FLAG_XML_DECODE) && xml->curr_node->text_size > 1 && !NO_SPACE(xml)) { char *txt = xml->curr_node->text; xml->curr_node->text = END(xml); (void) acl_xml_decode(txt, xml->vbuf); xml->curr_node->text_size = END(xml) - xml->curr_node->text; txt = END(xml) - 1; while (txt >= xml->curr_node->text && IS_SPACE(*txt)) { *txt-- = 0; xml->curr_node->text_size--; } ADD(xml, '\0'); } return data; }
static const char *json_brother(ACL_JSON *json, const char *data) { ACL_JSON_NODE *parent; if (json->curr_node == json->root) { json->finish = 1; return NULL; } SKIP_SPACE(data); if (*data == 0) return NULL; /* 如果到达根结点的结束符,则 json 解析过程完毕 */ parent = acl_json_node_parent(json->curr_node); acl_assert(parent); if (*data == ',' || *data == ';') { data++; if (parent->left_ch == '{') json->status = ACL_JSON_S_MEMBER; else if (parent->left_ch == '[') json->status = ACL_JSON_S_ELEMENT; else json->status = ACL_JSON_S_NEXT; json->curr_node = parent; return data; } if (*data == parent->right_ch) { data++; if (parent == json->root) { json->finish = 1; return NULL; } json->curr_node = parent; /* 查询父结点的下一个兄弟结点 */ json->status = ACL_JSON_S_NEXT; return data; } if (parent->left_ch == '{') json->status = ACL_JSON_S_MEMBER; else if (parent->left_ch == '[') json->status = ACL_JSON_S_ELEMENT; else json->status = ACL_JSON_S_NEXT; json->curr_node = parent; return data; }