1<?php 2 3namespace Rubix\ML\Persisters\Serializers; 4 5use Rubix\ML\Encoding; 6use Rubix\ML\Persistable; 7use Rubix\ML\Exceptions\RuntimeException; 8use Rubix\ML\Exceptions\InvalidArgumentException; 9 10/** 11 * Gzip 12 * 13 * A compression format based on the DEFLATE algorithm with a header and CRC32 checksum. 14 * 15 * References: 16 * [1] P. Deutsch. (1996). RFC 1951 - DEFLATE Compressed Data Format Specification version. 17 * 18 * @category Machine Learning 19 * @package Rubix/ML 20 * @author Andrew DalPino 21 */ 22class Gzip implements Serializer 23{ 24 /** 25 * The compression level between 0 and 9, 0 meaning no compression. 26 * 27 * @var int 28 */ 29 protected $level; 30 31 /** 32 * The base serializer. 33 * 34 * @var \Rubix\ML\Persisters\Serializers\Serializer 35 */ 36 protected $base; 37 38 /** 39 * @param int $level 40 * @param \Rubix\ML\Persisters\Serializers\Serializer|null $base 41 * @throws \Rubix\ML\Exceptions\InvalidArgumentException 42 */ 43 public function __construct(int $level = 1, ?Serializer $base = null) 44 { 45 if ($level < 0 or $level > 9) { 46 throw new InvalidArgumentException('Level must be' 47 . " between 0 and 9, $level given."); 48 } 49 50 if ($base instanceof self) { 51 throw new InvalidArgumentException('Base serializer' 52 . ' must not be an instance of Gzip.'); 53 } 54 55 $this->level = $level; 56 $this->base = $base ?? new Native(); 57 } 58 59 /** 60 * Serialize a persistable object and return the data. 61 * 62 * @param \Rubix\ML\Persistable $persistable 63 * @return \Rubix\ML\Encoding 64 */ 65 public function serialize(Persistable $persistable) : Encoding 66 { 67 $encoding = $this->base->serialize($persistable); 68 69 $data = gzencode($encoding, $this->level); 70 71 if ($data === false) { 72 throw new RuntimeException('Failed to compress data.'); 73 } 74 75 return new Encoding($data); 76 } 77 78 /** 79 * Unserialize a persistable object and return it. 80 * 81 * @param \Rubix\ML\Encoding $encoding 82 * @throws \Rubix\ML\Exceptions\RuntimeException 83 * @return \Rubix\ML\Persistable 84 */ 85 public function unserialize(Encoding $encoding) : Persistable 86 { 87 $data = gzdecode($encoding); 88 89 if ($data === false) { 90 throw new RuntimeException('Failed to decompress data.'); 91 } 92 93 return $this->base->unserialize(new Encoding($data)); 94 } 95 96 /** 97 * Return the string representation of the object. 98 * 99 * @return string 100 */ 101 public function __toString() : string 102 { 103 return "Gzip (level: {$this->level}, base: {$this->base})"; 104 } 105} 106