<?php
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Classes for reading and writing Avro data to AvroIO objects.
 *
 * @package Avro
 *
 * @todo Implement JSON encoding, as is required by the Avro spec.
 */

/**
 * Exceptions arising from writing or reading Avro data.
 *
 * @package Avro
 */
class AvroIOTypeException extends AvroException
{
  /**
   * @param AvroSchema $expected_schema
   * @param mixed $datum
   */
  public function __construct($expected_schema, $datum)
  {
    parent::__construct(sprintf('The datum %s is not an example of schema %s',
                                var_export($datum, true), $expected_schema));
  }
}

/**
 * Exceptions arising from incompatibility between
 * reader and writer schemas.
 *
 * @package Avro
 */
class AvroIOSchemaMatchException extends AvroException
{
  /**
   * @param AvroSchema $writers_schema
   * @param AvroSchema $readers_schema
   */
  function __construct($writers_schema, $readers_schema)
  {
    parent::__construct(
      sprintf("Writer's schema %s and Reader's schema %s do not match.",
              $writers_schema, $readers_schema));
  }
}

/**
 * Handles schema-specific writing of data to the encoder.
 *
 * Ensures that each datum written is consistent with the writer's schema.
 *
 * @package Avro
 */
class AvroIODatumWriter
{
  /**
   * Schema used by this instance to write Avro data.
   * @var AvroSchema
   */
  public $writers_schema;

  /**
   * @param AvroSchema $writers_schema
   */
  function __construct($writers_schema=null)
  {
    $this->writers_schema = $writers_schema;
  }

  /**
   * @param AvroSchema $writers_schema
   * @param $datum
   * @param AvroIOBinaryEncoder $encoder
   * @returns mixed
   *
   * @throws AvroIOTypeException if $datum is invalid for $writers_schema
   */
  function write_data($writers_schema, $datum, $encoder)
  {
    if (!AvroSchema::is_valid_datum($writers_schema, $datum))
      throw new AvroIOTypeException($writers_schema, $datum);

    switch ($writers_schema->type())
    {
      case AvroSchema::NULL_TYPE:
        return $encoder->write_null($datum);
      case AvroSchema::BOOLEAN_TYPE:
        return $encoder->write_boolean($datum);
      case AvroSchema::INT_TYPE:
        return $encoder->write_int($datum);
      case AvroSchema::LONG_TYPE:
        return $encoder->write_long($datum);
      case AvroSchema::FLOAT_TYPE:
        return $encoder->write_float($datum);
      case AvroSchema::DOUBLE_TYPE:
        return $encoder->write_double($datum);
      case AvroSchema::STRING_TYPE:
        return $encoder->write_string($datum);
      case AvroSchema::BYTES_TYPE:
        return $encoder->write_bytes($datum);
      case AvroSchema::ARRAY_SCHEMA:
        return $this->write_array($writers_schema, $datum, $encoder);
      case AvroSchema::MAP_SCHEMA:
        return $this->write_map($writers_schema, $datum, $encoder);
      case AvroSchema::FIXED_SCHEMA:
        return $this->write_fixed($writers_schema, $datum, $encoder);
      case AvroSchema::ENUM_SCHEMA:
      return $this->write_enum($writers_schema, $datum, $encoder);
      case AvroSchema::RECORD_SCHEMA:
      case AvroSchema::ERROR_SCHEMA:
      case AvroSchema::REQUEST_SCHEMA:
        return $this->write_record($writers_schema, $datum, $encoder);
      case AvroSchema::UNION_SCHEMA:
        return $this->write_union($writers_schema, $datum, $encoder);
      default:
        throw new AvroException(sprintf('Unknown type: %s',
                                        $writers_schema->type));
    }
  }

  /**
   * @param $datum
   * @param AvroIOBinaryEncoder $encoder
   */
  function write($datum, $encoder)
  {
    $this->write_data($this->writers_schema, $datum, $encoder);
  }

  /**#@+
   * @param AvroSchema $writers_schema
   * @param null|boolean|int|float|string|array $datum item to be written
   * @param AvroIOBinaryEncoder $encoder
   */
  private function write_array($writers_schema, $datum, $encoder)
  {
    $datum_count = count($datum);
    if (0 < $datum_count)
    {
      $encoder->write_long($datum_count);
      $items = $writers_schema->items();
      foreach ($datum as $item)
        $this->write_data($items, $item, $encoder);
    }
    return $encoder->write_long(0);
  }

  private function write_map($writers_schema, $datum, $encoder)
  {
    $datum_count = count($datum);
    if ($datum_count > 0)
    {
      $encoder->write_long($datum_count);
      foreach ($datum as $k => $v)
      {
        $encoder->write_string($k);
        $this->write_data($writers_schema->values(), $v, $encoder);
      }
    }
    $encoder->write_long(0);
  }

  private function write_union($writers_schema, $datum, $encoder)
  {
    $datum_schema_index = -1;
    $datum_schema = null;
    foreach ($writers_schema->schemas() as $index => $schema)
      if (AvroSchema::is_valid_datum($schema, $datum))
      {
        $datum_schema_index = $index;
        $datum_schema = $schema;
        break;
      }

    if (is_null($datum_schema))
      throw new AvroIOTypeException($writers_schema, $datum);

    $encoder->write_long($datum_schema_index);
    $this->write_data($datum_schema, $datum, $encoder);
  }

  private function write_enum($writers_schema, $datum, $encoder)
  {
    $datum_index = $writers_schema->symbol_index($datum);
    return $encoder->write_int($datum_index);
  }

  private function write_fixed($writers_schema, $datum, $encoder)
  {
    /**
     * NOTE Unused $writers_schema parameter included for consistency
     * with other write_* methods.
     */
    return $encoder->write($datum);
  }

  private function write_record($writers_schema, $datum, $encoder)
  {
    foreach ($writers_schema->fields() as $field)
      $this->write_data($field->type(), $datum[$field->name()], $encoder);
  }

  /**#@-*/
}

/**
 * Encodes and writes Avro data to an AvroIO object using
 * Avro binary encoding.
 *
 * @package Avro
 */
class AvroIOBinaryEncoder
{
  /**
   * Performs encoding of the given float value to a binary string
   *
   * XXX: This is <b>not</b> endian-aware! The {@link Avro::check_platform()}
   * called in {@link AvroIOBinaryEncoder::__construct()} should ensure the
   * library is only used on little-endian platforms, which ensure the little-endian
   * encoding required by the Avro spec.
   *
   * @param float $float
   * @returns string bytes
   * @see Avro::check_platform()
   */
  static function float_to_int_bits($float)
  {
    return pack('f', (float) $float);
  }

  /**
   * Performs encoding of the given double value to a binary string
   *
   * XXX: This is <b>not</b> endian-aware! See comments in
   * {@link AvroIOBinaryEncoder::float_to_int_bits()} for details.
   *
   * @param double $double
   * @returns string bytes
   */
  static function double_to_long_bits($double)
  {
    return pack('d', (double) $double);
  }

  /**
   * @param int|string $n
   * @returns string long $n encoded as bytes
   * @internal This relies on 64-bit PHP.
   */
  static public function encode_long($n)
  {
    $n = (int) $n;
    $n = ($n << 1) ^ ($n >> 63);
    $str = '';
    while (0 != ($n & ~0x7F))
    {
      $str .= chr(($n & 0x7F) | 0x80);
      $n >>= 7;
    }
    $str .= chr($n);
    return $str;
  }

  /**
   * @var AvroIO
   */
  private $io;

  /**
   * @param AvroIO $io object to which data is to be written.
   *
   */
  function __construct($io)
  {
    Avro::check_platform();
    $this->io = $io;
  }

  /**
   * @param null $datum actual value is ignored
   */
  function write_null($datum) { return null; }

  /**
   * @param boolean $datum
   */
  function write_boolean($datum)
  {
    $byte = $datum ? chr(1) : chr(0);
    $this->write($byte);
  }

  /**
   * @param int $datum
   */
  function write_int($datum) { $this->write_long($datum); }

  /**
   * @param int $n
   */
  function write_long($n)
  {
    if (Avro::uses_gmp())
      $this->write(AvroGMP::encode_long($n));
    else
      $this->write(self::encode_long($n));
  }

  /**
   * @param float $datum
   * @uses self::float_to_int_bits()
   */
  public function write_float($datum)
  {
    $this->write(self::float_to_int_bits($datum));
  }

  /**
   * @param float $datum
   * @uses self::double_to_long_bits()
   */
  public function write_double($datum)
  {
    $this->write(self::double_to_long_bits($datum));
  }

  /**
   * @param string $str
   * @uses self::write_bytes()
   */
  function write_string($str) { $this->write_bytes($str); }

  /**
   * @param string $bytes
   */
  function write_bytes($bytes)
  {
    $this->write_long(strlen($bytes));
    $this->write($bytes);
  }

  /**
   * @param string $datum
   */
  function write($datum) { $this->io->write($datum); }
}

/**
 * Handles schema-specifc reading of data from the decoder.
 *
 * Also handles schema resolution between the reader and writer
 * schemas (if a writer's schema is provided).
 *
 * @package Avro
 */
class AvroIODatumReader
{
  /**
   *
   * @param AvroSchema $writers_schema
   * @param AvroSchema $readers_schema
   * @returns boolean true if the schemas are consistent with
   *                  each other and false otherwise.
   */
  static function schemas_match($writers_schema, $readers_schema)
  {
    $writers_schema_type = $writers_schema->type;
    $readers_schema_type = $readers_schema->type;

    if (AvroSchema::UNION_SCHEMA == $writers_schema_type
        || AvroSchema::UNION_SCHEMA == $readers_schema_type)
      return true;

    if ($writers_schema_type == $readers_schema_type)
    {
      if (AvroSchema::is_primitive_type($writers_schema_type))
        return true;

      switch ($readers_schema_type)
      {
        case AvroSchema::MAP_SCHEMA:
          return self::attributes_match($writers_schema->values(),
                                        $readers_schema->values(),
                                        array(AvroSchema::TYPE_ATTR));
        case AvroSchema::ARRAY_SCHEMA:
          return self::attributes_match($writers_schema->items(),
                                        $readers_schema->items(),
                                        array(AvroSchema::TYPE_ATTR));
        case AvroSchema::ENUM_SCHEMA:
          return self::attributes_match($writers_schema, $readers_schema,
                                        array(AvroSchema::FULLNAME_ATTR));
        case AvroSchema::FIXED_SCHEMA:
          return self::attributes_match($writers_schema, $readers_schema,
                                        array(AvroSchema::FULLNAME_ATTR,
                                              AvroSchema::SIZE_ATTR));
        case AvroSchema::RECORD_SCHEMA:
        case AvroSchema::ERROR_SCHEMA:
          return self::attributes_match($writers_schema, $readers_schema,
                                        array(AvroSchema::FULLNAME_ATTR));
        case AvroSchema::REQUEST_SCHEMA:
          // XXX: This seems wrong
          return true;
          // XXX: no default
      }

      if (AvroSchema::INT_TYPE == $writers_schema_type
          && in_array($readers_schema_type, array(AvroSchema::LONG_TYPE,
                                                  AvroSchema::FLOAT_TYPE,
                                                  AvroSchema::DOUBLE_TYPE)))
        return true;

      if (AvroSchema::LONG_TYPE == $writers_schema_type
          && in_array($readers_schema_type, array(AvroSchema::FLOAT_TYPE,
                                                  AvroSchema::DOUBLE_TYPE)))
        return true;

      if (AvroSchema::FLOAT_TYPE == $writers_schema_type
          && AvroSchema::DOUBLE_TYPE == $readers_schema_type)
        return true;

      return false;
    }

  }

  /**
   * Checks equivalence of the given attributes of the two given schemas.
   *
   * @param AvroSchema $schema_one
   * @param AvroSchema $schema_two
   * @param string[] $attribute_names array of string attribute names to compare
   *
   * @returns boolean true if the attributes match and false otherwise.
   */
  static function attributes_match($schema_one, $schema_two, $attribute_names)
  {
    foreach ($attribute_names as $attribute_name)
      if ($schema_one->attribute($attribute_name)
          != $schema_two->attribute($attribute_name))
        return false;
    return true;
  }

  /**
   * @var AvroSchema
   */
  private $writers_schema;

  /**
   * @var AvroSchema
   */
  private $readers_schema;

  /**
   * @param AvroSchema $writers_schema
   * @param AvroSchema $readers_schema
   */
  function __construct($writers_schema=null, $readers_schema=null)
  {
    $this->writers_schema = $writers_schema;
    $this->readers_schema = $readers_schema;
  }

  /**
   * @param AvroSchema $readers_schema
   */
  public function set_writers_schema($readers_schema)
  {
    $this->writers_schema = $readers_schema;
  }

  /**
   * @param AvroIOBinaryDecoder $decoder
   * @returns string
   */
  public function read($decoder)
  {
    if (is_null($this->readers_schema))
      $this->readers_schema = $this->writers_schema;
    return $this->read_data($this->writers_schema, $this->readers_schema,
                            $decoder);
  }

  /**#@+
   * @param AvroSchema $writers_schema
   * @param AvroSchema $readers_schema
   * @param AvroIOBinaryDecoder $decoder
   */
  /**
   * @returns mixed
   */
  public function read_data($writers_schema, $readers_schema, $decoder)
  {
    if (!self::schemas_match($writers_schema, $readers_schema))
      throw new AvroIOSchemaMatchException($writers_schema, $readers_schema);

    // Schema resolution: reader's schema is a union, writer's schema is not
    if (AvroSchema::UNION_SCHEMA == $readers_schema->type()
        && AvroSchema::UNION_SCHEMA != $writers_schema->type())
    {
      foreach ($readers_schema->schemas() as $schema)
        if (self::schemas_match($writers_schema, $schema))
          return $this->read_data($writers_schema, $schema, $decoder);
      throw new AvroIOSchemaMatchException($writers_schema, $readers_schema);
    }

    switch ($writers_schema->type())
    {
      case AvroSchema::NULL_TYPE:
        return $decoder->read_null();
      case AvroSchema::BOOLEAN_TYPE:
        return $decoder->read_boolean();
      case AvroSchema::INT_TYPE:
        return $decoder->read_int();
      case AvroSchema::LONG_TYPE:
        return $decoder->read_long();
      case AvroSchema::FLOAT_TYPE:
        return $decoder->read_float();
      case AvroSchema::DOUBLE_TYPE:
        return $decoder->read_double();
      case AvroSchema::STRING_TYPE:
        return $decoder->read_string();
      case AvroSchema::BYTES_TYPE:
        return $decoder->read_bytes();
      case AvroSchema::ARRAY_SCHEMA:
        return $this->read_array($writers_schema, $readers_schema, $decoder);
      case AvroSchema::MAP_SCHEMA:
        return $this->read_map($writers_schema, $readers_schema, $decoder);
      case AvroSchema::UNION_SCHEMA:
        return $this->read_union($writers_schema, $readers_schema, $decoder);
      case AvroSchema::ENUM_SCHEMA:
        return $this->read_enum($writers_schema, $readers_schema, $decoder);
      case AvroSchema::FIXED_SCHEMA:
        return $this->read_fixed($writers_schema, $readers_schema, $decoder);
      case AvroSchema::RECORD_SCHEMA:
      case AvroSchema::ERROR_SCHEMA:
      case AvroSchema::REQUEST_SCHEMA:
        return $this->read_record($writers_schema, $readers_schema, $decoder);
      default:
        throw new AvroException(sprintf("Cannot read unknown schema type: %s",
                                        $writers_schema->type()));
    }
  }

  /**
   * @returns array
   */
  public function read_array($writers_schema, $readers_schema, $decoder)
  {
    $items = array();
    $block_count = $decoder->read_long();
    while (0 != $block_count)
    {
      if ($block_count < 0)
      {
        $block_count = -$block_count;
        $block_size = $decoder->read_long(); // Read (and ignore) block size
      }
      for ($i = 0; $i < $block_count; $i++)
        $items []= $this->read_data($writers_schema->items(),
                                    $readers_schema->items(),
                                    $decoder);
      $block_count = $decoder->read_long();
    }
    return $items;
  }

  /**
   * @returns array
   */
  public function read_map($writers_schema, $readers_schema, $decoder)
  {
    $items = array();
    $pair_count = $decoder->read_long();
    while (0 != $pair_count)
    {
      if ($pair_count < 0)
      {
        $pair_count = -$pair_count;
        // Note: we're not doing anything with block_size other than skipping it
        $block_size = $decoder->read_long();
      }

      for ($i = 0; $i < $pair_count; $i++)
      {
        $key = $decoder->read_string();
        $items[$key] = $this->read_data($writers_schema->values(),
                                        $readers_schema->values(),
                                        $decoder);
      }
      $pair_count = $decoder->read_long();
    }
    return $items;
  }

  /**
   * @returns mixed
   */
  public function read_union($writers_schema, $readers_schema, $decoder)
  {
    $schema_index = $decoder->read_long();
    $selected_writers_schema = $writers_schema->schema_by_index($schema_index);
    return $this->read_data($selected_writers_schema, $readers_schema, $decoder);
  }

  /**
   * @returns string
   */
  public function read_enum($writers_schema, $readers_schema, $decoder)
  {
    $symbol_index = $decoder->read_int();
    $symbol = $writers_schema->symbol_by_index($symbol_index);
    if (!$readers_schema->has_symbol($symbol))
      null; // FIXME: unset wrt schema resolution
    return $symbol;
  }

  /**
   * @returns string
   */
  public function read_fixed($writers_schema, $readers_schema, $decoder)
  {
    return $decoder->read($writers_schema->size());
  }

  /**
   * @returns array
   */
  public function read_record($writers_schema, $readers_schema, $decoder)
  {
    $readers_fields = $readers_schema->fields_hash();
    $record = array();
    foreach ($writers_schema->fields() as $writers_field)
    {
      $type = $writers_field->type();
      if (isset($readers_fields[$writers_field->name()]))
        $record[$writers_field->name()]
          = $this->read_data($type,
                             $readers_fields[$writers_field->name()]->type(),
                             $decoder);
      else
        $this->skip_data($type, $decoder);
    }
    // Fill in default values
    if (count($readers_fields) > count($record))
    {
      $writers_fields = $writers_schema->fields_hash();
      foreach ($readers_fields as $field_name => $field)
      {
        if (!isset($writers_fields[$field_name]))
        {
          if ($field->has_default_value())
            $record[$field->name()]
              = $this->read_default_value($field->type(),
                                          $field->default_value());
          else
            null; // FIXME: unset
        }
      }
    }

    return $record;
  }
  /**#@-*/

  /**
   * @param AvroSchema $field_schema
   * @param null|boolean|int|float|string|array $default_value
   * @returns null|boolean|int|float|string|array
   *
   * @throws AvroException if $field_schema type is unknown.
   */
  public function read_default_value($field_schema, $default_value)
  {
    switch($field_schema->type())
    {
      case AvroSchema::NULL_TYPE:
        return null;
      case AvroSchema::BOOLEAN_TYPE:
        return $default_value;
      case AvroSchema::INT_TYPE:
      case AvroSchema::LONG_TYPE:
        return (int) $default_value;
      case AvroSchema::FLOAT_TYPE:
      case AvroSchema::DOUBLE_TYPE:
        return (float) $default_value;
      case AvroSchema::STRING_TYPE:
      case AvroSchema::BYTES_TYPE:
        return $default_value;
      case AvroSchema::ARRAY_SCHEMA:
        $array = array();
        foreach ($default_value as $json_val)
        {
          $val = $this->read_default_value($field_schema->items(), $json_val);
          $array []= $val;
        }
        return $array;
      case AvroSchema::MAP_SCHEMA:
        $map = array();
        foreach ($default_value as $key => $json_val)
          $map[$key] = $this->read_default_value($field_schema->values(),
                                                 $json_val);
        return $map;
      case AvroSchema::UNION_SCHEMA:
        return $this->read_default_value($field_schema->schema_by_index(0),
                                         $default_value);
      case AvroSchema::ENUM_SCHEMA:
      case AvroSchema::FIXED_SCHEMA:
        return $default_value;
      case AvroSchema::RECORD_SCHEMA:
        $record = array();
        foreach ($field_schema->fields() as $field)
        {
          $field_name = $field->name();
          if (!$json_val = $default_value[$field_name])
            $json_val = $field->default_value();

          $record[$field_name] = $this->read_default_value($field->type(),
                                                           $json_val);
        }
        return $record;
    default:
      throw new AvroException(sprintf('Unknown type: %s', $field_schema->type()));
    }
  }

  /**
   * @param AvroSchema $writers_schema
   * @param AvroIOBinaryDecoder $decoder
   */
  private function skip_data($writers_schema, $decoder)
  {
    switch ($writers_schema->type())
    {
      case AvroSchema::NULL_TYPE:
        return $decoder->skip_null();
      case AvroSchema::BOOLEAN_TYPE:
        return $decoder->skip_boolean();
      case AvroSchema::INT_TYPE:
        return $decoder->skip_int();
      case AvroSchema::LONG_TYPE:
        return $decoder->skip_long();
      case AvroSchema::FLOAT_TYPE:
        return $decoder->skip_float();
      case AvroSchema::DOUBLE_TYPE:
        return $decoder->skip_double();
      case AvroSchema::STRING_TYPE:
        return $decoder->skip_string();
      case AvroSchema::BYTES_TYPE:
        return $decoder->skip_bytes();
      case AvroSchema::ARRAY_SCHEMA:
        return $decoder->skip_array($writers_schema, $decoder);
      case AvroSchema::MAP_SCHEMA:
        return $decoder->skip_map($writers_schema, $decoder);
      case AvroSchema::UNION_SCHEMA:
        return $decoder->skip_union($writers_schema, $decoder);
      case AvroSchema::ENUM_SCHEMA:
        return $decoder->skip_enum($writers_schema, $decoder);
      case AvroSchema::FIXED_SCHEMA:
        return $decoder->skip_fixed($writers_schema, $decoder);
      case AvroSchema::RECORD_SCHEMA:
      case AvroSchema::ERROR_SCHEMA:
      case AvroSchema::REQUEST_SCHEMA:
        return $decoder->skip_record($writers_schema, $decoder);
      default:
        throw new AvroException(sprintf('Unknown schema type: %s',
                                        $writers_schema->type()));
    }
  }
}

/**
 * Decodes and reads Avro data from an AvroIO object encoded using
 * Avro binary encoding.
 *
 * @package Avro
 */
class AvroIOBinaryDecoder
{

  /**
   * @param int[] array of byte ascii values
   * @returns long decoded value
   * @internal Requires 64-bit platform
   */
  public static function decode_long_from_array($bytes)
  {
    $b = array_shift($bytes);
    $n = $b & 0x7f;
    $shift = 7;
    while (0 != ($b & 0x80))
    {
      $b = array_shift($bytes);
      $n |= (($b & 0x7f) << $shift);
      $shift += 7;
    }
    return (($n >> 1) ^ -($n & 1));
  }

  /**
   * Performs decoding of the binary string to a float value.
   *
   * XXX: This is <b>not</b> endian-aware! See comments in
   * {@link AvroIOBinaryEncoder::float_to_int_bits()} for details.
   *
   * @param string $bits
   * @returns float
   */
  static public function int_bits_to_float($bits)
  {
    $float = unpack('f', $bits);
    return (float) $float[1];
  }

  /**
   * Performs decoding of the binary string to a double value.
   *
   * XXX: This is <b>not</b> endian-aware! See comments in
   * {@link AvroIOBinaryEncoder::float_to_int_bits()} for details.
   *
   * @param string $bits
   * @returns float
   */
  static public function long_bits_to_double($bits)
  {
    $double = unpack('d', $bits);
    return (double) $double[1];
  }

  /**
   * @var AvroIO
   */
  private $io;

  /**
   * @param AvroIO $io object from which to read.
   */
  public function __construct($io)
  {
    Avro::check_platform();
    $this->io = $io;
  }

  /**
   * @returns string the next byte from $this->io.
   * @throws AvroException if the next byte cannot be read.
   */
  private function next_byte() { return $this->read(1); }

  /**
   * @returns null
   */
  public function read_null() { return null; }

  /**
   * @returns boolean
   */
  public function read_boolean()
  {
    return (boolean) (1 == ord($this->next_byte()));
  }

  /**
   * @returns int
   */
  public function read_int() { return (int) $this->read_long(); }

  /**
   * @returns long
   */
  public function read_long()
  {
    $byte = ord($this->next_byte());
    $bytes = array($byte);
    while (0 != ($byte & 0x80))
    {
      $byte = ord($this->next_byte());
      $bytes []= $byte;
    }

    if (Avro::uses_gmp())
      return AvroGMP::decode_long_from_array($bytes);

    return self::decode_long_from_array($bytes);
  }

  /**
   * @returns float
   */
  public function read_float()
  {
    return self::int_bits_to_float($this->read(4));
  }

  /**
   * @returns double
   */
  public function read_double()
  {
    return self::long_bits_to_double($this->read(8));
  }

  /**
   * A string is encoded as a long followed by that many bytes
   * of UTF-8 encoded character data.
   * @returns string
   */
  public function read_string() { return $this->read_bytes(); }

  /**
   * @returns string
   */
  public function read_bytes() { return $this->read($this->read_long()); }

  /**
   * @param int $len count of bytes to read
   * @returns string
   */
  public function read($len) { return $this->io->read($len); }

  public function skip_null() { return null; }

  public function skip_boolean() { return $this->skip(1); }

  public function skip_int() { return $this->skip_long(); }

  public function skip_long()
  {
    $b = $this->next_byte();
    while (0 != (ord($b) & 0x80))
      $b = $this->next_byte();
  }

  public function skip_float() { return $this->skip(4); }

  public function skip_double() { return $this->skip(8); }

  public function skip_bytes() { return $this->skip($this->read_long()); }

  public function skip_string() { return $this->skip_bytes(); }

  /**
   * @param int $len count of bytes to skip
   * @uses AvroIO::seek()
   */
  public function skip($len) { $this->seek($len, AvroIO::SEEK_CUR); }

  /**
   * @returns int position of pointer in AvroIO instance
   * @uses AvroIO::tell()
   */
  private function tell() { return $this->io->tell(); }

  /**
   * @param int $offset
   * @param int $whence
   * @returns boolean true upon success
   * @uses AvroIO::seek()
   */
  private function seek($offset, $whence)
  {
    return $this->io->seek($offset, $whence);
  }
}

