public void Init() { this.RawData = this.ReadBinaries(); this.IpRanges = this.GetEmptyRangesIps(this.RawData.IpRangesCount); this.Locations = this.GetEmptyLocations(this.RawData.LocationsCount); var ipRanges = this.IpRanges; var locations = this.Locations; BinaryReaderHelper.RawDeserializerList <IpRange>( this.RawData.IpRangesBytes, this.RawData.IpRangesCount, Marshal.SizeOf <IpRange>(), ref ipRanges); BinaryReaderHelper.RawDeserializerList <Location>( this.RawData.LocationsBytes, this.RawData.LocationsCount, Marshal.SizeOf <Location>(), ref locations); IpRanges = ipRanges; Locations = locations; InitIndexes(); OnIndexesCreated?.Invoke(); }
public ArraySegment <byte> ReadValue(int length) { Trace.Assert(length <= Int32.MaxValue - 2); m_buffer.EnsureCapacity(length + 2); BinaryReaderHelper.ReadTo(m_reader, m_buffer.Array, 0, length + 2); return(new ArraySegment <byte>(m_buffer.Array, 0, length)); }
private int ReadLine() { var position = BinaryReaderHelper.ReadToken(m_reader, m_buffer.Array, 0, m_buffer.Capacity, token => token == 0x0A); if (position == -1) { throw new InvalidOperationException("End of line not found"); } return(--position); }
private int ReadToken() { var position = BinaryReaderHelper.ReadToken(m_reader, m_buffer.Array, 0, m_buffer.Capacity, token => token == 0x20 || token == 0x0A); if (position == -1) { throw new InvalidOperationException("Token not found"); } if (m_buffer.Array[position] == 0x0A) { position--; } return(position); }
public ResponseStatus ReadStatus() { var buffer = m_buffer.Array; BinaryReaderHelper.ReadTo(m_reader, buffer, 0, Offset.EndOfHeader); var totalLength = BigEndianConverter.GetInt32(buffer, Offset.TotalBodyLength); m_buffer.EnsureCapacity(Offset.EndOfHeader + totalLength); BinaryReaderHelper.ReadTo(m_reader, buffer, Offset.EndOfHeader, totalLength); var status = (ResponseStatus)m_buffer.Array[Offset.Status]; if (status == ResponseStatus.NoError) { if (buffer[Offset.OperationCode] == 0x00) { status = ResponseStatus.Value; } } return(status); }
/// <summary> /// BinaryReader.BaseStream position is preserved in cases other than Continue /// </summary> /// <param name="br"> /// A <see cref="BinaryReader"/> /// </param> /// <returns> /// A <see cref="ProcessStatus"/> /// ProcessStatus.Error if any errors are detected, the stream position /// is restored to the starting position /// ProcessStatus.NeedMoreData if we run into a situation where there isn't /// enough data to continue processing. Stream position is at the position /// where the internal state machine is waiting to resume when additional /// data arrives /// </returns> public ProcessStatus Process(BinaryReader br) { if (IsDebugEnabled) { Log.Debug(""); } string line; HttpMessage.ProcessStatus processStatus; while (true) { // the request response and header phases work in terms of lines, // terminated by /r/n, this is different from the body phase that // is a blob of bytes if "Content-Length" was set in the headers, or // chunked mode if "Transfer-Encoding" was set in the headers if ((Phase == Phases.RequestResponse) || (Phase == Phases.Headers) || (Phase == Phases.BodyChunkedLength) || (Phase == Phases.BodyChunkSeparator)) { if (IsDebugEnabled) { Log.Debug("Line reading phase"); } // save the starting position so we can restore if we don't have // enough bytes long startingPosition = br.BaseStream.Position; // read the next line from the binary reader var readNextLine = BinaryReaderHelper.ReadNextLineFromBinaryReader(br, out line); if (IsDebugEnabled) { Log.Debug("readNextLine {0}, line of '{1}'", readNextLine, line); } // NOTE: Because we ensure that we have a string that was properly terminated by // crlf we can consider 'Needs`MoreData' cases inside of this if() to be // errors if (readNextLine == BinaryReaderHelper.ReadNextLineResponses.StringTerminatedByCrLf) { if (Phase == Phases.RequestResponse) { if (IsDebugEnabled) { Log.Debug("Phase == Phases.RequestResponse"); } processStatus = ProcessRequestResponseFirstLineHandler(line); if (processStatus == ProcessStatus.Error) { Log.Debug("ProcessStatus.Error() from ProcessRequestResponseFirstLineHandler()"); // rewind to the starting position br.BaseStream.Position = startingPosition; return(ProcessStatus.Error); } else if (processStatus == ProcessStatus.Complete) { Log.Debug("status == ProcessStatus.Compete, moving to Phases.Headers"); // done with the request/response first line handler // move to the next phase phase = Phases.Headers; } else { // make sure to catch any unexpected status return values throw new System.InvalidOperationException("Unexpected processStatus of " + processStatus + " returned by ProcessRequestResponseFirstLineHandler()"); } } else if (Phase == Phases.Headers) { if (IsDebugEnabled) { Log.Debug("Phase == Phases.Headers"); } processStatus = ProcessHeaders(line); if (processStatus == ProcessStatus.Error) { Log.Debug("ProcessStatus.Error from ProcessHeaders(), moving back to startingPosition and returning ProcessStatus.Error"); // rewind to the starting position br.BaseStream.Position = startingPosition; return(ProcessStatus.Error); } else if (processStatus == ProcessStatus.Complete) { if (IsDebugEnabled) { Log.Debug("Done with headers"); } // done with headers // if we have a content length then move to Phases.Body // otherwise we are done with the request if (ContentLength != -1) { if (IsDebugEnabled) { Log.Debug("ContentLength is {0}, moving to Body phase", ContentLength); } phase = Phases.Body; } else if (TransferEncoding == "chunked") { if (IsDebugEnabled) { Log.Debug("TransferEncoding chunked, moving to Phases.BodyChunkedLength"); } phase = Phases.BodyChunkedLength; } else { // we are all done, no data follows the headers if (IsDebugEnabled) { Log.Debug("returning ProcessStatus.Complete"); } return(ProcessStatus.Complete); } } else if (processStatus == ProcessStatus.Continue) { if (IsDebugEnabled) { Log.Debug("ProcessHeaders() returned 'Continue'"); } } else { // make sure to catch any unexpected status return values throw new System.InvalidOperationException("Unexpected processStatus of " + processStatus + " returned by ProcessHeaders()"); } } else if (Phase == Phases.BodyChunkedLength) { if (IsDebugEnabled) { Log.Debug("Phase == Phases.BodyChunkedLength"); } processStatus = PhaseBodyChunkLength(line); if (processStatus != ProcessStatus.Continue) { return(processStatus); } } else if (Phase == Phases.BodyChunkSeparator) { if (IsDebugEnabled) { Log.Debug("Phase == Phases.BodyChunkSeparator"); } // we expect the line to be empty if (line != String.Empty) { Log.Error("Expected a line that was String.Empty in the BodyChunkSeparator state but instead got '" + line + "'"); return(ProcessStatus.Error); } // if the ChunkLength is 0 then we are all done with the chunked data if (ChunkLength == 0) { Log.Debug("Found ChunkLength of zero, decoding content and returning ProcessStatus.Complete"); // we have the entire body, decode the content DecodeContent(); return(ProcessStatus.Complete); } else // we have more chunks pending { // go back to the BodyChunkedLength phase if (IsDebugEnabled) { Log.Debug("Going back to Phases.BodyChunkedLength"); } phase = Phases.BodyChunkedLength; } } } else if (readNextLine == BinaryReaderHelper.ReadNextLineResponses.NonAsciiCharacterFound) { if (IsDebugEnabled) { Log.Debug("found a non-ascii character, this appears to be a binary stream, returning an error code"); } return(ProcessStatus.Error); } else if ((readNextLine == BinaryReaderHelper.ReadNextLineResponses.StringAtEndOfStream) || (readNextLine == BinaryReaderHelper.ReadNextLineResponses.NeedMoreBytes)) { if (IsDebugEnabled) { Log.Debug("restoring the starting position and returning ProcessStatus.NeedMoreData", readNextLine); } // restore the starting position br.BaseStream.Position = startingPosition; // if we don't have enough data or if we have data but no crlf // then report this return(ProcessStatus.NeedMoreData); } else { // Treat errors more seriously in DEBUG mode #if DEBUG throw new System.InvalidOperationException("unknown readNextLine value of " + readNextLine + ", returning an error"); #else Log.Error("unknown readNextLine value of " + readNextLine + ", returning an error"); return(ProcessStatus.Error); #endif } } else if (Phase == Phases.Body) { if (IsDebugEnabled) { Log.Debug("Phase == Phases.Body"); } processStatus = PhaseBody(br); if (processStatus != ProcessStatus.Continue) { return(processStatus); } } else if (Phase == Phases.BodyChunkData) { if (IsDebugEnabled) { Log.Debug("Phase == Phases.BodyChunkData"); } processStatus = PhaseBodyChunkData(br); if (processStatus != ProcessStatus.Continue) { return(processStatus); } } else { throw new System.InvalidCastException("Unknown phase of " + Phase); } } // while(true) }
public ResponseStatus ReadStatus() { var status = ResponseStatus.Unknown; var buffer = m_statusBuffer; BinaryReaderHelper.ReadTo(m_reader, buffer, 0, 5); var remains = 0; var code = buffer[3] | (buffer[4] << 8); switch (code) { case End: status = ResponseStatus.NoError; break; case Value: status = ResponseStatus.Value; remains = 1; break; case Stored: status = ResponseStatus.NoError; remains = 3; break; case Deleted: status = ResponseStatus.NoError; remains = 4; break; case NotFound: status = ResponseStatus.KeyNotFound; remains = 6; break; case Exists: status = ResponseStatus.KeyExists; remains = 3; break; case NotStored: status = ResponseStatus.ItemNotStored; remains = 7; break; case ServerError: case ClientError: Read(8); throw new InvalidOperationException(ReadError()); case Error: Read(2); throw new InvalidOperationException(); default: throw new NotImplementedException(); } if (remains > 0) { BinaryReaderHelper.ReadTo(m_reader, buffer, 0, remains); } return(status); }
private void Read(int count) { BinaryReaderHelper.ReadTo(m_reader, m_buffer.Array, 0, count); }