Add Zend_Io package proposal
git-svn-id: http://php-reader.googlecode.com/svn/branches/zend@151 51a70ab9-7547-0410-9469-37e369ee0574
This commit is contained in:
624
src/Zend/Io/Writer.php
Normal file
624
src/Zend/Io/Writer.php
Normal file
@@ -0,0 +1,624 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Io
|
||||
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Zend_Io_Writer class represents a character stream providing means to
|
||||
* write primitive types (string, integers, ...) to it.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Io
|
||||
* @author Sven Vollbehr <sven@vollbehr.eu>
|
||||
* @author Ryan Butterfield <buttza@gmail.com>
|
||||
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
class Zend_Io_Writer
|
||||
{
|
||||
const MACHINE_ENDIAN_ORDER = 0;
|
||||
const LITTLE_ENDIAN_ORDER = 1;
|
||||
const BIG_ENDIAN_ORDER = 2;
|
||||
|
||||
/**
|
||||
* The endianess of the current machine.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private static $_endianess = 0;
|
||||
|
||||
/**
|
||||
* The resource identifier of the stream.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $_fd = null;
|
||||
|
||||
/**
|
||||
* Size of the underlying stream.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_size = 0;
|
||||
|
||||
/**
|
||||
* Constructs the Zend_Io_Writer class with given open file descriptor.
|
||||
*
|
||||
* @param resource $fd The file descriptor.
|
||||
* @throws Zend_Io_Exception if file descriptor is not valid
|
||||
*/
|
||||
public function __construct($fd)
|
||||
{
|
||||
if (!is_resource($fd) ||
|
||||
!in_array(get_resource_type($fd), array('stream'))) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Invalid resource type (only resources of type stream are supported)');
|
||||
}
|
||||
|
||||
$this->_fd = $fd;
|
||||
|
||||
$offset = $this->getOffset();
|
||||
fseek($this->_fd, 0, SEEK_END);
|
||||
$this->_size = ftell($this->_fd);
|
||||
fseek($this->_fd, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default destructor.
|
||||
*/
|
||||
public function __destruct() {}
|
||||
|
||||
/**
|
||||
* Returns the current point of operation.
|
||||
*
|
||||
* @return integer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
if ($this->_fd === null) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Cannot operate on a closed stream');
|
||||
}
|
||||
return ftell($this->_fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the point of operation, ie the cursor offset value. The offset may
|
||||
* also be set to a negative value when it is interpreted as an offset from
|
||||
* the end of the stream instead of the beginning.
|
||||
*
|
||||
* @param integer $offset The new point of operation.
|
||||
* @return void
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function setOffset($offset)
|
||||
{
|
||||
if ($this->_fd === null) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Cannot operate on a closed stream');
|
||||
}
|
||||
fseek($this->_fd, $offset < 0 ? $this->getSize() + $offset : $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream size in bytes.
|
||||
*
|
||||
* @return integer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
if ($this->_fd === null) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Cannot operate on a closed stream');
|
||||
}
|
||||
return $this->_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stream size in bytes, and truncates if required.
|
||||
*
|
||||
* @param integer $size The new size
|
||||
* @return void
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function setSize($size)
|
||||
{
|
||||
if ($this->_fd === null) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Cannot operate on a closed stream');
|
||||
}
|
||||
ftruncate($this->_fd, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying stream file descriptor.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getFileDescriptor()
|
||||
{
|
||||
return $this->_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <var>value</var> up to <var>length</var> bytes to the stream.
|
||||
*
|
||||
* @param string $value The value to write to the stream.
|
||||
* @param integer $length The number of bytes to write. Defaults to the
|
||||
* length of the given value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function write($value, $length = null)
|
||||
{
|
||||
if ($this->_fd === null) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Cannot operate on a closed stream');
|
||||
}
|
||||
fwrite($this->_fd, $value, $length === null ? strlen($value) : $length);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an 8-bit integer as binary data to the stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt8($value)
|
||||
{
|
||||
return $this->write(pack('c*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an unsigned 8-bit integer as binary data to the stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeUInt8()
|
||||
{
|
||||
return $this->write(pack('C*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns signed 16-bit integer as machine endian ordered binary data.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return string
|
||||
*/
|
||||
private function _toInt16($value)
|
||||
{
|
||||
return pack('s*', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed 16-bit integer as little-endian ordered binary data to
|
||||
* the stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt16LE($value)
|
||||
{
|
||||
if ($this->_isBigEndian()) {
|
||||
return $this->write(strrev($this->_toInt16($value)));
|
||||
} else {
|
||||
return $this->write($this->_toInt16($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns signed 16-bit integer as big-endian ordered binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt16BE($value)
|
||||
{
|
||||
if ($this->_isLittleEndian()) {
|
||||
return $this->write(strrev($this->_toInt16($value)));
|
||||
} else {
|
||||
return $this->write($this->_toInt16($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes unsigned 16-bit integer as little-endian ordered binary data
|
||||
* to the stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeUInt16LE($value)
|
||||
{
|
||||
return $this->write(pack('v*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes unsigned 16-bit integer as big-endian ordered binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeUInt16BE($value)
|
||||
{
|
||||
return $this->write(pack('n*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns signed 32-bit integer as machine-endian ordered binary data.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return string
|
||||
*/
|
||||
private final function _toInt32($value)
|
||||
{
|
||||
return pack('l*', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes signed 32-bit integer as little-endian ordered binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt32LE($value)
|
||||
{
|
||||
if ($this->_isBigEndian()) {
|
||||
return $this->write(strrev($this->_toInt32($value)));
|
||||
} else {
|
||||
return $this->write($this->_toInt32($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes signed 32-bit integer as big-endian ordered binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt32BE($value)
|
||||
{
|
||||
if ($this->_isLittleEndian()) {
|
||||
return $this->write(strrev($this->_toInt32($value)));
|
||||
} else {
|
||||
return $this->write($this->_toInt32($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes unsigned 32-bit integer as little-endian ordered binary data to
|
||||
* the stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeUInt32LE($value)
|
||||
{
|
||||
return $this->write(pack('V*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes unsigned 32-bit integer as big-endian ordered binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeUInt32BE($value)
|
||||
{
|
||||
return $this->write(pack('N*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes 64-bit float as little-endian ordered binary data string to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt64LE($value)
|
||||
{
|
||||
return $this->write(pack('V*', $value & 0xffffffff, $value / (0xffffffff+1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes 64-bit float as big-endian ordered binary data string to the
|
||||
* stream.
|
||||
*
|
||||
* @param integer $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeInt64BE($value)
|
||||
{
|
||||
return $this->write(pack('N*', $value / (0xffffffff+1), $value & 0xffffffff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a floating point number as machine endian ordered binary data.
|
||||
*
|
||||
* @param float $value The input value.
|
||||
* @return string
|
||||
*/
|
||||
private function _toFloat($value)
|
||||
{
|
||||
return pack('f*', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a floating point number as little-endian ordered binary data to
|
||||
* the stream.
|
||||
*
|
||||
* @param float $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeFloatLE($value)
|
||||
{
|
||||
if ($this->_isBigEndian()) {
|
||||
return $this->write(strrev($this->_toFloat($value)));
|
||||
} else {
|
||||
return $this->write($this->_toFloat($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a floating point number as big-endian ordered binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param float $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeFloatBE($value)
|
||||
{
|
||||
if ($this->_isLittleEndian()) {
|
||||
return $this->write(strrev($this->_toFloat($value)));
|
||||
} else {
|
||||
return $this->write($this->_toFloat($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes string as binary data padded to given length with zeros. If
|
||||
* <var>length</var> is smaller than the length of the string, it is
|
||||
* considered as the length of the padding.
|
||||
*
|
||||
* @param string $value The input value.
|
||||
* @param integer $length The length to which to pad the value.
|
||||
* @param string $padding The padding character.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeString8($value, $length = null, $padding = "\0")
|
||||
{
|
||||
if ($length === null) {
|
||||
$length = strlen($value);
|
||||
}
|
||||
if ($length < ($tmp = strlen($value))) {
|
||||
$length = $tmp + $length;
|
||||
}
|
||||
return $this->write(str_pad($value, $length, $padding));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the multibyte string as binary data with given byte order mark
|
||||
* (BOM) and padded to given length with zeros. Length is given in unicode
|
||||
* characters so each character adds two zeros to the string. If length is
|
||||
* smaller than the length of the string, it is considered as the length of
|
||||
* the padding.
|
||||
*
|
||||
* If byte order mark is <var>null</var> no mark is inserted to the binary
|
||||
* data.
|
||||
*
|
||||
* @param string $value The input value.
|
||||
* @param integer $order The byte order of the binary data string.
|
||||
* @param integer $length The length to which to pad the value.
|
||||
* @param string $padding The padding character.
|
||||
* @return string
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeString16
|
||||
($value, $order = null, $length = null, $padding = "\0")
|
||||
{
|
||||
if ($length === null) {
|
||||
$length = (int)(strlen($value) / 2);
|
||||
}
|
||||
if ($length < ($tmp = strlen($value) / 2)) {
|
||||
$length = $tmp + $length;
|
||||
}
|
||||
if ($order == self::BIG_ENDIAN_ORDER &&
|
||||
!(ord($value[0]) == 0xfe && ord($value[1]) == 0xff)) {
|
||||
$value = 0xfeff . $value;
|
||||
$length++;
|
||||
}
|
||||
if ($order == self::LITTLE_ENDIAN_ORDER &&
|
||||
!(ord($value[0]) == 0xff && ord($value[1]) == 0xfe)) {
|
||||
$value = 0xfffe . $value;
|
||||
$length++;
|
||||
}
|
||||
return $this->write(str_pad($value, $length * 2, $padding));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes hexadecimal string having high nibble first as binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param string $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if <var>length</var> attribute is negative or
|
||||
* if the stream is closed
|
||||
*/
|
||||
public final function writeHHex($length)
|
||||
{
|
||||
return $this->write(pack('H*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes hexadecimal string having low nibble first as binary data to the
|
||||
* stream.
|
||||
*
|
||||
* @param string $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if <var>length</var> attribute is negative or
|
||||
* if the stream is closed
|
||||
*/
|
||||
public final function writeLHex($length)
|
||||
{
|
||||
return $this->write(pack('h*', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes big-endian ordered hexadecimal GUID string as little-endian
|
||||
* ordered binary data string to the stream.
|
||||
*
|
||||
* @param string $value The input value.
|
||||
* @return Zend_Io_Writer
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public final function writeGuid()
|
||||
{
|
||||
$string = '';
|
||||
$C = preg_split('/-/', $value);
|
||||
return $this->write
|
||||
(pack
|
||||
('V1v2N2', hexdec($C[0]), hexdec($C[1]), hexdec($C[2]),
|
||||
hexdec($C[3] . substr($C[4], 0, 4)), hexdec(substr($C[4], 4))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces write of all buffered output to the underlying resource.
|
||||
*
|
||||
* @return void
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
if ($this->_fd === null) {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Cannot operate on a closed stream');
|
||||
}
|
||||
fflush($this->_fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream. Once a stream has been closed, further calls to write
|
||||
* methods will throw an exception. Closing a previously-closed stream,
|
||||
* however, has no effect.
|
||||
*
|
||||
* @return void
|
||||
* @throws Zend_Io_Exception if the stream is closed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if ($this->_fd !== null) {
|
||||
@fclose($this->_fd);
|
||||
$this->_fd = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current machine endian order.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function _getEndianess()
|
||||
{
|
||||
if (self::$_endianess === 0) {
|
||||
self::$_endianess = $this->_toInt32("\x01\x00\x00\x00") == 1 ?
|
||||
self::LITTLE_ENDIAN_ORDER : self::BIG_ENDIAN_ORDER;
|
||||
}
|
||||
return self::$_endianess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current machine endian order is little endian.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function _isLittleEndian()
|
||||
{
|
||||
return $this->_getEndianess() == self::LITTLE_ENDIAN_ORDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current machine endian order is big endian.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function _isBigEndian()
|
||||
{
|
||||
return $this->_getEndianess() == self::BIG_ENDIAN_ORDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic function so that $obj->value will work.
|
||||
*
|
||||
* @param string $name The field name.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (method_exists($this, 'get' . ucfirst(strtolower($name)))) {
|
||||
return call_user_func
|
||||
(array($this, 'get' . ucfirst(strtolower($name))));
|
||||
} else {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Unknown field: ' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic function so that assignments with $obj->value will work.
|
||||
*
|
||||
* @param string $name The field name.
|
||||
* @param string $value The field value.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (method_exists($this, 'set' . ucfirst(strtolower($name)))) {
|
||||
call_user_func
|
||||
(array($this, 'set' . ucfirst(strtolower($name))), $value);
|
||||
} else {
|
||||
require_once('Zend/Io/Exception.php');
|
||||
throw new Zend_Io_Exception('Unknown field: ' . $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user