/**
  * Parses data from a data buffer into an array representing a frame header
  *
  * @param \WebSocketServer\Socket\Buffer $buffer The data buffer
  *
  * @return bool True is a complete frame header was successfully parsed from the buffer
  *
  * @throws \RangeException When the frame is invalid
  */
 private function parseFrameHeader(Buffer $buffer)
 {
     if ($buffer->length() < 2) {
         return false;
     }
     $firstByte = ord($buffer->read(1, 0, Buffer::READ_PEEK));
     $fin = (bool) ($firstByte & 0b10000000);
     $rsv = ($firstByte & 0b1110000) >> 4;
     $opcode = $firstByte & 0b1111;
     $secondByte = ord($buffer->read(1, 1, Buffer::READ_PEEK));
     $masked = (bool) ($secondByte & 0b10000000);
     $lengthHeader = $secondByte & 0b1111111;
     $bytesProcessed = 2;
     if ($lengthHeader === 0x7f) {
         if ($buffer->length() < 10) {
             return false;
         }
         $lengthLong32Pair = unpack('NN', $buffer->read(8, 2, Buffer::READ_PEEK));
         $bytesProcessed += 8;
         if (PHP_INT_MAX === 0x7fffffff) {
             // Size of packets limited to 2.1GB on 32-bit platforms
             // TODO: fix this (although arguably a non-problem, this is a huge security flaw)
             if ($lengthLong32Pair[0] !== 0 || $lengthLong32Pair[1] < 0) {
                 $buffer->read(10);
                 throw new \RangeException('A frame was received that stated its payload length to be larger than 0x7fffffff bytes, this platform does not support values that large');
             }
             $length = $lengthLong32Pair[1];
         } else {
             $length = $lengthLong32Pair[0] << 32 | $lengthLong32Pair[1];
             if ($length < 0) {
                 throw new \RangeException('Invalid frame: Most significant bit of 64-bit length field set');
             }
         }
     } else {
         if ($lengthHeader === 0x7e) {
             if ($buffer->length() < 4) {
                 return false;
             }
             $length = current(unpack('n', $buffer->read(2, 2, Buffer::READ_PEEK)));
             $bytesProcessed += 2;
         } else {
             $length = $lengthHeader;
         }
     }
     if ($masked) {
         if ($buffer->length() < $bytesProcessed + 4) {
             return false;
         }
         $maskingKey = $buffer->read(4, $bytesProcessed, Buffer::READ_PEEK);
         $bytesProcessed += 4;
     } else {
         $maskingKey = null;
     }
     $buffer->read($bytesProcessed);
     $this->pendingFrameHeader = ['fin' => $fin, 'rsv' => $rsv, 'opcode' => $opcode, 'masked' => $masked, 'maskingKey' => $maskingKey, 'length' => $length];
     return true;
 }