- char *pos, *end, c;
- int aux;
-
- /* scan */
- pos = text;
- end = text + size;
-
- /* scans: [ */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '[') goto bad_header;
-
- /* scans code: 2|3|4 */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- switch (*pos++) {
- case '2': r->code = CALL; break;
- case '3': r->code = RETOK; break;
- case '4': r->code = RETERR; break;
- default: goto bad_header;
- }
-
- /* scans: , */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != ',') goto bad_header;
-
- /* scans id: "id" */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '"') goto bad_header;
- r->id = pos;
- while(pos < end && *pos != '"') pos++;
- if (pos == end) goto bad_header;
- r->idlen = (size_t)(pos++ - r->id);
-
- /* scans: , */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != ',') goto bad_header;
-
- /* scans the method if needed */
- if (r->code == CALL) {
- /* scans: " */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '"') goto bad_header;
-
- /* scans: api/ */
- r->api = pos;
- while(pos < end && *pos != '"' && *pos != '/') pos++;
- if (pos == end) goto bad_header;
- if (*pos != '/') goto bad_header;
- r->apilen = (size_t)(pos++ - r->api);
- if (r->apilen && r->api[r->apilen - 1] == '\\')
- r->apilen--;
-
- /* scans: verb" */
- r->verb = pos;
- while(pos < end && *pos != '"') pos++;
- if (pos == end) goto bad_header;
- r->verblen = (size_t)(pos++ - r->verb);
-
- /* scans: , */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != ',') goto bad_header;
- }
-
- /* scan obj */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- aux = 0;
- r->obj = pos;
- while (pos < end && (aux != 0 || (*pos != ',' && *pos != ']'))) {
- if (pos == end) goto bad_header;
- switch(*pos) {
- case '{': case '[': aux++; break;
- case '}': case ']': if (!aux--) goto bad_header; break;
- case '"':
- do {
- pos += 1 + (*pos == '\\');
- } while(pos < end && *pos != '"');
- default:
- break;
- }
- pos++;
- }
- if (pos > end) goto bad_header;
- if (pos == end && aux != 0) goto bad_header;
- c = *pos;
- r->objlen = (size_t)(pos++ - r->obj);
- while (r->objlen && r->obj[r->objlen - 1] == ' ')
- r->objlen--;
-
- /* scan the token (if any) */
- if (c == ',') {
- /* scans token: "token" */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '"') goto bad_header;
- r->tok = pos;
- while(pos < end && *pos != '"') pos++;
- if (pos == end) goto bad_header;
- r->toklen = (size_t)(pos++ - r->tok);
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- c = *pos++;