// places a double in the buffer private static void appendDouble(BuffersState bufState, double value) { long longBits = BitConverter.DoubleToInt64Bits(value); appendLong(bufState, longBits); }
public static List<byte[]> Serialize(Parameters parameters, int chunkSize) { if(chunkSize != int.MaxValue && chunkSize % 4 != 0) { throw new System.ArgumentException(); } List<byte[]> stringCache = new List<byte[]>(); int numberOfBytes = serializationSize(parameters, stringCache); // allocate all buffers List<byte[]> buffers = new List<byte[]>(); while (numberOfBytes > 0) { int sizeOfBuffer = Math.Min(numberOfBytes, chunkSize); buffers.Add(new byte[sizeOfBuffer]); numberOfBytes -= sizeOfBuffer; } // fill all buffers with data BuffersState bufState = new BuffersState(); bufState.buffers = buffers; bufState.bufferIndex = 0; bufState.byteIndex = 0; serialize(bufState, parameters, stringCache); return buffers; }
public static List <byte[]> Serialize(Parameters parameters, int chunkSize) { if (chunkSize != int.MaxValue && chunkSize % 4 != 0) { throw new System.ArgumentException(); } List <byte[]> stringCache = new List <byte[]>(); int numberOfBytes = serializationSize(parameters, stringCache); // allocate all buffers List <byte[]> buffers = new List <byte[]>(); while (numberOfBytes > 0) { int sizeOfBuffer = Math.Min(numberOfBytes, chunkSize); buffers.Add(new byte[sizeOfBuffer]); numberOfBytes -= sizeOfBuffer; } // fill all buffers with data BuffersState bufState = new BuffersState(); bufState.buffers = buffers; bufState.bufferIndex = 0; bufState.byteIndex = 0; serialize(bufState, parameters, stringCache); return(buffers); }
// places an integer in the buffer private static void appendInt(BuffersState bufState, int value) { byte[] buf = bufState.buffers[bufState.bufferIndex]; storeInt(buf, bufState.byteIndex, value); bufState.byteIndex += SIZE_OF_INT; bufState.checkIndices(); }
// places a binary object in the buffer private static void appendBinary(BuffersState bufState, byte[] value) { // first place the length of binary buffer appendInt(bufState, value.Length); // then the content itself, but padded to full 4-byte word appendBytes(bufState, value); }
// places a string in the buffer private static void appendString(BuffersState bufState, List <byte[]> stringCache) { byte[] valueAsBytes = stringCache[0]; stringCache.RemoveAt(0); // first place the length of string appendInt(bufState, valueAsBytes.Length); // then the content itself, but padded to full 4-byte word appendBytes(bufState, valueAsBytes); }
// places a byte array, but without bounds private static void appendBytes(BuffersState bufState, byte[] array) { int currentPos = 0; int bytesLeft = array.Length; while (bytesLeft >= SIZE_OF_INT) { byte[] buf = bufState.buffers[bufState.bufferIndex]; int contiguousBlockSize = Math.Min( buf.Length - bufState.byteIndex, bytesLeft & ~0x03 ); for (int i = 0; i != contiguousBlockSize; ++i) { buf[bufState.byteIndex + i] = array[currentPos + i]; } currentPos += contiguousBlockSize; bytesLeft -= contiguousBlockSize; bufState.byteIndex += contiguousBlockSize; bufState.checkIndices(); } if (bytesLeft != 0) { // padding required byte[] buf = bufState.buffers[bufState.bufferIndex]; for (int i = 0; i != bytesLeft; ++i) { buf[bufState.byteIndex + i] = array[currentPos + i]; } bufState.byteIndex += SIZE_OF_INT; bufState.checkIndices(); } }
private static void serialize(BuffersState bufState, Parameters parameters, List <byte[]> stringCache) { // number of entries appendInt(bufState, parameters.Count); foreach (Parameters.Entry e in parameters) { // name of this entry appendString(bufState, stringCache); // type code appendInt(bufState, typeToCode(e.Type)); // entry value itself switch (e.Type) { case Parameters.EntryType.BOOLEAN: appendInt(bufState, e.GetBoolean() ? 1 : 0); break; case Parameters.EntryType.INTEGER: appendInt(bufState, e.GetInteger()); break; case Parameters.EntryType.LONG: appendLong(bufState, e.GetLong()); break; case Parameters.EntryType.DOUBLE: appendDouble(bufState, e.GetDouble()); break; case Parameters.EntryType.STRING: appendString(bufState, stringCache); break; case Parameters.EntryType.BINARY: appendBinary(bufState, e.GetBinary()); break; case Parameters.EntryType.BOOLEAN_ARRAY: { bool[] array = e.GetBooleanArray(); // pack the array int bytesNeeded = (array.Length + BITS_IN_BYTE - 1) / BITS_IN_BYTE; byte[] packedArray = new byte[bytesNeeded]; for (int i = 0; i != array.Length; ++i) { int bytePosition = i / BITS_IN_BYTE; int bitPosition = i % BITS_IN_BYTE; if (array[i]) { packedArray[bytePosition] |= (byte)(1 << bitPosition); } } appendInt(bufState, array.Length); appendBytes(bufState, packedArray); } break; case Parameters.EntryType.INTEGER_ARRAY: { int[] array = e.GetIntegerArray(); appendInt(bufState, array.Length); for (int i = 0; i != array.Length; ++i) { appendInt(bufState, array[i]); } } break; case Parameters.EntryType.LONG_ARRAY: { long[] array = e.GetLongArray(); appendInt(bufState, array.Length); for (int i = 0; i != array.Length; ++i) { appendLong(bufState, array[i]); } } break; case Parameters.EntryType.DOUBLE_ARRAY: { double[] array = e.GetDoubleArray(); appendInt(bufState, array.Length); for (int i = 0; i != array.Length; ++i) { appendDouble(bufState, array[i]); } } break; case Parameters.EntryType.STRING_ARRAY: { string[] array = e.GetStringArray(); appendInt(bufState, array.Length); for (int i = 0; i != array.Length; ++i) { appendString(bufState, stringCache); } } break; case Parameters.EntryType.BINARY_ARRAY: { byte[][] array = e.GetBinaryArray(); appendInt(bufState, array.Length); for (int i = 0; i != array.Length; ++i) { appendBinary(bufState, array[i]); } } break; case Parameters.EntryType.NESTED_PARAMETERS: { Parameters nested = e.GetNestedParameters(); serialize(bufState, nested, stringCache); } break; case Parameters.EntryType.NESTED_PARAMETERS_ARRAY: { Parameters[] nested = e.GetNestedArray(); appendInt(bufState, nested.Length); for (int i = 0; i != nested.Length; ++i) { serialize(bufState, nested[i], stringCache); } } break; } } }
// places a long in the buffer private static void appendLong(BuffersState bufState, long value) { appendInt(bufState, (int)(value & 0xffffffffL)); appendInt(bufState, (int)(value >> 32)); }
private static void serialize(BuffersState bufState, Parameters parameters, List<byte[]> stringCache) { // number of entries appendInt(bufState, parameters.Count); foreach(Parameters.Entry e in parameters) { // name of this entry appendString(bufState, stringCache); // type code appendInt(bufState, typeToCode(e.Type)); // entry value itself switch(e.Type) { case Parameters.EntryType.BOOLEAN: appendInt(bufState, e.GetBoolean() ? 1 : 0); break; case Parameters.EntryType.INTEGER: appendInt(bufState, e.GetInteger()); break; case Parameters.EntryType.LONG: appendLong(bufState, e.GetLong()); break; case Parameters.EntryType.DOUBLE: appendDouble(bufState, e.GetDouble()); break; case Parameters.EntryType.STRING: appendString(bufState, stringCache); break; case Parameters.EntryType.BINARY: appendBinary(bufState, e.GetBinary()); break; case Parameters.EntryType.BOOLEAN_ARRAY: { bool[] array = e.GetBooleanArray(); // pack the array int bytesNeeded = (array.Length + BITS_IN_BYTE - 1) / BITS_IN_BYTE; byte[] packedArray = new byte[bytesNeeded]; for(int i = 0; i != array.Length; ++i) { int bytePosition = i / BITS_IN_BYTE; int bitPosition = i % BITS_IN_BYTE; if(array[i]) { packedArray[bytePosition] |= (byte)(1 << bitPosition); } } appendInt(bufState, array.Length); appendBytes(bufState, packedArray); } break; case Parameters.EntryType.INTEGER_ARRAY: { int[] array = e.GetIntegerArray(); appendInt(bufState, array.Length); for(int i = 0; i != array.Length; ++i) { appendInt(bufState, array[i]); } } break; case Parameters.EntryType.LONG_ARRAY: { long[] array = e.GetLongArray(); appendInt(bufState, array.Length); for(int i = 0; i != array.Length; ++i) { appendLong(bufState, array[i]); } } break; case Parameters.EntryType.DOUBLE_ARRAY: { double[] array = e.GetDoubleArray(); appendInt(bufState, array.Length); for(int i = 0; i != array.Length; ++i) { appendDouble(bufState, array[i]); } } break; case Parameters.EntryType.STRING_ARRAY: { string[] array = e.GetStringArray(); appendInt(bufState, array.Length); for(int i = 0; i != array.Length; ++i) { appendString(bufState, stringCache); } } break; case Parameters.EntryType.BINARY_ARRAY: { byte[][] array = e.GetBinaryArray(); appendInt(bufState, array.Length); for(int i = 0; i != array.Length; ++i) { appendBinary(bufState, array[i]); } } break; case Parameters.EntryType.NESTED_PARAMETERS: { Parameters nested = e.GetNestedParameters(); serialize(bufState, nested, stringCache); } break; } } }
// places a string in the buffer private static void appendString(BuffersState bufState, List<byte[]> stringCache) { byte[] valueAsBytes = stringCache[0]; stringCache.RemoveAt(0); // first place the length of string appendInt(bufState, valueAsBytes.Length); // then the content itself, but padded to full 4-byte word appendBytes(bufState, valueAsBytes); }
// places a byte array, but without bounds private static void appendBytes(BuffersState bufState, byte[] array) { int currentPos = 0; int bytesLeft = array.Length; while(bytesLeft >= SIZE_OF_INT) { byte[] buf = bufState.buffers[bufState.bufferIndex]; int contiguousBlockSize = Math.Min( buf.Length - bufState.byteIndex, bytesLeft & ~0x03 ); for(int i = 0; i != contiguousBlockSize; ++i) { buf[bufState.byteIndex + i] = array[currentPos + i]; } currentPos += contiguousBlockSize; bytesLeft -= contiguousBlockSize; bufState.byteIndex += contiguousBlockSize; bufState.checkIndices(); } if(bytesLeft != 0) { // padding required byte[] buf = bufState.buffers[bufState.bufferIndex]; for(int i = 0; i != bytesLeft; ++i) { buf[bufState.byteIndex + i] = array[currentPos + i]; } bufState.byteIndex += SIZE_OF_INT; bufState.checkIndices(); } }