- 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 (!__atomic_sub_fetch(&ws->refcount, 1, __ATOMIC_RELAXED)) {
+ afb_evt_listener_unref(ws->listener);
+ afb_wsj1_unref(ws->wsj1);
+ if (ws->cleanup != NULL)
+ ws->cleanup(ws->cleanup_closure);
+ afb_session_unref(ws->session);
+ afb_cred_unref(ws->cred);
+ afb_apiset_unref(ws->apiset);
+ free(ws);