in External/HTTP/util_http_reader.c [132:501]
size_t util_http_reader_read(struct util_http_reader* r, char* buffer, size_t length) {
size_t n;
int post;
HAPPrecondition(r != NULL);
HAPPrecondition(buffer != NULL);
r->result_token = NULL;
r->result_length = 0;
n = 0;
HAPAssert(n <= length);
if (n < length) {
do {
switch (r->state) {
case util_HTTP_READER_STATE_EXPECTING_METHOD:
if (r->substate == SUBSTATE_NONE) {
n += skip_whitespace(&buffer[n], length - n);
HAPAssert(n <= length);
if (n < length) {
if (buffer[n] == CR) {
n++;
r->substate = SUBSTATE_AFTER_CR;
} else if (buffer[n] == LF) {
n++;
} else {
r->state = util_HTTP_READER_STATE_READING_METHOD;
}
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_CR);
if (buffer[n] == LF) {
n++;
r->substate = SUBSTATE_NONE;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
}
break;
case util_HTTP_READER_STATE_READING_METHOD:
if (r->substate == SUBSTATE_NONE) {
if (is_token_char(buffer[n])) {
r->substate = SUBSTATE_READING;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_READING);
n += read_octets(r, &buffer[n], length - n, is_token_char);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_METHOD;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_COMPLETED_METHOD:
r->state = util_HTTP_READER_STATE_EXPECTING_URI;
break;
case util_HTTP_READER_STATE_EXPECTING_URI:
if (r->substate == SUBSTATE_NONE) {
if (is_whitespace(buffer[n])) {
n++;
r->substate = SUBSTATE_AFTER_SP;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_SP);
n += skip_whitespace(&buffer[n], length - n);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_READING_URI;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_READING_URI:
if (r->substate == SUBSTATE_NONE) {
if (is_uri_char(buffer[n])) {
r->substate = SUBSTATE_READING;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_READING);
n += read_octets(r, &buffer[n], length - n, is_uri_char);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_URI;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_COMPLETED_URI:
r->state = util_HTTP_READER_STATE_EXPECTING_VERSION;
break;
case util_HTTP_READER_STATE_EXPECTING_VERSION:
if (r->type == util_HTTP_READER_TYPE_REQUEST) {
if (r->substate == SUBSTATE_NONE) {
if (is_whitespace(buffer[n])) {
n++;
r->substate = SUBSTATE_AFTER_SP;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_SP);
n += skip_whitespace(&buffer[n], length - n);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_READING_VERSION;
r->substate = SUBSTATE_NONE;
}
}
} else {
HAPAssert(r->type == util_HTTP_READER_TYPE_RESPONSE);
if (r->substate == SUBSTATE_NONE) {
n += skip_whitespace(&buffer[n], length - n);
HAPAssert(n <= length);
if (n < length) {
if (buffer[n] == CR) {
n++;
r->substate = SUBSTATE_AFTER_CR;
} else if (buffer[n] == LF) {
n++;
} else {
r->state = util_HTTP_READER_STATE_READING_VERSION;
}
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_CR);
if (buffer[n] == LF) {
n++;
r->substate = SUBSTATE_NONE;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
}
}
break;
case util_HTTP_READER_STATE_READING_VERSION:
if (r->substate == SUBSTATE_NONE) {
if (is_version_char(buffer[n])) {
r->substate = SUBSTATE_READING;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_READING);
n += read_octets(r, &buffer[n], length - n, is_version_char);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_VERSION;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_COMPLETED_VERSION:
if (r->type == util_HTTP_READER_TYPE_REQUEST) {
r->state = util_HTTP_READER_STATE_EXPECTING_HEADER_NAME;
} else {
HAPAssert(r->type == util_HTTP_READER_TYPE_RESPONSE);
r->state = util_HTTP_READER_STATE_EXPECTING_STATUS;
}
break;
case util_HTTP_READER_STATE_EXPECTING_STATUS:
if (r->substate == SUBSTATE_NONE) {
if (is_whitespace(buffer[n])) {
n++;
r->substate = SUBSTATE_AFTER_SP;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_SP);
n += skip_whitespace(&buffer[n], length - n);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_READING_STATUS;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_READING_STATUS:
if (r->substate == SUBSTATE_NONE) {
if (is_digit(buffer[n])) {
r->substate = SUBSTATE_READING;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_READING);
n += read_octets(r, &buffer[n], length - n, is_digit);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_STATUS;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_COMPLETED_STATUS:
r->state = util_HTTP_READER_STATE_EXPECTING_REASON;
break;
case util_HTTP_READER_STATE_EXPECTING_REASON:
if (r->substate == SUBSTATE_NONE) {
if (is_whitespace(buffer[n])) {
n++;
r->substate = SUBSTATE_AFTER_SP;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_SP);
n += skip_whitespace(&buffer[n], length - n);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_READING_REASON;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_READING_REASON:
n += read_octets(r, &buffer[n], length - n, is_text_char);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_REASON;
}
break;
case util_HTTP_READER_STATE_COMPLETED_REASON:
r->state = util_HTTP_READER_STATE_EXPECTING_HEADER_NAME;
break;
case util_HTTP_READER_STATE_EXPECTING_HEADER_NAME:
if (r->substate == SUBSTATE_NONE) {
if (buffer[n] == CR) {
n++;
r->substate = SUBSTATE_AFTER_CR;
} else if (buffer[n] == LF) {
n++;
r->state = util_HTTP_READER_STATE_READING_HEADER_NAME;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_CR);
if (buffer[n] == LF) {
n++;
r->state = util_HTTP_READER_STATE_READING_HEADER_NAME;
r->substate = SUBSTATE_NONE;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
}
break;
case util_HTTP_READER_STATE_READING_HEADER_NAME:
if (r->substate == SUBSTATE_NONE) {
if (is_token_char(buffer[n])) {
r->substate = SUBSTATE_READING;
} else {
r->state = util_HTTP_READER_STATE_ENDING_HEADER_LINES;
}
} else {
HAPAssert(r->substate == SUBSTATE_READING);
n += read_octets(r, &buffer[n], length - n, is_token_char);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_HEADER_NAME;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_COMPLETED_HEADER_NAME:
r->state = util_HTTP_READER_STATE_EXPECTING_HEADER_VALUE;
break;
case util_HTTP_READER_STATE_EXPECTING_HEADER_VALUE:
if (buffer[n] == ':') {
n++;
r->state = util_HTTP_READER_STATE_READING_HEADER_VALUE;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
break;
case util_HTTP_READER_STATE_READING_HEADER_VALUE:
n += read_octets_and_quotes(r, &buffer[n], length - n, is_text_char);
HAPAssert(n <= length);
if (n < length) {
r->state = util_HTTP_READER_STATE_COMPLETED_HEADER_VALUE;
}
break;
case util_HTTP_READER_STATE_COMPLETED_HEADER_VALUE:
r->state = util_HTTP_READER_STATE_ENDING_HEADER_LINE;
break;
case util_HTTP_READER_STATE_ENDING_HEADER_LINE:
if (r->substate == SUBSTATE_NONE) {
if (buffer[n] == CR) {
n++;
r->substate = SUBSTATE_AFTER_CR;
} else if (buffer[n] == LF) {
n++;
r->substate = SUBSTATE_AFTER_LF;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else if (r->substate == SUBSTATE_AFTER_CR) {
if (buffer[n] == LF) {
n++;
r->substate = SUBSTATE_AFTER_LF;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_LF);
if (is_whitespace(buffer[n])) {
r->state = util_HTTP_READER_STATE_READING_HEADER_VALUE;
r->substate = SUBSTATE_NONE;
} else if (r->in_quoted_string) {
r->state = util_HTTP_READER_STATE_ERROR;
} else {
r->state = util_HTTP_READER_STATE_READING_HEADER_NAME;
r->substate = SUBSTATE_NONE;
}
}
break;
case util_HTTP_READER_STATE_ENDING_HEADER_LINES:
if (r->substate == SUBSTATE_NONE) {
if (buffer[n] == CR) {
n++;
r->substate = SUBSTATE_AFTER_CR;
} else if (buffer[n] == LF) {
n++;
r->state = util_HTTP_READER_STATE_DONE;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
} else {
HAPAssert(r->substate == SUBSTATE_AFTER_CR);
if (buffer[n] == LF) {
n++;
r->state = util_HTTP_READER_STATE_DONE;
r->substate = SUBSTATE_NONE;
} else {
r->state = util_HTTP_READER_STATE_ERROR;
}
}
break;
case util_HTTP_READER_STATE_DONE:
case util_HTTP_READER_STATE_ERROR:
break;
default:
HAPFatalError();
break;
}
} while ((n < length) && (r->state != util_HTTP_READER_STATE_COMPLETED_METHOD) &&
(r->state != util_HTTP_READER_STATE_COMPLETED_URI) &&
(r->state != util_HTTP_READER_STATE_COMPLETED_VERSION) &&
(r->state != util_HTTP_READER_STATE_COMPLETED_STATUS) &&
(r->state != util_HTTP_READER_STATE_COMPLETED_REASON) &&
(r->state != util_HTTP_READER_STATE_COMPLETED_HEADER_NAME) &&
(r->state != util_HTTP_READER_STATE_COMPLETED_HEADER_VALUE) &&
(r->state != util_HTTP_READER_STATE_DONE) && (r->state != util_HTTP_READER_STATE_ERROR));
}
post = (n == length) ||
((n < length) &&
((r->state == util_HTTP_READER_STATE_ERROR) || (r->state == util_HTTP_READER_STATE_COMPLETED_METHOD) ||
(r->state == util_HTTP_READER_STATE_COMPLETED_URI) ||
(r->state == util_HTTP_READER_STATE_COMPLETED_VERSION) ||
(r->state == util_HTTP_READER_STATE_COMPLETED_STATUS) ||
(r->state == util_HTTP_READER_STATE_COMPLETED_REASON) ||
(r->state == util_HTTP_READER_STATE_COMPLETED_HEADER_NAME) ||
(r->state == util_HTTP_READER_STATE_COMPLETED_HEADER_VALUE) || (r->state == util_HTTP_READER_STATE_DONE)));
HAPAssert(post);
return n;
}