    /**
     * call-seq:
     *    parser.execute(req_hash, data, start) -> Integer
     *
     * Takes a Hash and a String of data, parses the String of data filling in the Hash
     * returning an Integer to indicate how much of the data has been read.  No matter
     * what the return value, you should call HttpParser#finished? and HttpParser#error?
     * to figure out if it's done parsing or there was an error.
     *
     * This function now throws an exception when there is a parsing error.  This makes
     * the logic for working with the parser much easier.  You can still test for an
     * error, but now you need to wrap the parser with an exception handling block.
     *
     * The third argument allows for parsing a partial request and then continuing
     * the parsing from that position.  It needs all of the original data as well
     * so you have to append to the data buffer as you read.
     */
    VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
    {
      http_parser *http = NULL;
      int from = 0;
      char *dptr = NULL;
      long dlen = 0;

      DATA_GET(self, http_parser, http);

      from = FIX2INT(start);
      dptr = RSTRING(data)->ptr;
      dlen = RSTRING(data)->len;

      if(from >= dlen) {
        rb_raise(eHttpParserError, "Requested start is after data buffer end.");
      } else {
        http->data = (void *)req_hash;
        http_parser_execute(http, dptr, dlen, from);

        VALIDATE_MAX_LENGTH(http_parser_nread(http), HEADER);

        if(http_parser_has_error(http)) {
          rb_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
        } else {
          return INT2FIX(http_parser_nread(http));
        }
      }
    }