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(void) pj_scan_advance_n( pj_scanner *scanner, unsigned N, pj_bool_t skip_ws) { if (scanner->curptr + N > scanner->end) { pj_scan_syntax_err(scanner); return; } scanner->curptr += N; if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) { pj_scan_skip_whitespace(scanner); } }
PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner ) { int chr = *scanner->curptr; if (!chr) { pj_scan_syntax_err(scanner); return 0; } ++scanner->curptr; if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) { pj_scan_skip_whitespace(scanner); } return chr; }
PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner, unsigned N, pj_str_t *out) { if (scanner->curptr + N > scanner->end) { pj_scan_syntax_err(scanner); return; } pj_strset(out, scanner->curptr, N); scanner->curptr += N; if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) { pj_scan_skip_whitespace(scanner); } }
PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner, int until_char, 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) && *s != until_char) { ++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); } }
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); } }
PJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner, const char *until_spec, pj_str_t *out) { register char *s = scanner->curptr; pj_size_t speclen; if (s >= scanner->end) { pj_scan_syntax_err(scanner); return; } speclen = strlen(until_spec); while (PJ_SCAN_CHECK_EOF(s) && !memchr(until_spec, *s, speclen)) { ++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); } }
PJ_DEF(void) pj_scan_get_quotes(pj_scanner *scanner, const char *begin_quote, const char *end_quote, int qsize, pj_str_t *out) { register char *s = scanner->curptr; int qpair = -1; int i; pj_assert(qsize > 0); /* Check and eat the begin_quote. */ for (i = 0; i < qsize; ++i) { if (*s == begin_quote[i]) { qpair = i; break; } } if (qpair == -1) { pj_scan_syntax_err(scanner); return; } ++s; /* Loop until end_quote is found. */ do { /* loop until end_quote is found. */ while (PJ_SCAN_CHECK_EOF(s) && *s != '\n' && *s != end_quote[qpair]) { ++s; } /* check that no backslash character precedes the end_quote. */ if (*s == end_quote[qpair]) { if (*(s-1) == '\\') { char *q = s-2; char *r = s-2; while (r != scanner->begin && *r == '\\') { --r; } /* break from main loop if we have odd number of backslashes */ if (((unsigned)(q-r) & 0x01) == 1) { break; } ++s; } else { /* end_quote is not preceeded by backslash. break now. */ break; } } else { /* loop ended by non-end_quote character. break now. */ break; } } while (1); /* Check and eat the end quote. */ if (*s != end_quote[qpair]) { pj_scan_syntax_err(scanner); return; } ++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); } }