/// <inheritdoc/> public byte ReadByte(long index) { byte ret; if (!cache.TryReadByte(index, out ret)) { ByteCache.FillCache callback = delegate(byte[] buffer, out long cacheStart, out int cacheLength) { // the file is more likely to be read from the beginning to the end cacheStart = Math.Max(0, index - 512); cacheLength = (int)Math.Min(buffer.Length, stream.Length - cacheStart); try { stream.ReadBytesToBuffer(buffer, cacheStart, cacheLength); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } ret = buffer[index - cacheStart]; }; cache.Cache(callback); } return(ret); }
public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { IDataStreamHelpers.ReadBytesToBufferArgsCheck(this, buffer, start, ref length, offset); while (length > 0) { var off = start % fullChunkSize; int read; if (off < chunkStart.Length) { read = (int)Math.Min(length, chunkStart.Length - off); chunkStart.ReadBytesToBuffer(buffer, off, read, offset); } else if (off > fullChunkSize - 3) { read = (int)Math.Min(length, fullChunkSize - off); chunkEnd.ReadBytesToBuffer(buffer, off - (fullChunkSize - 2), read, offset); } else { var chunk = start / fullChunkSize; off -= chunkStart.Length; read = (int)Math.Min(length, chunkSize - off); innerStream.ReadBytesToBuffer(buffer, chunk * chunkSize + off, read, offset); } length -= read; offset += read; start += read; } }
/// <inheritdoc/> public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { IDataStreamHelpers.ReadBytesToBufferArgsCheck(this, buffer, start, ref length, offset); innerStream.ReadBytesToBuffer(buffer, start, length, offset); for (long i = 0; i < length; ++i) { buffer[offset + i] = (byte)(buffer[offset + i] ^ mask[(start + i) % 4]); } }
/// <inheritdoc/> public override int Read(byte[] buffer, int offset, int count) { int len = Math.Min(count, (int)(Math.Min(int.MaxValue, stream.Length - (position + offset)))); if (len > 0) { stream.ReadBytesToBuffer(buffer, position + offset, len); position += len; } return(len); }
/// <summary> /// Reads bytes and returns them as a byte array. This method must perform a copy. /// </summary> /// <param name="s"></param> /// <inheritdoc cref="IDataStream.ReadBytesToBuffer" select="param[@name='start']|param[@name='length']|exception"/> /// <inheritdoc cref="IDataStreamHelpers.ReadBytesToBufferArgsCheck" select="exception"/> public static byte[] ReadBytes(this IDataStream s, long start = 0, int length = -1) { if (length == -1) { length = (int)Math.Min(int.MaxValue, s.Length - start); } var ret = new byte[length]; s.ReadBytesToBuffer(ret, start, length); return(ret); }
/// <inheritdoc/> public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { IDataStreamHelpers.ReadBytesToBufferArgsCheck(this, buffer, start, ref length, offset); if (length == -1) { length = (int)Math.Min(int.MaxValue, Length - start); } if (start + length > count || start < 0 || length < 0) { throw new ArgumentOutOfRangeException("wrong index or length"); } stream.ReadBytesToBuffer(buffer, this.offset + start, length, offset); }
public static void Send(Socket socket, IDataStream stream) { if (stream.Length < socket.SendBufferSize) { socket.Send(stream.ReadBytes()); } else { var buffer = new byte[socket.SendBufferSize]; var remaining = stream.Length; long start = 0; while (remaining > 0) { var read = (int)Math.Min(remaining, buffer.Length); stream.ReadBytesToBuffer(buffer, start, read); start += read; remaining -= read; socket.Send(buffer, read, SocketFlags.None); } } }
/// <inheritdoc/> public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { MessageData.ReadBytesToBuffer(buffer, start, length, offset); }
/// <summary> /// Parse the header from data stream /// </summary> /// <param name="s"></param> /// <returns>length of missing payload data (negative if there are more data than neccessary)</returns> public long ParseHeader(IDataStream s) { headerLength = 2; var len = s.Length; if (len < 2) { throw new ArgumentException("Stream too short to contain the header!"); } byte b1, b2; b1 = s.ReadByte(0); b2 = s.ReadByte(1); msg.FIN = (b1 & 0x80) == 0x80; msg.RSV1 = (b1 & 0x40) == 0x40; msg.RSV2 = (b1 & 0x20) == 0x20; msg.RSV3 = (b1 & 0x10) == 0x10; msg.Opcode = (OpcodeType)(b1 & 0x0F); msg.MASK = (b2 & 0x80) == 0x80; msg.PayloadLength = b2 & ~0x80; byte[] buffer; if (msg.PayloadLength == 126) { if (len < 4) { throw new ArgumentException("Stream too short to contain the header!"); } buffer = new byte[2]; s.ReadBytesToBuffer(buffer, 2, 2); if (BitConverter.IsLittleEndian) { b1 = buffer[0]; buffer[0] = buffer[1]; buffer[1] = b1; } msg.PayloadLength = BitConverter.ToUInt16(buffer, 0); headerLength += 2; } else if (msg.PayloadLength == 127) { if (len < 10) { throw new ArgumentException("Stream too short to contain the header!"); } buffer = new byte[8]; s.ReadBytesToBuffer(buffer, 2, 8); if (BitConverter.IsLittleEndian) { Array.Reverse(buffer); } // lets hope no one will ever send a websocket message that long that this actually matters. msg.PayloadLength = (long)BitConverter.ToUInt64(buffer, 0); headerLength += 8; } if (msg.MASK) { buffer = new byte[4]; s.ReadBytesToBuffer(buffer, headerLength, 4); msg.MaskingKey = buffer; headerLength += 4; } return(headerLength + msg.PayloadLength - len); }
/// <inheritdoc/> public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { binaryStream.ReadBytesToBuffer(buffer, start, length, offset); }
/// <summary> /// Append data to file /// </summary> /// <param name="hint">as returned from FileLog.CreateFile or FileLogReader.GetFileHint</param> /// <param name="input">data to append</param> /// <remarks> /// Note that this function only appends data, eg. be careful not to pass more data into it. /// For example if you incrementaly add data to a StreamList don't pass the whole list each time, but only new data. /// </remarks> public void AppendDataToFile(LoggedFileInfo hint, IDataStream input) { long remaining = input.Length; if (remaining == 0) { return; } lock (streamLock) { var initialPos = stream.Position; if (blockBuffer == null) { blockBuffer = new byte[BlockSize]; } stream.Position = hint.Hint; long size = binReader.ReadInt64(); // stream position is now the beginning of FBT long blockOffset = size % BlockSize; long fbt2Offset = (size / (BlockSize)) % (FilesPerBlock + 1); long fbtOffset = size / (BlockSize * (FilesPerBlock + 1)) + 1; // locate correct FBT while (fbtOffset > FilesPerBlock) { // move to the next table long nextFBT = binReader.ReadInt64(); if (nextFBT == 0) { nextFBT = createNewFBT(stream.Position - sizeof(long)); } stream.Position = nextFBT; fbtOffset -= FilesPerBlock; } long currentFBT = stream.Position; while (remaining > 0) { while (fbtOffset <= FilesPerBlock) { stream.Position = currentFBT + fbtOffset * sizeof(long); long currentFBT2 = binReader.ReadInt64(); if (currentFBT2 == 0) { stream.Position -= sizeof(long); binWriter.Write(stream.Length); currentFBT2 = stream.Length; stream.Position = stream.Length; writeNewTable(); } while (fbt2Offset <= FilesPerBlock) { int bytesRead = (int)Math.Min(BlockSize - blockOffset, remaining); input.ReadBytesToBuffer(blockBuffer, input.Length - remaining, bytesRead); stream.Position = currentFBT2 + fbt2Offset * sizeof(long); long currentBlock = binReader.ReadInt64(); if (currentBlock == 0) { stream.Position -= sizeof(long); binWriter.Write(stream.Length); stream.Position = stream.Length; // blockBuffer is exactly blockSize bytes long // so don't call writeNewTable() to avoid unnecessary writes // extra data written to the block will be ovewritten later or not used at all binWriter.Write(blockBuffer); } else { stream.Position = currentBlock + blockOffset; binWriter.Write(blockBuffer, 0, bytesRead); } blockOffset = 0; remaining -= bytesRead; if (remaining == 0) { stream.Position = hint.Hint; binWriter.Write(size + input.Length); stream.Flush(); stream.Position = initialPos; return; } // otherwise the current block has been filled completely ++fbt2Offset; } fbt2Offset = 0; fbtOffset++; } fbtOffset = 1; currentFBT = createNewFBT(currentFBT); } // unreachable throw new InvalidOperationException("There is something terribly wrong - more bytes were written than it was supposed to."); } }