/// <summary> /// Writes an Int32 value type content and returns its location for possible further update. /// </summary> /// <param name="number">Int32 value to write.</param> /// <param name="chunk">Chunk the value was stored at.</param> /// <param name="position">Chunk location where the value was saved.</param> public void WriteInt32AndRememberItsLocation(int number, out byte[] chunk, out int position) { if (this._disposed) { throw new ObjectDisposedException("GenuineChunkedStream"); } if (this._currentWriteBlock == null || this._writePosition >= this._currentWriteBlock.Length - 4) { this.ObtainNextBuffer(); } // set returned values chunk = this._currentWriteBlock; position = this._writePosition; // write the value MessageCoder.WriteInt32(this._currentWriteBlock, this._writePosition, number); // and advance the pointer this._writePosition += 4; this._chunksAndStreams[this._chunksAndStreams.Count - 1] = this._writePosition; if (this._length >= 0) { this._length += 4; } }
/// <summary> /// Fills in the provided stream with the specified messages that the total size as close to the recommended size as possible. /// </summary> /// <param name="message">The message.</param> /// <param name="messageContainer">Accumulated messages or a null reference.</param> /// <param name="packedMessages">This instance will contain all packed messages after this function completes.</param> /// <param name="resultContent">The filled stream.</param> /// <param name="intermediateBuffer">The intermediate buffer.</param> /// <param name="recommendedSize">The recommended size.</param> public static void FillInLabelledStream(Message message, MessageContainer messageContainer, ArrayList packedMessages, GenuineChunkedStream resultContent, byte[] intermediateBuffer, int recommendedSize) { BinaryWriter binaryWriter = new BinaryWriter(resultContent); if (packedMessages != null) { packedMessages.Clear(); } while (message != null) { // not finished yet binaryWriter.Write((byte)0); if (packedMessages != null) { packedMessages.Add(message); } MessageCoder.WriteLabelledStream(message.SerializedContent, resultContent, binaryWriter, intermediateBuffer); message = null; if (resultContent.Length > recommendedSize) { break; } if (messageContainer != null) { message = messageContainer.GetMessage(); } if (message == null) { break; } } // "finish" flag binaryWriter.Write((byte)1); }
/// <summary> /// Synchronously reads the next network packet if it is available. /// </summary> private void ReadNextPortion() { int bytesRead = 0; int lengthToRead = 0; // try to read the remaining part of the packet if (this._currentPacketBytesRead < this._currentPacketSize) { // read the next part of the packet lengthToRead = Math.Min(this._currentPacketSize - this._currentPacketBytesRead, this._readBuffer.Length); this._validLength = this._underlyingStream.Read(this._readBuffer, 0, lengthToRead); if (this._validLength == 0) { throw GenuineExceptions.Get_Receive_Portion(); } this.ITransportContext.ConnectionManager.IncreaseBytesReceived(this._validLength); this._currentPacketBytesRead += this._validLength; this._currentPosition = 0; return; } // the underlying stream ends if (this._messageRead) { return; } // prepare for reading a header lengthToRead = MessageCoder.LABEL_HEADER_SIZE; this._currentPosition = 0; // read the header while (this._currentPosition < lengthToRead) { bytesRead = this._underlyingStream.Read(this._readBuffer, this._currentPosition, lengthToRead - this._currentPosition); if (bytesRead == 0) { throw GenuineExceptions.Get_Receive_Portion(); } this.ITransportContext.ConnectionManager.IncreaseBytesReceived(bytesRead); this._currentPosition += bytesRead; } // parse the header if (this._readBuffer[0] != MessageCoder.COMMAND_MAGIC_CODE) { throw GenuineExceptions.Get_Receive_IncorrectData(); } this._currentPacketSize = MessageCoder.ReadInt32(this._readBuffer, 1); this._messageRead = this._readBuffer[5] != 0; this._currentPacketBytesRead = 0; // and read the part of the packet if (this._currentPacketBytesRead < this._currentPacketSize) { // read the next part of the packet lengthToRead = Math.Min(this._currentPacketSize - this._currentPacketBytesRead, this._readBuffer.Length); // GenuineUtility.ReadDataFromStream(this._underlyingStream, this._readBuffer, 0, lengthToRead); // this._validLength = lengthToRead; this._validLength = this._underlyingStream.Read(this._readBuffer, 0, lengthToRead); if (this._validLength == 0) { throw GenuineExceptions.Get_Receive_Portion(); } this.ITransportContext.ConnectionManager.IncreaseBytesReceived(this._validLength); this._currentPacketBytesRead += this._validLength; this._currentPosition = 0; } }
/// <summary> /// Updates the difference of the length property. /// </summary> public void Dispose() { MessageCoder.WriteInt32(this._chunk, this._position, (int)(this._outputStream.Length - this._initialLength)); }