public PageHeader ReadPageHeader(long position) { _stream.Seek(position, SeekOrigin.Begin); if (_stream.Read(_readBuffer, 0, 27) != 27) { return(null); } if (_readBuffer[0] != 79 || _readBuffer[1] != 103 || _readBuffer[2] != 103 || _readBuffer[3] != 83) { return(null); } if (_readBuffer[4] != 0) { return(null); } PageHeader pageHeader = new PageHeader(); pageHeader.Flags = (PageFlags)_readBuffer[5]; long num = BitConverter.ToInt32(_readBuffer, 6); long num2 = BitConverter.ToInt32(_readBuffer, 10); pageHeader.GranulePosition = num + (num2 << 32); pageHeader.StreamSerial = BitConverter.ToInt32(_readBuffer, 14); pageHeader.SequenceNumber = BitConverter.ToInt32(_readBuffer, 18); uint checkCrc = BitConverter.ToUInt32(_readBuffer, 22); _crc.Reset(); for (int i = 0; i < 22; i++) { _crc.Update(_readBuffer[i]); } _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(_readBuffer[26]); int num3 = _readBuffer[26]; if (_stream.Read(_readBuffer, 0, num3) != num3) { return(null); } List <int> list = new List <int>(num3); int num4 = 0; int num5 = 0; for (int j = 0; j < num3; j++) { byte b = _readBuffer[j]; _crc.Update(b); if (num5 == list.Count) { list.Add(0); } list[num5] += b; if (b < byte.MaxValue) { num5++; pageHeader.LastPacketContinues = false; } else { pageHeader.LastPacketContinues = true; } num4 += b; } pageHeader.PacketSizes = list.ToArray(); pageHeader.DataOffset = position + 27 + num3; if (_stream.Read(_readBuffer, 0, num4) != num4) { return(null); } for (int k = 0; k < num4; k++) { _crc.Update(_readBuffer[k]); } if (_crc.Test(checkCrc)) { _containerBits += 8 * (27 + num3); _pageCount++; return(pageHeader); } return(null); }
PageHeader ReadPageHeader(long position) { // set the stream's position _stream.Seek(position, SeekOrigin.Begin); // header // NB: if the stream didn't have an EOS flag, this is the most likely spot for the EOF to be found... if (_stream.Read(_readBuffer, 0, 27) != 27) { return(null); } // capture signature if (_readBuffer[0] != 0x4f || _readBuffer[1] != 0x67 || _readBuffer[2] != 0x67 || _readBuffer[3] != 0x53) { return(null); } // check the stream version if (_readBuffer[4] != 0) { return(null); } // start populating the header var hdr = new PageHeader(); // bit flags hdr.Flags = (PageFlags)_readBuffer[5]; // granulePosition hdr.GranulePosition = BitConverter.ToInt64(_readBuffer, 6); // stream serial hdr.StreamSerial = BitConverter.ToInt32(_readBuffer, 14); // sequence number hdr.SequenceNumber = BitConverter.ToInt32(_readBuffer, 18); // save off the CRC var crc = BitConverter.ToUInt32(_readBuffer, 22); // start calculating the CRC value for this page _crc.Reset(); for (int i = 0; i < 22; i++) { _crc.Update(_readBuffer[i]); } _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(_readBuffer[26]); // figure out the length of the page var segCnt = (int)_readBuffer[26]; if (_stream.Read(_readBuffer, 0, segCnt) != segCnt) { return(null); } var packetSizes = new List <int>(segCnt); int size = 0, idx = 0; for (int i = 0; i < segCnt; i++) { var temp = _readBuffer[i]; _crc.Update(temp); if (idx == packetSizes.Count) { packetSizes.Add(0); } packetSizes[idx] += temp; if (temp < 255) { ++idx; hdr.LastPacketContinues = false; } else { hdr.LastPacketContinues = true; } size += temp; } hdr.PacketSizes = packetSizes.ToArray(); hdr.DataOffset = position + 27 + segCnt; // now we have to go through every byte in the page if (_stream.Read(_readBuffer, 0, size) != size) { return(null); } for (int i = 0; i < size; i++) { _crc.Update(_readBuffer[i]); } if (_crc.Test(crc)) { _containerBits += 8 * (27 + segCnt); ++_pageCount; return(hdr); } return(null); }
private bool CheckPage(long pageOffset, out short packetCount, out long nextPageOffset) { if (DecodeHeader()) { // we have a potentially good page... check the CRC var crc = BitConverter.ToUInt32(_headerBuf, 22); var segCount = _headerBuf[26]; _crc.Reset(); for (var j = 0; j < 22; j++) { _crc.Update(_headerBuf[j]); } _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(segCount); // while we're here, count up the number of packets in the page var dataLen = 0; var pktLen = 0; short pktCnt = 0; for (var j = 0; j < segCount; j++) { var segLen = _headerBuf[27 + j]; _crc.Update(segLen); pktLen += segLen; dataLen += segLen; if (segLen < 255 || j == segCount - 1) { if (pktLen > 0) { ++pktCnt; pktLen = 0; } } } packetCount = pktCnt; // finish calculating the CRC _stream.Position = pageOffset + 27 + segCount; if (_stream.Read(_dataBuf, 0, dataLen) < dataLen) { // we're going to assume this means the stream has ended nextPageOffset = 0; return(false); } for (var j = 0; j < dataLen; j++) { _crc.Update(_dataBuf[j]); } if (_crc.Test(crc)) { // cool, we have a valid page! nextPageOffset = _stream.Position; PageOffset = pageOffset; PageCount++; ContainerBits += 8 * (27 + segCount); return(true); } } packetCount = 0; nextPageOffset = 0; return(false); }