%PDF- %PDF-
Direktori : /www/varak.net/wiki.varak.net/vendor/wikimedia/avro/lib/avro/ |
Current File : //www/varak.net/wiki.varak.net/vendor/wikimedia/avro/lib/avro/io.php |
<?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 * * http://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. */ /** * Avro IO object classes * @package Avro */ /** * Exceptions associated with AvroIO instances. * @package Avro */ class AvroIOException extends AvroException {} /** * Barebones IO base class to provide common interface for file and string * access within the Avro classes. * * @package Avro */ class AvroIO { /** * @var string general read mode */ const READ_MODE = 'r'; /** * @var string general write mode. */ const WRITE_MODE = 'w'; /** * @var int set position equal to $offset bytes */ const SEEK_CUR = SEEK_CUR; /** * @var int set position to current index + $offset bytes */ const SEEK_SET = SEEK_SET; /** * @var int set position to end of file + $offset bytes */ const SEEK_END = SEEK_END; /** * Read $len bytes from AvroIO instance * @var int $len * @return string bytes read */ public function read($len) { throw new AvroNotImplementedException('Not implemented'); } /** * 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) { throw new AvroNotImplementedException('Not implemented'); } /** * Return byte offset within AvroIO instance * @return int */ public function tell() { throw new AvroNotImplementedException('Not implemented'); } /** * Set the position indicator. The new position, measured in bytes * from the beginning of the file, is obtained by adding $offset to * the position specified by $whence. * * @param int $offset * @param int $whence one of AvroIO::SEEK_SET, AvroIO::SEEK_CUR, * or Avro::SEEK_END * @returns boolean true * * @throws AvroIOException */ public function seek($offset, $whence=self::SEEK_SET) { throw new AvroNotImplementedException('Not implemented'); } /** * Flushes any buffered data to the AvroIO object. * @returns boolean true upon success. */ public function flush() { throw new AvroNotImplementedException('Not implemented'); } /** * Returns whether or not the current position at the end of this AvroIO * instance. * * Note is_eof() is <b>not</b> 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; } }