diff --git a/lib/avro/datum.php b/lib/avro/datum.php index bde5cf7..354f96b 100644 --- a/lib/avro/datum.php +++ b/lib/avro/datum.php @@ -584,7 +584,7 @@ public function read_data($writers_schema, $readers_schema, $decoder) case AvroSchema::STRING_TYPE: return $decoder->read_string(); case AvroSchema::BYTES_TYPE: - return $decoder->read_bytes(); + return $decoder->read_bytes($writers_schema, $readers_schema, $decoder); case AvroSchema::ARRAY_SCHEMA: return $this->read_array($writers_schema, $readers_schema, $decoder); case AvroSchema::MAP_SCHEMA: @@ -918,6 +918,17 @@ static public function long_bits_to_double($bits) return (double) $double[1]; } + /** + * @param $bytes + * @param $scale + * @return float|int + */ + static public function bytes_to_decimal($bytes, $scale = 0) + { + $int = hexdec(bin2hex($bytes)); + return $scale > 0 ? ($int / (10 ** $scale)) : $int; + } + /** * @var AvroIO */ @@ -996,12 +1007,20 @@ public function read_double() * of UTF-8 encoded character data. * @return string */ - public function read_string() { return $this->read_bytes(); } + public function read_string() { return $this->read($this->read_long()); } /** + * For Decimal logical type spec https://avro.apache.org/docs/1.10.2/spec.pdf Section 10.1 * @return string */ - public function read_bytes() { return $this->read($this->read_long()); } + public function read_bytes($writers_schema, $readers_schema, $decoder) + { + $bytes = $this->read($this->read_long()); + if ($writers_schema->logical_type() === 'decimal') { + return self::bytes_to_decimal($bytes, $writers_schema->extra_attributes()['scale'] ?? 0); + } + return $bytes; + } /** * @param int $len count of bytes to read