PJ_DEF(void) pj_scan_get( pj_scanner *scanner, const pj_cis_t *spec, pj_str_t *out) { register char *s = scanner->curptr; pj_assert(pj_cis_match(spec,0)==0); /* EOF is detected implicitly */ if (!pj_cis_match(spec, *s)) { pj_scan_syntax_err(scanner); return; } do { ++s; } while (pj_cis_match(spec, *s)); /* No need to check EOF here (PJ_SCAN_CHECK_EOF(s)) because * buffer is NULL terminated and pj_cis_match(spec,0) should be * false. */ pj_strset3(out, scanner->curptr, s); scanner->curptr = s; if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { pj_scan_skip_whitespace(scanner); } }
PJ_DEF(void) pj_scan_get_unescape( pj_scanner *scanner, const pj_cis_t *spec, pj_str_t *out) { register char *s = scanner->curptr; char *dst = s; pj_assert(pj_cis_match(spec,0)==0); /* Must not match character '%' */ pj_assert(pj_cis_match(spec,'%')==0); /* EOF is detected implicitly */ if (!pj_cis_match(spec, *s) && *s != '%') { pj_scan_syntax_err(scanner); return; } out->ptr = s; do { if (*s == '%') { if (s+3 <= scanner->end && pj_isxdigit(*(s+1)) && pj_isxdigit(*(s+2))) { *dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(s+1)) << 4) + pj_hex_digit_to_val(*(s+2))); ++dst; s += 3; } else { *dst++ = *s++; *dst++ = *s++; break; } } if (pj_cis_match(spec, *s)) { char *start = s; do { ++s; } while (pj_cis_match(spec, *s)); if (dst != start) pj_memmove(dst, start, s-start); dst += (s-start); } } while (*s == '%'); scanner->curptr = s; out->slen = (dst - out->ptr); if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { pj_scan_skip_whitespace(scanner); } }
PJ_DEF(pj_ssize_t) pj_strncpy2_escape( char *dst_str, const pj_str_t *src_str, pj_ssize_t max, const pj_cis_t *unres) { const char *src = src_str->ptr; const char *src_end = src + src_str->slen; char *dst = dst_str; char *dst_end = dst + max; if (max < src_str->slen) return -1; while (src != src_end && dst != dst_end) { if (pj_cis_match(unres, *src)) { *dst++ = *src++; } else { if (dst < dst_end-2) { *dst++ = '%'; pj_val_to_hex_digit(*src, dst); dst+=2; ++src; } else { break; } } } return src==src_end ? dst-dst_str : -1; }
/* Compare two numbers, according to RFC 3966: * - both must be either local or global numbers. * - The 'global-number-digits' and the 'local-number-digits' must be * equal, after removing all visual separators. */ PJ_DEF(int) pjsip_tel_nb_cmp(const pj_str_t *number1, const pj_str_t *number2) { const char *s1 = number1->ptr, *e1 = number1->ptr + number1->slen, *s2 = number2->ptr, *e2 = number2->ptr + number2->slen; /* Compare each number, ignoreing visual separators. */ while (s1!=e1 && s2!=e2) { int diff; if (pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s1)) { ++s1; continue; } if (pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s2)) { ++s2; continue; } diff = pj_tolower(*s1) - pj_tolower(*s2); if (!diff) { ++s1, ++s2; continue; } else return diff; } /* Exhaust remaining visual separators. */ while (s1!=e1 && pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s1)) ++s1; while (s2!=e2 && pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s2)) ++s2; if (s1==e1 && s2==e2) return 0; else if (s1==e1) return -1; else return 1; }
PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner, const pj_cis_t *spec, pj_str_t *out) { register char *s = scanner->curptr; if (s >= scanner->end) { pj_scan_syntax_err(scanner); return -1; } while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match( spec, *s)) ++s; pj_strset3(out, scanner->curptr, s); return *s; }
PJ_DEF(int) pj_scan_peek( pj_scanner *scanner, const pj_cis_t *spec, pj_str_t *out) { register char *s = scanner->curptr; if (s >= scanner->end) { pj_scan_syntax_err(scanner); return -1; } /* Don't need to check EOF with PJ_SCAN_CHECK_EOF(s) */ while (pj_cis_match(spec, *s)) ++s; pj_strset3(out, scanner->curptr, s); return *s; }
PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner, const pj_cis_t *spec, pj_str_t *out) { register char *s = scanner->curptr; if (s >= scanner->end) { pj_scan_syntax_err(scanner); return; } while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match(spec, *s)) { ++s; } pj_strset3(out, scanner->curptr, s); scanner->curptr = s; if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { pj_scan_skip_whitespace(scanner); } }
static pj_json_elem* parse_elem_throw(struct parse_state *st, pj_json_elem *elem) { pj_str_t name = {NULL, 0}, value = {NULL, 0}; pj_str_t token; if (!elem) elem = pj_pool_alloc(st->pool, sizeof(*elem)); /* Parse name */ if (*st->scanner.curptr == '"') { pj_scan_get_char(&st->scanner); pj_scan_get_until_ch(&st->scanner, '"', &token); pj_scan_get_char(&st->scanner); if (*st->scanner.curptr == ':') { pj_scan_get_char(&st->scanner); name = token; } else { value = token; } } if (value.slen) { /* Element with string value and no name */ pj_json_elem_string(elem, &name, &value); return elem; } /* Parse value */ if (pj_cis_match(&st->float_spec, *st->scanner.curptr) || *st->scanner.curptr == '-') { float val; pj_bool_t neg = PJ_FALSE; if (*st->scanner.curptr == '-') { pj_scan_get_char(&st->scanner); neg = PJ_TRUE; } pj_scan_get(&st->scanner, &st->float_spec, &token); val = pj_strtof(&token); if (neg) val = -val; pj_json_elem_number(elem, &name, val); } else if (*st->scanner.curptr == '"') { unsigned err; char *start = st->scanner.curptr; err = parse_quoted_string(st, &token); if (err) { st->scanner.curptr = start + err; return NULL; } pj_json_elem_string(elem, &name, &token); } else if (pj_isalpha(*st->scanner.curptr)) { if (pj_scan_strcmp(&st->scanner, "false", 5)==0) { pj_json_elem_bool(elem, &name, PJ_FALSE); pj_scan_advance_n(&st->scanner, 5, PJ_TRUE); } else if (pj_scan_strcmp(&st->scanner, "true", 4)==0) { pj_json_elem_bool(elem, &name, PJ_TRUE); pj_scan_advance_n(&st->scanner, 4, PJ_TRUE); } else if (pj_scan_strcmp(&st->scanner, "null", 4)==0) { pj_json_elem_null(elem, &name); pj_scan_advance_n(&st->scanner, 4, PJ_TRUE); } else { return NULL; } } else if (*st->scanner.curptr == '[') { pj_json_elem_array(elem, &name); if (parse_children(st, elem) != PJ_SUCCESS) return NULL; } else if (*st->scanner.curptr == '{') { pj_json_elem_obj(elem, &name); if (parse_children(st, elem) != PJ_SUCCESS) return NULL; } else { return NULL; } return elem; }
bool match(int c) const { return pj_cis_match(&cis_, c) != 0; }