+zend_class_entry *php_http_message_parser_class_entry;
+static zend_object_handlers php_http_message_parser_object_handlers;
+
+zend_object *php_http_message_parser_object_new(zend_class_entry *ce)
+{
+ return &php_http_message_parser_object_new_ex(ce, NULL)->zo;
+}
+
+php_http_message_parser_object_t *php_http_message_parser_object_new_ex(zend_class_entry *ce, php_http_message_parser_t *parser)
+{
+ php_http_message_parser_object_t *o;
+
+ o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce));
+ zend_object_std_init(&o->zo, ce);
+ object_properties_init(&o->zo, ce);
+
+ if (parser) {
+ o->parser = parser;
+ } else {
+ o->parser = php_http_message_parser_init(NULL);
+ }
+ php_http_buffer_init(&o->buffer);
+ o->zo.handlers = &php_http_message_parser_object_handlers;
+
+ return o;
+}
+
+void php_http_message_parser_object_free(zend_object *object)
+{
+ php_http_message_parser_object_t *o = PHP_HTTP_OBJ(object, NULL);
+
+ if (o->parser) {
+ php_http_message_parser_free(&o->parser);
+ }
+ php_http_buffer_dtor(&o->buffer);
+ zend_object_std_dtor(object);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_getState, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpMessageParser, getState)
+{
+ php_http_message_parser_object_t *parser_obj = PHP_HTTP_OBJ(NULL, getThis());
+
+ zend_parse_parameters_none();
+ /* always return the real state */
+ RETVAL_LONG(php_http_message_parser_state_is(parser_obj->parser));
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_parse, 0, 0, 3)
+ ZEND_ARG_INFO(0, data)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(1, message)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpMessageParser, parse)
+{
+ php_http_message_parser_object_t *parser_obj;
+ zval *zmsg;
+ char *data_str;
+ size_t data_len;
+ zend_long flags;
+
+ php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz", &data_str, &data_len, &flags, &zmsg), invalid_arg, return);
+
+ parser_obj = PHP_HTTP_OBJ(NULL, getThis());
+ php_http_buffer_append(&parser_obj->buffer, data_str, data_len);
+ RETVAL_LONG(php_http_message_parser_parse(parser_obj->parser, &parser_obj->buffer, flags, &parser_obj->parser->message));
+
+ ZVAL_DEREF(zmsg);
+ zval_dtor(zmsg);
+ ZVAL_NULL(zmsg);
+ if (parser_obj->parser->message) {
+ php_http_message_t *msg_cpy = php_http_message_copy(parser_obj->parser->message, NULL);
+ php_http_message_object_t *msg_obj = php_http_message_object_new_ex(php_http_message_class_entry, msg_cpy);
+ ZVAL_OBJ(zmsg, &msg_obj->zo);
+ }
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_stream, 0, 0, 3)
+ ZEND_ARG_INFO(0, stream)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(1, message)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpMessageParser, stream)
+{
+ php_http_message_parser_object_t *parser_obj;
+ zend_error_handling zeh;
+ zval *zmsg, *zstream;
+ php_stream *s;
+ zend_long flags;
+
+ php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &zstream, &flags, &zmsg), invalid_arg, return);
+
+ zend_replace_error_handling(EH_THROW, php_http_exception_unexpected_val_class_entry, &zeh);
+ php_stream_from_zval(s, zstream);
+ zend_restore_error_handling(&zeh);
+
+ parser_obj = PHP_HTTP_OBJ(NULL, getThis());
+ RETVAL_LONG(php_http_message_parser_parse_stream(parser_obj->parser, &parser_obj->buffer, s, flags, &parser_obj->parser->message));
+
+ ZVAL_DEREF(zmsg);
+ zval_dtor(zmsg);
+ ZVAL_NULL(zmsg);
+ if (parser_obj->parser->message) {
+ php_http_message_t *msg_cpy = php_http_message_copy(parser_obj->parser->message, NULL);
+ php_http_message_object_t *msg_obj = php_http_message_object_new_ex(php_http_message_class_entry, msg_cpy);
+ ZVAL_OBJ(zmsg, &msg_obj->zo);
+ }
+}
+
+static zend_function_entry php_http_message_parser_methods[] = {
+ PHP_ME(HttpMessageParser, getState, ai_HttpMessageParser_getState, ZEND_ACC_PUBLIC)
+ PHP_ME(HttpMessageParser, parse, ai_HttpMessageParser_parse, ZEND_ACC_PUBLIC)
+ PHP_ME(HttpMessageParser, stream, ai_HttpMessageParser_stream, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+PHP_MINIT_FUNCTION(http_message_parser)
+{
+ zend_class_entry ce;
+
+ INIT_NS_CLASS_ENTRY(ce, "http\\Message", "Parser", php_http_message_parser_methods);
+ php_http_message_parser_class_entry = zend_register_internal_class(&ce);
+ memcpy(&php_http_message_parser_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ php_http_message_parser_class_entry->create_object = php_http_message_parser_object_new;
+ php_http_message_parser_object_handlers.clone_obj = NULL;
+ php_http_message_parser_object_handlers.free_obj = php_http_message_parser_object_free;
+ php_http_message_parser_object_handlers.offset = XtOffsetOf(php_http_message_parser_object_t, zo);
+
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("CLEANUP"), PHP_HTTP_MESSAGE_PARSER_CLEANUP);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("DUMB_BODIES"), PHP_HTTP_MESSAGE_PARSER_DUMB_BODIES);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("EMPTY_REDIRECTS"), PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("GREEDY"), PHP_HTTP_MESSAGE_PARSER_GREEDY);
+
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_FAILURE"), PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_START"), PHP_HTTP_MESSAGE_PARSER_STATE_START);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_HEADER"), PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_HEADER_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_DUMB"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_LENGTH"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_CHUNKED"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_UPDATE_CL"), PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
+
+ return SUCCESS;
+}
+