void require_string( char* string ) { int c; while (*string) { c = fgetc( edits ); require_char( *string, c ); ++string; } }
int read_edit_spec(void) { // // I wanted to do just // // int count = fscanf( edits, "%d: `%[^`]` -> `%[^`]`\n", &edit_offset, from_string, to_string ); // // but fscanf has some weird prohibition against accepting // zero-length fields :( so we just do it by hand: /// char buf[ 4096 ]; char* p = buf; int i = fgetc( edits ); if (i == EOF) return FALSE; do { *p++ = i; } while (isdigit( i = fgetc( edits ))); *p = '\0'; edit_offset = atoi( buf ); require_char( ':', i ); require_string( " `" ); p = from_string; while (( i = fgetc( edits )) != '`') { require_char(i,i); *p++ = i; } *p = '\0'; require_string( " -> `" ); p = to_string; while (( i = fgetc( edits )) != '`') { require_char(i,i); *p++ = i; } *p = '\0'; require_string( "\n" ); return TRUE; }
Result ws::http_request_parser::consume(char c) { switch(state_) { case METHOD_GET_1: return require_char(c, 'G', METHOD_GET_2); break; case METHOD_GET_2: return require_char(c, 'E', METHOD_GET_3); break; case METHOD_GET_3: return require_char(c, 'T', METHOD_GET_SP); break; case METHOD_GET_SP: return require_char(c, ' ', URI); break; case URI: if (c == ' ') state_ = HTTP_1; else if (!is_ctl(c)) request.uri.push_back(c); else return BAD_REQUEST; return INDETERMINATE; break; case HTTP_1: return require_char(c, 'H', HTTP_2); break; case HTTP_2: return require_char(c, 'T', HTTP_3); break; case HTTP_3: return require_char(c, 'T', HTTP_4); break; case HTTP_4: return require_char(c, 'P', HTTP_SLASH); break; case HTTP_SLASH: return require_char(c, '/', HTTP_VERSION_MAJOR); break; case HTTP_VERSION_MAJOR: return require_char(c, '1', HTTP_VERSION_POINT); break; case HTTP_VERSION_POINT: return require_char(c, '.', HTTP_VERSION_MINOR); break; case HTTP_VERSION_MINOR: return require_char(c, '1', REQUEST_LINE_CR); break; case REQUEST_LINE_CR: return require_char(c, CR, REQUEST_LINE_LF); break; case REQUEST_LINE_LF: return require_char(c, LF, HEADER_START); break; case HEADER_START: if (c == CR) { state_ = FINAL_LF; return INDETERMINATE; } state_ = HEADER_NAME; return process_header_name_char(c); break; case HEADER_NAME: if (c == ':') { state_ = HEADER_VALUE_START; return INDETERMINATE; } return process_header_name_char(c); break; case HEADER_VALUE_START: if (is_lws(c)) return INDETERMINATE; state_ = HEADER_VALUE; return process_header_value_char(c); break; case HEADER_VALUE: if (c == CR) { header_value_complete(); state_ = HEADER_LF; return INDETERMINATE; } return process_header_value_char(c); break; case HEADER_LF: return require_char(c, LF, HEADER_START); break; case FINAL_LF: if (c == LF) { state_ = AFTER_FINAL_LF; return GOOD; } else return BAD_REQUEST; break; case AFTER_FINAL_LF: return BAD_REQUEST; break; } return BAD_REQUEST; }