X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/vendor/wikimedia/avro/lib/avro/io.php diff --git a/vendor/wikimedia/avro/lib/avro/io.php b/vendor/wikimedia/avro/lib/avro/io.php new file mode 100644 index 00000000..239e53d8 --- /dev/null +++ b/vendor/wikimedia/avro/lib/avro/io.php @@ -0,0 +1,494 @@ +not like eof in C or feof in PHP: + * it returns TRUE if the *next* read would be end of file, + * rather than if the *most recent* read read end of file. + * @returns boolean true if at the end of file, and false otherwise + */ + public function is_eof() + { + throw new AvroNotImplementedException('Not implemented'); + } + + /** + * Closes this AvroIO instance. + */ + public function close() + { + throw new AvroNotImplementedException('Not implemented'); + } + +} + +/** + * AvroIO wrapper for string access + * @package Avro + */ +class AvroStringIO extends AvroIO +{ + /** + * @var string + */ + private $string_buffer; + /** + * @var int current position in string + */ + private $current_index; + /** + * @var boolean whether or not the string is closed. + */ + private $is_closed; + + /** + * @param string $str initial value of AvroStringIO buffer. Regardless + * of the initial value, the pointer is set to the + * beginning of the buffer. + * @throws AvroIOException if a non-string value is passed as $str + */ + public function __construct($str = '') + { + $this->is_closed = false; + $this->string_buffer = ''; + $this->current_index = 0; + + if (is_string($str)) + $this->string_buffer .= $str; + else + throw new AvroIOException( + sprintf('constructor argument must be a string: %s', gettype($str))); + } + + /** + * Append bytes to this buffer. + * (Nothing more is needed to support Avro.) + * @param str $arg bytes to write + * @returns int count of bytes written. + * @throws AvroIOException if $args is not a string value. + */ + public function write($arg) + { + $this->check_closed(); + if (is_string($arg)) + return $this->append_str($arg); + throw new AvroIOException( + sprintf('write argument must be a string: (%s) %s', + gettype($arg), var_export($arg, true))); + } + + /** + * @returns string bytes read from buffer + * @todo test for fencepost errors wrt updating current_index + */ + public function read($len) + { + $this->check_closed(); + $read=''; + for($i=$this->current_index; $i<($this->current_index+$len); $i++) + $read .= $this->string_buffer[$i]; + if (strlen($read) < $len) + $this->current_index = $this->length(); + else + $this->current_index += $len; + return $read; + } + + /** + * @returns boolean true if successful + * @throws AvroIOException if the seek failed. + */ + public function seek($offset, $whence=self::SEEK_SET) + { + if (!is_int($offset)) + throw new AvroIOException('Seek offset must be an integer.'); + // Prevent seeking before BOF + switch ($whence) + { + case self::SEEK_SET: + if (0 > $offset) + throw new AvroIOException('Cannot seek before beginning of file.'); + $this->current_index = $offset; + break; + case self::SEEK_CUR: + if (0 > $this->current_index + $whence) + throw new AvroIOException('Cannot seek before beginning of file.'); + $this->current_index += $offset; + break; + case self::SEEK_END: + if (0 > $this->length() + $offset) + throw new AvroIOException('Cannot seek before beginning of file.'); + $this->current_index = $this->length() + $offset; + break; + default: + throw new AvroIOException(sprintf('Invalid seek whence %d', $whence)); + } + + return true; + } + + /** + * @returns int + * @see AvroIO::tell() + */ + public function tell() { return $this->current_index; } + + /** + * @returns boolean + * @see AvroIO::is_eof() + */ + public function is_eof() + { + return ($this->current_index >= $this->length()); + } + + /** + * No-op provided for compatibility with AvroIO interface. + * @returns boolean true + */ + public function flush() { return true; } + + /** + * Marks this buffer as closed. + * @returns boolean true + */ + public function close() + { + $this->check_closed(); + $this->is_closed = true; + return true; + } + + /** + * @throws AvroIOException if the buffer is closed. + */ + private function check_closed() + { + if ($this->is_closed()) + throw new AvroIOException('Buffer is closed'); + } + + /** + * Appends bytes to this buffer. + * @param string $str + * @returns integer count of bytes written. + */ + private function append_str($str) + { + $this->check_closed(); + $this->string_buffer .= $str; + $len = strlen($str); + $this->current_index += $len; + return $len; + } + + /** + * Truncates the truncate buffer to 0 bytes and returns the pointer + * to the beginning of the buffer. + * @returns boolean true + */ + public function truncate() + { + $this->check_closed(); + $this->string_buffer = ''; + $this->current_index = 0; + return true; + } + + /** + * @returns int count of bytes in the buffer + * @internal Could probably memoize length for performance, but + * no need do this yet. + */ + public function length() { return strlen($this->string_buffer); } + + /** + * @returns string + */ + public function __toString() { return $this->string_buffer; } + + + /** + * @returns string + * @uses self::__toString() + */ + public function string() { return $this->__toString(); } + + /** + * @returns boolean true if this buffer is closed and false + * otherwise. + */ + public function is_closed() { return $this->is_closed; } +} + +/** + * AvroIO wrapper for PHP file access functions + * @package Avro + */ +class AvroFile extends AvroIO +{ + /** + * @var string fopen read mode value. Used internally. + */ + const FOPEN_READ_MODE = 'rb'; + + /** + * @var string fopen write mode value. Used internally. + */ + const FOPEN_WRITE_MODE = 'wb'; + + /** + * @var string + */ + private $file_path; + + /** + * @var resource file handle for AvroFile instance + */ + private $file_handle; + + public function __construct($file_path, $mode = self::READ_MODE) + { + /** + * XXX: should we check for file existence (in case of reading) + * or anything else about the provided file_path argument? + */ + $this->file_path = $file_path; + switch ($mode) + { + case self::WRITE_MODE: + $this->file_handle = fopen($this->file_path, self::FOPEN_WRITE_MODE); + if (false == $this->file_handle) + throw new AvroIOException('Could not open file for writing'); + break; + case self::READ_MODE: + $this->file_handle = fopen($this->file_path, self::FOPEN_READ_MODE); + if (false == $this->file_handle) + throw new AvroIOException('Could not open file for reading'); + break; + default: + throw new AvroIOException( + sprintf("Only modes '%s' and '%s' allowed. You provided '%s'.", + self::READ_MODE, self::WRITE_MODE, $mode)); + } + } + + /** + * @returns int count of bytes written + * @throws AvroIOException if write failed. + */ + public function write($str) + { + $len = fwrite($this->file_handle, $str); + if (false === $len) + throw new AvroIOException(sprintf('Could not write to file')); + return $len; + } + + /** + * @param int $len count of bytes to read. + * @returns string bytes read + * @throws AvroIOException if length value is negative or if the read failed + */ + public function read($len) + { + if (0 > $len) + throw new AvroIOException( + sprintf("Invalid length value passed to read: %d", $len)); + + if (0 == $len) + return ''; + + $bytes = fread($this->file_handle, $len); + if (false === $bytes) + throw new AvroIOException('Could not read from file'); + return $bytes; + } + + /** + * @returns int current position within the file + * @throws AvroFileExcpetion if tell failed. + */ + public function tell() + { + $position = ftell($this->file_handle); + if (false === $position) + throw new AvroIOException('Could not execute tell on reader'); + return $position; + } + + /** + * @param int $offset + * @param int $whence + * @returns boolean true upon success + * @throws AvroIOException if seek failed. + * @see AvroIO::seek() + */ + public function seek($offset, $whence = SEEK_SET) + { + $res = fseek($this->file_handle, $offset, $whence); + // Note: does not catch seeking beyond end of file + if (-1 === $res) + throw new AvroIOException( + sprintf("Could not execute seek (offset = %d, whence = %d)", + $offset, $whence)); + return true; + } + + /** + * Closes the file. + * @returns boolean true if successful. + * @throws AvroIOException if there was an error closing the file. + */ + public function close() + { + $res = fclose($this->file_handle); + if (false === $res) + throw new AvroIOException('Error closing file.'); + return $res; + } + + /** + * @returns boolean true if the pointer is at the end of the file, + * and false otherwise. + * @see AvroIO::is_eof() as behavior differs from feof() + */ + public function is_eof() + { + $this->read(1); + if (feof($this->file_handle)) + return true; + $this->seek(-1, self::SEEK_CUR); + return false; + } + + /** + * @returns boolean true if the flush was successful. + * @throws AvroIOException if there was an error flushing the file. + */ + public function flush() + { + $res = fflush($this->file_handle); + if (false === $res) + throw new AvroIOException('Could not flush file.'); + return true; + } + +}