/** * Add a stream to the AppendStream * * @param StreamInterface $stream Stream to append. Must be readable. * * @throws \InvalidArgumentException if the stream is not readable */ public function addStream(StreamInterface $stream) { if (!$stream->isReadable()) { throw new \InvalidArgumentException('Each stream must be readable'); } // The stream is only seekable if all streams are seekable if (!$stream->isSeekable()) { $this->seekable = false; } $this->streams[] = $stream; }
/** * counts frequency of all values from input stream in a private variable * * @param StreamInterface $input * @throws Exception */ public function updateFrequencyArray(StreamInterface $input) { while (!$input->streamEnded()) { $char = $input->getChar(); if ($char === false) { break; } if (PHP_INT_MAX == $this->frequencyTotal) { throw new Exception('the counts in the frequency array are about to exceed ' . PHP_INT_MAX); } $this->frequencyTotal++; if (isset($this->frequency[$char])) { $this->frequency[$char]++; } else { $this->frequency[$char] = 1; } } }
/** * In order to utilize high water marks to tell writers to slow down, the * provided stream must answer to the "hwm" stream metadata variable, * providing the high water mark. If no "hwm" metadata value is available, * then the "drain" functionality is not utilized. * * This class accepts an associative array of configuration options. * * - drain: (callable) Function to invoke when the stream has drained, * meaning the buffer is now writable again because the size of the * buffer is at an acceptable level (e.g., below the high water mark). * The function accepts a single argument, the buffer stream object that * has drained. * - pump: (callable) A function that accepts the number of bytes to read * from the source stream. This function will block until all of the data * that was requested has been read, EOF of the source stream, or the * source stream is closed. * - size: (int) The expected size in bytes of the data that will be read * (if known up-front). * * @param StreamInterface $buffer Buffer that contains the data that has * been read by the event loop. * @param array $config Associative array of options. * * @throws \InvalidArgumentException if the buffer is not readable and * writable. */ public function __construct(StreamInterface $buffer, array $config = []) { if (!$buffer->isReadable() || !$buffer->isWritable()) { throw new \InvalidArgumentException('Buffer must be readable and writable'); } if (isset($config['size'])) { $this->size = $config['size']; } static $callables = ['pump', 'drain']; foreach ($callables as $check) { if (isset($config[$check])) { if (!is_callable($config[$check])) { throw new \InvalidArgumentException($check . ' must be callable'); } $this->{$check} = $config[$check]; } } $this->hwm = $buffer->getMetadata('hwm'); // Cannot drain when there's no high water mark. if ($this->hwm === null) { $this->drain = null; } $this->stream = $buffer; }
public function stream_stat() { static $modeMap = ['r' => 33060, 'r+' => 33206, 'w' => 33188]; return ['dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0]; }
/** * Read a line from the stream up to the maximum allowed buffer length * * @param StreamInterface $stream Stream to read from * @param int $maxLength Maximum buffer length * * @return string|bool */ function read_line(StreamInterface $stream, $maxLength = null) { $buffer = ''; $size = 0; while (!$stream->eof()) { if (false === ($byte = $stream->read(1))) { return $buffer; } $buffer .= $byte; // Break when a new line is found or the max length - 1 is reached if ($byte == PHP_EOL || ++$size == $maxLength - 1) { break; } } return $buffer; }
/** * Calculate the BLAKE2b checksum of an entire stream * * @param StreamInterface $fileStream * @param Key $key * @param bool $raw * @return string * @throws CryptoException\InvalidKey */ protected static function checksumData(StreamInterface $fileStream, Key $key = null, bool $raw = false) : string { $config = self::getConfig(Halite::HALITE_VERSION_FILE, 'checksum'); if ($key instanceof AuthenticationKey) { $state = \Sodium\crypto_generichash_init($key->getRawKeyMaterial(), $config->HASH_LEN); } elseif ($config->CHECKSUM_PUBKEY && $key instanceof SignaturePublicKey) { // In version 2, we use the public key as a hash key $state = \Sodium\crypto_generichash_init($key->getRawKeyMaterial(), $config->HASH_LEN); } elseif (isset($key)) { throw new CryptoException\InvalidKey('Argument 2: Expected an instance of AuthenticationKey'); } else { $state = \Sodium\crypto_generichash_init('', $config->HASH_LEN); } $size = $fileStream->getSize(); while ($fileStream->remainingBytes() > 0) { // Don't go past the file size even if $config->BUFFER is not an even multiple of it: if ($fileStream->getPos() + $config->BUFFER > $size) { $amount_to_read = $size - $fileStream->getPos(); } else { $amount_to_read = $config->BUFFER; } $read = $fileStream->readBytes($amount_to_read); \Sodium\crypto_generichash_update($state, $read); } // Do we want a raw checksum? if ($raw) { return \Sodium\crypto_generichash_final($state, $config->HASH_LEN); } return \Sodium\bin2hex(\Sodium\crypto_generichash_final($state, $config->HASH_LEN)); }
/** * * @return bool */ public function valid() { return !$this->stream->eof(); }
/** * Calculate the BLAKE2b checksum of the contents of a file * * @param StreamInterface $fileStream * @param Key $key * @param mixed $encoding Which encoding scheme to use for the checksum? * @return string * @throws InvalidKey */ protected static function checksumData(StreamInterface $fileStream, Key $key = null, $encoding = Halite::ENCODE_BASE64URLSAFE) : string { $config = self::getConfig(Halite::HALITE_VERSION_FILE, 'checksum'); // 1. Initialize the hash context if ($key instanceof AuthenticationKey) { // AuthenticationKey is for HMAC, but we can use it for keyed hashes too $state = \Sodium\crypto_generichash_init($key->getRawKeyMaterial(), $config->HASH_LEN); } elseif ($config->CHECKSUM_PUBKEY && $key instanceof SignaturePublicKey) { // In version 2, we use the public key as a hash key $state = \Sodium\crypto_generichash_init($key->getRawKeyMaterial(), $config->HASH_LEN); } elseif (isset($key)) { throw new InvalidKey('Argument 2: Expected an instance of AuthenticationKey or SignaturePublicKey'); } else { $state = \Sodium\crypto_generichash_init('', $config->HASH_LEN); } // 2. Calculate the hash $size = $fileStream->getSize(); while ($fileStream->remainingBytes() > 0) { // Don't go past the file size even if $config->BUFFER is not an even multiple of it: if ($fileStream->getPos() + $config->BUFFER > $size) { $amount_to_read = $size - $fileStream->getPos(); } else { $amount_to_read = $config->BUFFER; } $read = $fileStream->readBytes($amount_to_read); \Sodium\crypto_generichash_update($state, $read); } // 3. Do we want a raw checksum? $encoder = Halite::chooseEncoder($encoding); if ($encoder) { return $encoder(\Sodium\crypto_generichash_final($state, $config->HASH_LEN)); } return \Sodium\crypto_generichash_final($state, $config->HASH_LEN); }