/// 문자열의 왼쪽 공백 제거 int trimLeft() { if(bufLen == 0) return 0; char* str = buf; size_t n; for(n=0; n<bufLen; ++str, ++n) { if(!IS_WHITE_SPACE(*str)) break; } if(n > 0) { // moveSize + nullChar memmove(buf, &buf[n], (bufLen-n)+1); bufLen -= n; } assert(valid()); return bufLen; }
uint32_t reverse_doc( uint8_t *mem, uint32_t sz ) { uint32_t x, y; uint32_t last_known_pos = -1; for( x = 0; x < sz && !reverse; x ++ ) { for( y = x; y < sz && !IS_WHITE_SPACE(mem[y]); y ++ ); reverse_word( &mem[x], y - x ); x += (y - x); last_known_pos = x; } return last_known_pos; }
/// 문자열 오른쪽 공백 제거 int trimRight() { if(bufLen == 0) return 0; char* str = &buf[bufLen-1]; int n; for(n=bufLen-1; n>=0; --str, --n) { if(!IS_WHITE_SPACE(*str)) break; } n+= 1; buf[n] = '\0'; bufLen = n; assert(valid()); return bufLen; }
/* parseatt : used to parse the argument list * return 0 (false) in case of success and -1 (true) if the end * of the xmlbuffer is reached. */ static int parseatt(struct xmlparser * p) { const char * attname; int attnamelen; const char * attvalue; int attvaluelen; while(p->xml < p->xmlend) { if(*p->xml=='/' || *p->xml=='>') return 0; if( !IS_WHITE_SPACE(*p->xml) ) { char sep; attname = p->xml; attnamelen = 0; while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) { attnamelen++; p->xml++; if(p->xml >= p->xmlend) return -1; } while(*(p->xml++) != '=') { if(p->xml >= p->xmlend) return -1; } while(IS_WHITE_SPACE(*p->xml)) { p->xml++; if(p->xml >= p->xmlend) return -1; } sep = *p->xml; if(sep=='\'' || sep=='\"') { p->xml++; if(p->xml >= p->xmlend) return -1; attvalue = p->xml; attvaluelen = 0; while(*p->xml != sep) { attvaluelen++; p->xml++; if(p->xml >= p->xmlend) return -1; } } else { attvalue = p->xml; attvaluelen = 0; while( !IS_WHITE_SPACE(*p->xml) && *p->xml != '>' && *p->xml != '/') { attvaluelen++; p->xml++; if(p->xml >= p->xmlend) return -1; } } /*printf("%.*s='%.*s'\n", attnamelen, attname, attvaluelen, attvalue);*/ if(p->attfunc) p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); } p->xml++; } return -1; }
/* parseelt parse the xml stream and * call the callback functions when needed... */ static void parseelt(struct xmlparser * p) { int i; const char * elementname; while(p->xml < (p->xmlend - 1)) { if((p->xml)[0]=='<' && (p->xml)[1]!='?') { i = 0; elementname = ++p->xml; while( !IS_WHITE_SPACE(*p->xml) && (*p->xml!='>') && (*p->xml!='/') ) { i++; p->xml++; if (p->xml >= p->xmlend) return; /* to ignore namespace : */ if(*p->xml==':') { i = 0; elementname = ++p->xml; } } if(i>0) { if(p->starteltfunc) p->starteltfunc(p->data, elementname, i); if(parseatt(p)) return; if(*p->xml!='/') { const char * data; i = 0; data = ++p->xml; if (p->xml >= p->xmlend) return; while( IS_WHITE_SPACE(*p->xml) ) { p->xml++; if (p->xml >= p->xmlend) return; } while(*p->xml!='<') { i++; p->xml++; if (p->xml >= p->xmlend) return; } if(i>0 && p->datafunc) p->datafunc(p->data, data, i); } } else if(*p->xml == '/') { i = 0; elementname = ++p->xml; if (p->xml >= p->xmlend) return; while((*p->xml != '>')) { i++; p->xml++; if (p->xml >= p->xmlend) return; } if(p->endeltfunc) p->endeltfunc(p->data, elementname, i); p->xml++; } } else { p->xml++; } } }
http_connection::parse_result http_connection::parse_request_line() { const char* data = _M_in.data(); size_t len = _M_in.count(); while (_M_inp < (off_t) len) { unsigned char c = (unsigned char) data[_M_inp]; switch (_M_substate) { case 0: // Initial state. if ((c >= 'A') && (c <= 'Z')) { _M_token = _M_inp; _M_substate = 2; // Method. } else if (c == '\r') { _M_substate = 1; // '\r' before method. } else if ((!IS_WHITE_SPACE(c)) && (c != '\n')) { _M_method = http_method::UNKNOWN; _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 1: // '\r' before method. if (c == '\n') { _M_substate = 0; // Initial state. } else { _M_method = http_method::UNKNOWN; _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 2: // Method. if (IS_WHITE_SPACE(c)) { if ((_M_method = http_method::get_method(data + _M_token, _M_inp - _M_token)) == http_method::UNKNOWN) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } _M_substate = 3; // Whitespace after method. } else if ((c < 'A') || (c > 'Z')) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 3: // Whitespace after method. if (c > ' ') { _M_uri = _M_inp; _M_urilen = 1; _M_substate = 4; // URI. } else if (!IS_WHITE_SPACE(c)) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 4: // URI. if (c > ' ') { if (++_M_urilen == URI_MAX_LEN) { _M_error = http_error::REQUEST_URI_TOO_LONG; return PARSE_ERROR; } } else if (IS_WHITE_SPACE(c)) { _M_substate = 5; // Whitespace after URI. } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 5: // Whitespace after URI. if ((c == 'H') || (c == 'h')) { _M_substate = 6; // [H]TTP/<major>.<minor> } else if (!IS_WHITE_SPACE(c)) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 6: // [H]TTP/<major>.<minor> if ((c == 'T') || (c == 't')) { _M_substate = 7; // H[T]TP/<major>.<minor> } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 7: // H[T]TP/<major>.<minor> if ((c == 'T') || (c == 't')) { _M_substate = 8; // HT[T]P/<major>.<minor> } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 8: // HT[T]P/<major>.<minor> if ((c == 'P') || (c == 'p')) { _M_substate = 9; // HTT[P]/<major>.<minor> } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 9: // HTT[P]/<major>.<minor> if (c == '/') { _M_substate = 10; // HTTP[/]<major>.<minor> } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 10: // HTTP[/]<major>.<minor> if ((c >= '0') && (c <= '9')) { _M_major_number = c - '0'; if (_M_major_number > 1) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } _M_substate = 11; // HTTP/[<major>].<minor> } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 11: // HTTP/[<major>].<minor> if (c == '.') { _M_substate = 12; // HTTP/<major>[.]<minor> } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 12: // HTTP/<major>[.]<minor> if ((c >= '0') && (c <= '9')) { _M_minor_number = c - '0'; if ((_M_major_number == 1) && (_M_minor_number > 1)) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } _M_substate = 13; // HTTP/<major>.[<minor>] } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 13: // HTTP/<major>.[<minor>] if (c == '\r') { _M_substate = 14; // '\r' at the end of request line. } else if (c == '\n') { _M_inp++; return PARSING_COMPLETED; } else if (!IS_WHITE_SPACE(c)) { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; case 14: // '\r' at the end of request line. if (c == '\n') { _M_inp++; return PARSING_COMPLETED; } else { _M_error = http_error::BAD_REQUEST; return PARSE_ERROR; } break; } if (++_M_inp == REQUEST_LINE_MAX_LEN) { _M_error = http_error::REQUEST_ENTITY_TOO_LARGE; return PARSE_ERROR; } } return PARSING_NOT_COMPLETED; }
proxy_connection::parse_result proxy_connection::parse_status_line(unsigned fd) { const char* data = _M_client->_M_body.data(); size_t len = _M_client->_M_body.count(); while (_M_inp < (off_t) len) { unsigned char c = (unsigned char) data[_M_inp]; switch (_M_substate) { case 0: // Initial state. if ((c == 'H') || (c == 'h')) { _M_substate = 1; // [H]TTP/<major>.<minor> <status-code> break; } else if (!IS_WHITE_SPACE(c)) { return PARSE_ERROR; } break; case 1: // [H]TTP/<major>.<minor> if ((c == 'T') || (c == 't')) { _M_substate = 2; // H[T]TP/<major>.<minor> } else { return PARSE_ERROR; } break; case 2: // H[T]TP/<major>.<minor> if ((c == 'T') || (c == 't')) { _M_substate = 3; // HT[T]P/<major>.<minor> } else { return PARSE_ERROR; } break; case 3: // HT[T]P/<major>.<minor> if ((c == 'P') || (c == 'p')) { _M_substate = 4; // HTT[P]/<major>.<minor> } else { return PARSE_ERROR; } break; case 4: // HTT[P]/<major>.<minor> if (c == '/') { _M_substate = 5; // HTTP[/]<major>.<minor> } else { return PARSE_ERROR; } break; case 5: // HTTP[/]<major>.<minor> if ((c >= '0') && (c <= '9')) { _M_major_number = c - '0'; if (_M_major_number > 1) { return PARSE_ERROR; } _M_substate = 6; // HTTP/[<major>].<minor> } else { return PARSE_ERROR; } break; case 6: // HTTP/[<major>].<minor> if (c == '.') { _M_substate = 7; // HTTP/<major>[.]<minor> } else { return PARSE_ERROR; } break; case 7: // HTTP/<major>[.]<minor> if ((c >= '0') && (c <= '9')) { _M_minor_number = c - '0'; if ((_M_major_number == 1) && (_M_minor_number > 1)) { return PARSE_ERROR; } _M_substate = 8; // HTTP/<major>.[<minor>] } else { return PARSE_ERROR; } break; case 8: // HTTP/<major>.[<minor>] if (!IS_WHITE_SPACE(c)) { return PARSE_ERROR; } _M_substate = 9; // Whitespace after version. break; case 9: // Whitespace after version. if (IS_DIGIT(c)) { _M_status_code = c - '0'; _M_substate = 10; // Status code. } else if (!IS_WHITE_SPACE(c)) { return PARSE_ERROR; } break; case 10: // Status code. if (IS_DIGIT(c)) { _M_status_code = (_M_status_code * 10) + (c - '0'); if (_M_status_code >= 600) { return PARSE_ERROR; } } else if (IS_WHITE_SPACE(c)) { if (_M_status_code < 100) { return PARSE_ERROR; } _M_substate = 11; // Whitespace after status code. } else if (c == '\r') { if (_M_status_code < 100) { return PARSE_ERROR; } _M_substate = 13; // '\r' at the end of status line. } else if (c == '\n') { if (_M_status_code < 100) { return PARSE_ERROR; } _M_inp++; return PARSING_COMPLETED; } break; case 11: // Whitespace after status code. if (c > ' ') { _M_reason_phrase = _M_inp; _M_substate = 12; // Reason phrase. } else if (c == '\r') { _M_substate = 13; // '\r' at the end of status line. } else if (c == '\n') { _M_inp++; return PARSING_COMPLETED; } break; case 12: // Reason phrase. if (IS_WHITE_SPACE(c)) { if (_M_reason_phrase_len == 0) { _M_reason_phrase_len = _M_inp - _M_reason_phrase; } } else if (c > ' ') { _M_reason_phrase_len = 0; } else if (c == '\r') { if (_M_reason_phrase_len == 0) { _M_reason_phrase_len = _M_inp - _M_reason_phrase; } _M_substate = 13; // '\r' at the end of status line. } else if (c == '\n') { if (_M_reason_phrase_len == 0) { _M_reason_phrase_len = _M_inp - _M_reason_phrase; } _M_inp++; return PARSING_COMPLETED; } else if (c < ' ') { return PARSE_ERROR; } break; case 13: // '\r' at the end of status line. if (c == '\n') { _M_inp++; return PARSING_COMPLETED; } else { return PARSE_ERROR; } break; } if (++_M_inp == STATUS_LINE_MAX_LEN) { return PARSE_ERROR; } } return PARSING_NOT_COMPLETED; }
/* parseatt : used to parse the argument list * return 0 (false) in case of success and -1 (true) if the end * of the xmlbuffer is reached. */ int parseatt(struct xmlparser * p) { int rc; const char * ns; unsigned nslen; const char * attname; unsigned attnamelen; const char * attvalue; unsigned attvaluelen; while(p->xml < p->xmlend) { if(*p->xml=='/' || *p->xml=='>') return 0; if( !IS_WHITE_SPACE(*p->xml) ) { char sep; ns = NULL; nslen = 0; attname = p->xml; attnamelen = 0; while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) { if(*p->xml==':') { ns = attname; nslen = attnamelen; attnamelen = 0; attname = ++p->xml; } else { attnamelen++; p->xml++; } MINIXML_ENSURE_MORE; } while(*(p->xml++) != '=') { MINIXML_ENSURE_MORE; } while(IS_WHITE_SPACE(*p->xml)) { p->xml++; MINIXML_ENSURE_MORE; } sep = *p->xml; if(sep=='\'' || sep=='\"') { p->xml++; MINIXML_ENSURE_MORE; attvalue = p->xml; attvaluelen = 0; while(*p->xml != sep) { attvaluelen++; p->xml++; MINIXML_ENSURE_MORE; } } else { attvalue = p->xml; attvaluelen = 0; while( !IS_WHITE_SPACE(*p->xml) && *p->xml != '>' && *p->xml != '/') { attvaluelen++; p->xml++; MINIXML_ENSURE_MORE; } } /*printf("%.*s='%.*s'\n", attnamelen, attname, attvaluelen, attvalue);*/ if(p->attfunc && (rc = p->attfunc( p->data, ns, nslen, attname, attnamelen, attvalue, attvaluelen))) return rc; } p->xml++; } return -1; }
/* parseelt parse the xml stream and * call the callback functions when needed... */ int parseelt(struct xmlparser * p) { int rc; unsigned i, nslen, comment; const char * elementname, * ns; comment = 0; while(p->xml < (p->xmlend - 1)) { if (comment) { if (p->xml < (p->xmlend - 3) && !strncmp("-->", p->xml, 3)) { comment = 0; } else { p->xml ++; continue; } } if((p->xml)[0]=='<' && (p->xml)[1]!='?') { nslen = 0; ns = NULL; i = 0; elementname = ++p->xml; while( !IS_WHITE_SPACE(*p->xml) && (*p->xml!='>') && (*p->xml!='/') ) { i++; p->xml++; if (i == 3 && !strncmp("!--", elementname, 3)) { comment = 1; break; } MINIXML_ENSURE_MORE; /* to ignore namespace : */ if(*p->xml==':') { ns = elementname; nslen = i; i = 0; elementname = ++p->xml; } } if (comment) continue; if(i>0) { if(p->starteltfunc && (rc = p->starteltfunc( p->data, ns, nslen, elementname, i))) return rc; if((rc = parseatt(p))) return rc; if(*p->xml!='/') { const char * data; i = 0; data = ++p->xml; MINIXML_ENSURE_MORE; while( IS_WHITE_SPACE(*p->xml) ) { p->xml++; MINIXML_ENSURE_MORE; } while(*p->xml!='<') { i++; p->xml++; MINIXML_ENSURE_MORE; } if(p->xml<p->xmlend && *(p->xml+1)=='/' && i >= 0 && p->datafunc && (rc = p->datafunc(p->data, data, i))) return rc; } else { if(*(++p->xml) == '>') { if(p->endeltfunc && (rc = p->endeltfunc( p->data, ns, nslen, elementname, i))) return rc; } else { return -1; } } } else if(*p->xml == '/') { i = 0; elementname = ++p->xml; MINIXML_ENSURE_MORE; while((*p->xml != '>')) { i++; p->xml++; MINIXML_ENSURE_MORE; if(*p->xml==':') { ns = elementname; nslen = i; i = 0; elementname = ++p->xml; } } if(p->endeltfunc && (rc = p->endeltfunc( p->data, ns, nslen, elementname, i))) return rc; p->xml++; } } else { p->xml++; } } return 0; }
ContentType * mimeParseContentType(unsigned char *str) { ContentType *contentType; unsigned char *name; unsigned char *p; ContentTypeParameter *parameter; unsigned char *slash; unsigned char *subtype; unsigned char *type; unsigned char *value; if ((!str) || (!*str)) { return NULL; } while (IS_WHITE_SPACE(*str)) { str++; } if (!*str) { return NULL; } slash = (unsigned char *) strchr((char *) str, '/'); if ((!slash) || (slash == str)) { return NULL; } p = slash - 1; while (IS_WHITE_SPACE(*p)) { p--; } p++; type = lowerCase(copySizedString(str, p - str)); p = slash + 1; while (IS_WHITE_SPACE(*p)) { p++; } if (!*p) { free(type); return NULL; } subtype = p; while (IS_NON_WHITE_SPACE(*p) && (*p != ';')) { p++; } subtype = lowerCase(copySizedString(subtype, p - subtype)); contentType = calloc(sizeof(ContentType), 1); if (!contentType) { fprintf(stderr, "cannot calloc ContentType\n"); exit(0); } contentType->type = calloc(strlen((char *) type) + 1 + strlen((char *) subtype) + 1, 1); if (!contentType->type) { fprintf(stderr, "cannot calloc type\n"); exit(0); } strcpy((char *) contentType->type, (char *) type); strcat((char *) contentType->type, "/"); strcat((char *) contentType->type, (char *) subtype); free(type); free(subtype); while (IS_WHITE_SPACE(*p)) { p++; } if (!*p) { return contentType; } if (*p != ';') { fprintf(stderr, "expected semicolon; got '%c'\n", *p); fprintf(stderr, "str: %s\n", str); return contentType; } while (1) { p++; while (IS_WHITE_SPACE(*p)) { p++; } if (!*p) { fprintf(stderr, "expected parameter: %s\n", str); break; } name = p; while (IS_NON_WHITE_SPACE(*p) && (*p != '=')) { p++; } parameter = calloc(sizeof(ContentTypeParameter), 1); if (!parameter) { fprintf(stderr, "cannot calloc parameter\n"); exit(0); } parameter->name = lowerCase(copySizedString(name, p - name)); while (IS_WHITE_SPACE(*p)) { p++; } if (*p != '=') { fprintf(stderr, "expected '=': %s\n", str); return contentType; } p++; while (IS_WHITE_SPACE(*p)) { p++; } if (*p == '"') { p++; value = p; while ((*p) && (*p != '"')) { p++; } if (!*p) { fprintf(stderr, "expected '\"': %s\n", str); return contentType; } parameter->value = copySizedString(value, p - value); p++; } else { value = p; while (IS_NON_WHITE_SPACE(*p) && (*p != ';')) { p++; } parameter->value = copySizedString(value, p - value); } if (contentType->currentParameter) { contentType->currentParameter->next = parameter; } else { contentType->parameters = parameter; } contentType->currentParameter = parameter; while (IS_WHITE_SPACE(*p)) { p++; } if (!*p) { break; } } return contentType; }
bool net::filter::parse(const char* filter) { if (!init()) { return false; } bool tcp = false; bool udp = false; bool src = false; bool dest = false; unsigned first = 0; unsigned last = 0; int state = 0; // Initial state. while (*filter) { switch (state) { case 0: // Initial state. switch (*filter) { case 'i': case 'I': filter++; state = 1; // ICMP. break; case 's': case 'S': tcp = true; udp = true; src = true; dest = false; filter++; state = 4; // "port". break; case 'd': case 'D': tcp = true; udp = true; src = false; dest = true; filter++; state = 4; // "port". break; case 't': case 'T': tcp = true; udp = false; src = false; dest = false; filter++; state = 2; // TCP. break; case 'u': case 'U': tcp = false; udp = true; src = false; dest = false; filter++; state = 3; // UDP. break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': tcp = true; udp = true; src = true; dest = true; first = *filter - '0'; filter++; state = 5; // Port or range of ports. break; case ' ': case '\t': filter++; break; default: return false; } break; case 1: // ICMP. if (((filter[0] != 'c') && (filter[0] != 'C')) || \ ((filter[1] != 'm') && (filter[1] != 'M')) || \ ((filter[2] != 'p') && (filter[2] != 'P'))) { return false; } if ((filter[3]) && (!IS_WHITE_SPACE(filter[3]))) { return false; } _M_icmp = true; filter += 3; state = 0; // Initial state. break; case 2: // TCP. if (((filter[0] != 'c') && (filter[0] != 'C')) || \ ((filter[1] != 'p') && (filter[1] != 'P'))) { return false; } if ((!filter[2]) || (IS_WHITE_SPACE(filter[2]))) { set_tcp_ports(0, USHRT_MAX, true); filter += 2; state = 0; // Initial state. } else if (filter[2] == ':') { if ((filter[3] == 's') || (filter[3] == 'S')) { src = true; filter += 4; state = 4; // "port". } else if ((filter[3] == 'd') || (filter[3] == 'D')) { dest = true; filter += 4; state = 4; // "port". } else if (IS_DIGIT(filter[3])) { src = true; dest = true; first = filter[3] - '0'; filter += 4; state = 5; // Port or range of ports. } else { return false; } } else { return false; } break; case 3: // UDP. if (((filter[0] != 'd') && (filter[0] != 'D')) || \ ((filter[1] != 'p') && (filter[1] != 'P'))) { return false; } if ((!filter[2]) || (IS_WHITE_SPACE(filter[2]))) { set_udp_ports(0, USHRT_MAX, true); filter += 2; state = 0; // Initial state. } else if (filter[2] == ':') { if ((filter[3] == 's') || (filter[3] == 'S')) { src = true; filter += 4; state = 4; // "port". } else if ((filter[3] == 'd') || (filter[3] == 'D')) { dest = true; filter += 4; state = 4; // "port". } else if (IS_DIGIT(filter[3])) { src = true; dest = true; first = filter[3] - '0'; filter += 4; state = 5; // Port or range of ports. } else { return false; } } else { return false; } break; case 4: // "port". if (((filter[0] != 'p') && (filter[0] != 'P')) || \ ((filter[1] != 'o') && (filter[1] != 'O')) || \ ((filter[2] != 'r') && (filter[2] != 'R')) || \ ((filter[3] != 't') && (filter[3] != 'T')) || \ (filter[4] != ':') || \ (!IS_DIGIT(filter[5]))) { return false; } first = filter[5] - '0'; filter += 6; state = 5; // Port or range of ports. break; case 5: // Port or range of ports. while (IS_DIGIT(*filter)) { if ((first = (first * 10) + (*filter - '0')) > USHRT_MAX) { return false; } filter++; } if (first == 0) { return false; } if (*filter == '-') { last = 0; filter++; state = 6; // Range of ports. } else if ((!*filter) || (IS_WHITE_SPACE(*filter))) { install_filter(tcp, udp, src, dest, first, first, true); state = 0; // Initial state. } else { return false; } break; case 6: // Range of ports. while (IS_DIGIT(*filter)) { if ((last = (last * 10) + (*filter - '0')) > USHRT_MAX) { return false; } filter++; } if (last == 0) { return false; } if ((*filter) && (!IS_WHITE_SPACE(*filter))) { return false; } if (first > last) { return false; } install_filter(tcp, udp, src, dest, first, last, true); state = 0; // Initial state. break; } } if (state != 0) { return false; } _M_filter = true; return true; }
bool range_parser::parse(const char* string, size_t len, off_t filesize, range_list& ranges) { const char* end = string + len; int state = 0; // Initial state. off_t from = 0; off_t to = 0; off_t count = 0; while (string < end) { unsigned char c = (unsigned char) *string++; switch (state) { case 0: // Initial state. if (IS_DIGIT(c)) { from = c - '0'; state = 1; // From. } else if (c == '-') { state = 7; // Start of suffix length. } else if (!IS_WHITE_SPACE(c)) { return false; } break; case 1: // From. if (IS_DIGIT(c)) { off_t n = (from * 10) + (c - '0'); if ((n < from) || (n >= filesize)) { return false; } from = n; } else if (c == '-') { state = 3; // After '-'. } else if (IS_WHITE_SPACE(c)) { state = 2; // Whitespace after from. } else { return false; } break; case 2: // Whitespace after from. if (c == '-') { state = 3; // After '-'. } else if (!IS_WHITE_SPACE(c)) { return false; } break; case 3: // After '-'. if (IS_DIGIT(c)) { to = c - '0'; state = 4; // To. } else if (c == ',') { if (!ranges.add(from, filesize - 1)) { return false; } state = 6; // A new range starts. } else if (!IS_WHITE_SPACE(c)) { return false; } break; case 4: // To. if (IS_DIGIT(c)) { off_t n = (to * 10) + (c - '0'); // Overflow? if (n < to) { return false; } to = n; } else if (c == ',') { to = MIN(to, filesize - 1); if (!ranges.add(from, to)) { return false; } state = 6; // A new range starts. } else if (IS_WHITE_SPACE(c)) { state = 5; // Whitespace after to. } else { return false; } break; case 5: // Whitespace after to. if (c == ',') { to = MIN(to, filesize - 1); if (!ranges.add(from, to)) { return false; } state = 6; // A new range starts. } else if (!IS_WHITE_SPACE(c)) { return false; } break; case 6: // A new range starts. if (IS_DIGIT(c)) { from = c - '0'; state = 1; // From. } else if (c == '-') { state = 7; // Start of suffix length. } else if (!IS_WHITE_SPACE(c)) { return false; } break; case 7: // Start of suffix length. if (IS_DIGIT(c)) { count = c - '0'; state = 8; // Suffix length. } else if (!IS_WHITE_SPACE(c)) { return false; } break; case 8: // Suffix length. if (IS_DIGIT(c)) { off_t n = (count * 10) + (c - '0'); // Overflow? if (n < count) { return false; } count = n; } else if (c == ',') { if (count == 0) { return false; } count = MIN(count, filesize); if (!ranges.add(filesize - count, filesize - 1)) { return false; } state = 6; // A new range starts. } else if (IS_WHITE_SPACE(c)) { state = 9; // Whitespace after suffix length. } else { return false; } break; case 9: // Whitespace after suffix length. if (c == ',') { if (count == 0) { return false; } count = MIN(count, filesize); if (!ranges.add(filesize - count, filesize - 1)) { return false; } state = 6; // A new range starts. } else if (!IS_WHITE_SPACE(c)) { return false; } break; } } switch (state) { case 0: return true; case 3: return ranges.add(from, filesize - 1); case 4: case 5: to = MIN(to, filesize - 1); return ranges.add(from, to); case 8: case 9: if (count == 0) { return false; } count = MIN(count, filesize); return ranges.add(filesize - count, filesize - 1); default: return false; } }
net::internet::http::analyzer::parse_result net::internet::http::analyzer::parse_status_line(connection* conn) { const char* data = conn->in->data(); size_t len = conn->in->count(); unsigned short offset = conn->protocol.http.offset; while (offset < len) { unsigned char c = (unsigned char) data[offset]; switch (conn->protocol.http.substate) { case 0: // Initial state. if ((c == 'H') || (c == 'h')) { conn->protocol.http.substate = 1; // [H]TTP/<major>.<minor> } else if (!IS_WHITE_SPACE(c)) { return kParseError; } break; case 1: // [H]TTP/<major>.<minor> if ((c == 'T') || (c == 't')) { conn->protocol.http.substate = 2; // H[T]TP/<major>.<minor> } else { return kParseError; } break; case 2: // H[T]TP/<major>.<minor> if ((c == 'T') || (c == 't')) { conn->protocol.http.substate = 3; // HT[T]P/<major>.<minor> } else { return kParseError; } break; case 3: // HT[T]P/<major>.<minor> if ((c == 'P') || (c == 'p')) { conn->protocol.http.substate = 4; // HTT[P]/<major>.<minor> } else { return kParseError; } break; case 4: // HTT[P]/<major>.<minor> if (c == '/') { conn->protocol.http.substate = 5; // HTTP[/]<major>.<minor> } else { return kParseError; } break; case 5: // HTTP[/]<major>.<minor> if ((c >= '0') && (c <= '9')) { conn->protocol.http.major_number = c - '0'; if (conn->protocol.http.major_number > 1) { return kParseError; } conn->protocol.http.substate = 6; // HTTP/[<major>].<minor> } else { return kParseError; } break; case 6: // HTTP/[<major>].<minor> if (c == '.') { conn->protocol.http.substate = 7; // HTTP/<major>[.]<minor> } else { return kParseError; } break; case 7: // HTTP/<major>[.]<minor> if ((c >= '0') && (c <= '9')) { conn->protocol.http.minor_number = c - '0'; if ((conn->protocol.http.major_number == 1) && (conn->protocol.http.minor_number > 1)) { return kParseError; } conn->protocol.http.substate = 8; // HTTP/<major>.[<minor>] } else { return kParseError; } break; case 8: // HTTP/<major>.[<minor>] if (IS_WHITE_SPACE(c)) { conn->protocol.http.substate = 9; // Whitespace after HTTP-Version. } else { return kParseError; } break; case 9: // Whitespace after HTTP-Version. if ((c >= '0') && (c <= '9')) { conn->protocol.http.status_code = c - '0'; conn->protocol.http.substate = 10; // Status-Code. } else if (!IS_WHITE_SPACE(c)) { return kParseError; } break; case 10: // Status-Code. if ((c >= '0') && (c <= '9')) { conn->protocol.http.status_code = (conn->protocol.http.status_code * 10) + (c - '0'); if (conn->protocol.http.status_code > 999) { return kParseError; } } else if (IS_WHITE_SPACE(c)) { conn->protocol.http.substate = 11; // Whitespace after Status-Code. } else if (c == '\r') { conn->protocol.http.substate = 12; // '\r' at the end of status line. } else if (c == '\n') { conn->protocol.http.offset = ++offset; return kParsingCompleted; } else { return kParseError; } break; case 11: // Whitespace after Status-Code. if (c == '\r') { conn->protocol.http.substate = 12; // '\r' at the end of status line. } else if (c == '\n') { conn->protocol.http.offset = ++offset; return kParsingCompleted; } else if (c < ' ') { return kParseError; } break; case 12: // '\r' at the end of status line. if (c == '\n') { conn->protocol.http.offset = ++offset; return kParsingCompleted; } else { return kParseError; } break; } if (++offset == kStatusLineMaxLen) { return kParseError; } } conn->protocol.http.offset = offset; return kParsingNotCompleted; }
/* parseelt parse the xml stream and * call the callback functions when needed... */ static void parseelt(struct xmlparser * p) { int i; const char * elementname; while(p->xml < (p->xmlend - 1)) { if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4))) { p->xml += 3; /* ignore comments */ do { p->xml++; if ((p->xml + 3) >= p->xmlend) return; } while(memcmp(p->xml, "-->", 3) != 0); p->xml += 3; } else if((p->xml)[0]=='<' && (p->xml)[1]!='?') { i = 0; elementname = ++p->xml; while( !IS_WHITE_SPACE(*p->xml) && (*p->xml!='>') && (*p->xml!='/') ) { i++; p->xml++; if (p->xml >= p->xmlend) return; /* to ignore namespace : */ if(*p->xml==':') { i = 0; elementname = ++p->xml; } } if(i>0) { if(p->starteltfunc) p->starteltfunc(p->data, elementname, i); if(parseatt(p)) return; if(*p->xml!='/') { const char * data; i = 0; data = ++p->xml; if (p->xml >= p->xmlend) return; while( IS_WHITE_SPACE(*p->xml) ) { i++; p->xml++; if (p->xml >= p->xmlend) return; } if(memcmp(p->xml, "<![CDATA[", 9) == 0) { /* CDATA handling */ p->xml += 9; data = p->xml; i = 0; while(memcmp(p->xml, "]]>", 3) != 0) { i++; p->xml++; if ((p->xml + 3) >= p->xmlend) return; } if(i>0 && p->datafunc) p->datafunc(p->data, data, i); while(*p->xml!='<') { p->xml++; if (p->xml >= p->xmlend) return; } } else { while(*p->xml!='<') { i++; p->xml++; if ((p->xml + 1) >= p->xmlend) return; } if(i>0 && p->datafunc && *(p->xml + 1) == '/') p->datafunc(p->data, data, i); } } } else if(*p->xml == '/') { i = 0; elementname = ++p->xml; if (p->xml >= p->xmlend) return; while((*p->xml != '>')) { i++; p->xml++; if (p->xml >= p->xmlend) return; } if(p->endeltfunc) p->endeltfunc(p->data, elementname, i); p->xml++; } } else { p->xml++; } } }
static void InsertUBO_STD140_LayoutControl(std::string &inout){ enum State { LINE_START, PREPROCESSOR_START, IGNORE_LINE }; //insert "layout(std140) uniform;" to the source code, but only after every #extension lines since these lines must appear before any none preprocessor lines size_t line = 1; size_t insert_pos = 0; size_t line_insert = 1; State state = LINE_START; for (size_t i = 0; i < inout.size(); ++i) { char c = inout[i]; if (c == '\n') { line ++; state = LINE_START; } else { switch (state) { case LINE_START: if (c == '#') state = PREPROCESSOR_START; else if (!IS_WHITE_SPACE(c))//not white space state = IGNORE_LINE; break; case PREPROCESSOR_START: if (c == 'e')//may be "extension" { if (inout.compare(i, 9, "extension") == 0 && i + 9 < inout.size() && IS_WHITE_SPACE(inout[i + 9])) { //found #extension insert_pos = inout.find("\n", i + 9) + 1; i = insert_pos - 1; line ++; line_insert = line; state = LINE_START; } } else if (!IS_WHITE_SPACE(c))//not white space { state = IGNORE_LINE; } break; }//switch (state) }//else of if (c == '\n') }//for (size_t i = 0; i < inout.size(); ++i) if (insert_pos < inout.size()) { char statement_to_insert[] = "layout(std140) uniform;\n#line 9999999999\n"; sprintf(statement_to_insert, "layout(std140) uniform;\n#line %u\n", (hquint32)line_insert - 1); inout.insert(insert_pos, statement_to_insert); } }
/* parseatt : used to parse the argument list * return 0 (false) in case of success and -1 (true) if the end * of the xmlbuffer is reached. * At the moment, nothing is done with the attributes found */ int parseatt(struct xmlparser * p) { char attname[64]; char attvalue[64]; while(p->xml < p->xmlend) { if(*p->xml=='/' || *p->xml=='>') return 0; if( !IS_WHITE_SPACE(*p->xml) ) { int j = 0; char sep; while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) { attname[j++] = *(p->xml++); if(p->xml >= p->xmlend) return -1; } attname[j] = '\0'; while(*(p->xml++) != '=') { if(p->xml >= p->xmlend) return -1; } while(IS_WHITE_SPACE(*p->xml)) { p->xml++; if(p->xml >= p->xmlend) return -1; } sep = *p->xml; j = 0; if(sep=='\'' || sep=='\"') { p->xml++; if(p->xml >= p->xmlend) return -1; while(*p->xml != sep) { attvalue[j++] = *(p->xml++); if(p->xml >= p->xmlend) return -1; } } else { while( !IS_WHITE_SPACE(*p->xml) && *p->xml != '>' && *p->xml != '/') { attvalue[j++] = *(p->xml++); if(p->xml >= p->xmlend) return -1; } } attvalue[j]='\0'; //printf("'%s'='%s' ", attname, attvalue); } p->xml++; } return -1; }