/// <summary>Write the given object to the stream.</summary> /// <remarks> /// Write the given object to the stream. If it is a Text or BytesWritable, /// write it directly. Otherwise, write it to a buffer and then write the /// length and data to the stream. /// </remarks> /// <param name="obj">the object to write</param> /// <exception cref="System.IO.IOException"/> private void WriteObject(Writable obj) { // For Text and BytesWritable, encode them directly, so that they end up // in C++ as the natural translations. if (obj is Text) { Text t = (Text)obj; int len = t.GetLength(); WritableUtils.WriteVInt(stream, len); stream.Write(t.GetBytes(), 0, len); } else { if (obj is BytesWritable) { BytesWritable b = (BytesWritable)obj; int len = b.GetLength(); WritableUtils.WriteVInt(stream, len); stream.Write(b.GetBytes(), 0, len); } else { buffer.Reset(); obj.Write(buffer); int length = buffer.GetLength(); WritableUtils.WriteVInt(stream, length); stream.Write(buffer.GetData(), 0, length); } } }
/// <summary>Utility method for testing writables.</summary> /// <exception cref="System.Exception"/> public static Writable TestWritable(Writable before, Configuration conf) { DataOutputBuffer dob = new DataOutputBuffer(); before.Write(dob); DataInputBuffer dib = new DataInputBuffer(); dib.Reset(dob.GetData(), dob.GetLength()); Writable after = (Writable)ReflectionUtils.NewInstance(before.GetType(), conf); after.ReadFields(dib); Assert.Equal(before, after); return(after); }
/// <summary>Utility method for testing VersionedWritables.</summary> /// <exception cref="System.Exception"/> public static void TestVersionedWritable(Writable before, Writable after) { DataOutputBuffer dob = new DataOutputBuffer(); before.Write(dob); DataInputBuffer dib = new DataInputBuffer(); dib.Reset(dob.GetData(), dob.GetLength()); try { after.ReadFields(dib); } catch (VersionMismatchException vmme) { System.Console.Out.WriteLine("Good, we expected this:" + vmme); return; } throw new Exception("A Version Mismatch Didn't Happen!"); }
/// <exception cref="System.IO.IOException"/> protected internal virtual void WriteObject(Writable obj, DataOutputStream stream ) { // For Text and BytesWritable, encode them directly, so that they end up // in C++ as the natural translations. DataOutputBuffer buffer = new DataOutputBuffer(); if (obj is Text) { Text t = (Text)obj; int len = t.GetLength(); WritableUtils.WriteVLong(stream, len); stream.Flush(); stream.Write(t.GetBytes(), 0, len); stream.Flush(); } else { if (obj is BytesWritable) { BytesWritable b = (BytesWritable)obj; int len = b.GetLength(); WritableUtils.WriteVLong(stream, len); stream.Write(b.GetBytes(), 0, len); } else { buffer.Reset(); obj.Write(buffer); int length = buffer.GetLength(); WritableUtils.WriteVInt(stream, length); stream.Write(buffer.GetData(), 0, length); } } stream.Flush(); }
public override void Write(byte[] data) => Writable.Write(data);
private int ProcessData(byte[] data, bool writeExcess) { ThrowIfEnded(); if (!IsSet) { throw new InvalidOperationException("Not set"); } int i = 0, len; char c; byte[] sliced; for (; i < data.Length;) { switch (State) { case BodyParserState.RawRead: len = ContentLength == -1 ? data.Length - i : Math.Min(data.Length - i, ContentLength - CurrentReadBytes); sliced = new byte[len]; Buffer.BlockCopy(data, i, sliced, 0, len); i += len; CurrentReadBytes += len; ContentTransform.Write(data); if (ContentTransform.Buffered > 0) { Readable.Write(ContentTransform.Read()); } if (CurrentReadBytes == ContentLength) { State = BodyParserState.Dormant; OnEnd?.Invoke(); break; } break; case BodyParserState.Chunked_Length: c = (char)data[i++]; if (c != CR) { StringQueue.Append(c); } else { if (!int.TryParse(StringQueue.Next(), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out int result)) { End(); return(-1); } chunkLen = result; State = BodyParserState.Chunked_LenLf; } break; case BodyParserState.Chunked_LenLf: c = (char)data[i++]; if (c != LF) { End(); return(-1); } if (chunkLen == 0) { State = BodyParserState.Chunked_Trailer; } else { State = BodyParserState.Chunked_ChunkData; } break; case BodyParserState.Chunked_ChunkData: len = Math.Min(data.Length - i, chunkLen - chunkIndex); sliced = new byte[len]; Buffer.BlockCopy(data, i, sliced, 0, len); i += len; CurrentReadBytes += len; chunkIndex += len; ContentTransform.Write(sliced); Readable.Write(ContentTransform.Read()); if (chunkLen == chunkIndex) { State = BodyParserState.Chunked_ChunkCr; } break; case BodyParserState.Chunked_ChunkCr: c = (char)data[i++]; if (c != CR) { End(); return(-1); } State = BodyParserState.Chunked_ChunkLf; break; case BodyParserState.Chunked_ChunkLf: c = (char)data[i++]; if (c != LF) { End(); return(-1); } State = BodyParserState.Chunked_Length; chunkLen = chunkIndex = 0; StringQueue.New(); break; case BodyParserState.Chunked_Trailer: c = (char)data[i++]; if (c != CR) { chunkIndex++; } else { if (chunkIndex == 0) { State = BodyParserState.Chunked_Lf; } else { chunkIndex = -1; // LF will be added } } break; case BodyParserState.Chunked_Lf: c = (char)data[i++]; if (c != LF) { End(); return(-1); } State = BodyParserState.Dormant; OnEnd?.Invoke(); ContentLength = CurrentReadBytes; break; default: throw new InvalidOperationException("ProcessData cannot execute on Dormant state"); } } if (writeExcess) { len = data.Length - i; sliced = new byte[len]; Buffer.BlockCopy(data, i, sliced, 0, len); Writable.Write(sliced); } return(i); }