Я написал класс-оболочку вокруг байтового потока, чтобы поочередно читать этот поток (битовые массивы), используя этот метод:
public function readBits($len) {
if($len === 0) {
return 0;
}
if($this->nextbyte === null) {
//no byte has been started yet
if($len % 8 == 0) {
//don't start a byte with the cache, even number of bytes
$ret = 0;
//just return byte count not bit count
$len /= 8;
while ($len--) {
if($this->bytestream->eof()) {
//no more bytes
return false;
}
$byte = $this->bytestream->readByte();
$ret = ($ret << 8) | ord($byte);
}
return $ret;
} else {
$this->nextbyte = ord($this->bytestream->readByte());
$this->byteshift = 0;
}
}
if($len <= 8 && $this->byteshift + $len <= 8) {
//get the bitmask e.g. 00000111 for 3
$bitmask = self::$includeBitmask[$len - 1];
//can be satisfied with the remaining bits
$ret = $this->nextbyte & $bitmask;
//shift by len
$this->nextbyte >>= $len;
$this->byteshift += $len;
} else {
//read the remaining bits first
$bitsremaining = 8 - $this->byteshift;
$ret = $this->readBits($bitsremaining);
//decrease len by the amount bits remaining
$len -= $bitsremaining;
//set the internal byte cache to null
$this->nextbyte = null;
if($len > 8) {
//read entire bytes as far as possible
for ($i = intval($len / 8); $i > 0; $i--) {
if($this->bytestream->eof()) {
//no more bytes
return false;
}
$byte = $this->bytestream->readByte();
$ret = ($ret << 8) | ord($byte);
}
//reduce len to the rest of the requested number
$len = $len % 8;
}
//read a new byte to get the rest required
$newbyte = $this->readBits($len);
$ret = ($ret << $len) | $newbyte;
}
if($this->byteshift === 8) {
//delete the cached byte
$this->nextbyte = null;
}
return $ret;
}
Это позволяет мне читать битовые массивы произвольной длины из моего потока байтов, которые возвращаются в целых числах (так как php не имеет целых чисел со знаком).
Проблема появляется, когда я пытаюсь прочитать битовый массив размером более 64 бит, и я предполагаю, что если бы я использовал класс в 32-битной системе, проблема возникла бы уже с 32-битными массивами.
Проблема в том, что возвращаемое значение, очевидно, слишком велико, чтобы его можно было хранить в целом числе, поэтому оно переходит в отрицательное целое число.
Мой вопрос сейчас заключается в том, что будет лучшим способом справиться с этим. Я могу думать о:
Есть ли что-то, что я упустил по этому поводу, или один из упомянутых вариантов на самом деле является лучшим способом решения этой проблемы?
заранее спасибо за помощь
Задача ещё не решена.
Других решений пока нет …