/// <summary> /// Seek past the value for the previously read key. /// </summary> public static void SkipKey(CitoStream stream, Key key) { switch (key.GetWireType()) { case Wire.Fixed32: stream.Seek(4, CitoSeekOrigin.Current); return; case Wire.Fixed64: stream.Seek(8, CitoSeekOrigin.Current); return; case Wire.LengthDelimited: stream.Seek(ProtocolParser.ReadUInt32(stream), CitoSeekOrigin.Current); return; case Wire.Varint: ProtocolParser.ReadSkipVarInt(stream); return; default: #if !CITO throw new NotImplementedException("Unknown wire type: " + key.GetWireType()); #else return; #endif } }
/// <summary> /// Unsigned VarInt format /// </summary> public static void WriteUInt64(CitoStream stream, int val) { byte[] buffer = new byte[10]; int count = 0; while (true) { #if !CITO buffer[count] = (byte)(val & 0x7F); #else buffer[count] = (val & 0x7F).LowByte; #endif val = ProtoPlatform.logical_right_shift(val, 7); if (val == 0) { break; } buffer[count] |= 0x80; count += 1; } stream.Write(buffer, 0, count + 1); }
/// <summary> /// Unsigned VarInt format /// </summary> public static void WriteUInt32_(CitoStream stream, int val) { byte[] buffer = new byte[5]; int count = 0; while (true) { #if !CITO buffer[count] = (byte)(val & 0x7F); #else buffer[count] = (val & 0x7F).LowByte; #endif val = val >> 7; if (val == 0) { break; } buffer[count] |= 0x80; count += 1; } stream.Write(buffer, 0, count + 1); }
/// <summary> /// Read the value for an unknown key as bytes. /// Used to preserve unknown keys during deserialization. /// Requires the message option preserveunknown=true. /// </summary> public static byte[] ReadValueBytes(CitoStream stream, Key key) { byte[] b; int offset = 0; switch (key.GetWireType()) { case Wire.Fixed32: b = new byte[4]; while (offset < 4) { offset += stream.Read(b, offset, 4 - offset); } return(b); case Wire.Fixed64: b = new byte[8]; while (offset < 8) { offset += stream.Read(b, offset, 8 - offset); } return(b); case Wire.LengthDelimited: //Read and include length in value buffer int length = ProtocolParser.ReadUInt32(stream); CitoMemoryStream ms = new CitoMemoryStream(); { //TODO: pass b directly to MemoryStream constructor or skip usage of it completely ProtocolParser.WriteUInt32(ms, length); b = new byte[length + ms.Length()]; byte[] arr = ms.ToArray(); for (int i = 0; i < ProtoPlatform.ArrayLength(arr); i++) { b[i] = arr[i]; } offset = ms.Length(); } //Read data into buffer while (offset < ProtoPlatform.ArrayLength(b)) { offset += stream.Read(b, offset, ProtoPlatform.ArrayLength(b) - offset); } return(b); case Wire.Varint: return(ProtocolParser.ReadVarIntBytes(stream)); default: #if !CITO throw new NotImplementedException("Unknown wire type: " + key.GetWireType()); #else return(null); #endif } }
public static Key ReadKey_(byte firstByte, CitoStream stream) { if (firstByte < 128) { return(Key.Create((firstByte >> 3), (firstByte & 0x07))); } int fieldID = (ReadUInt32(stream) << 4) | ((firstByte >> 3) & 0x0F); return(Key.Create(fieldID, (firstByte & 0x07))); }
public static void WriteBool(CitoStream stream, bool val) { byte ret = 0; if (val) { ret = 1; } stream.WriteByte(ret); }
/// <summary> /// Skip the next varint length prefixed bytes. /// Alternative to ReadBytes when the data is not of interest. /// </summary> public static void SkipBytes(CitoStream stream) { int length = ReadUInt32(stream); if (stream.CanSeek()) { stream.Seek(length, CitoSeekOrigin.Current); } else { ReadBytes(stream); } }
//} //} //using System; //using System.IO; //namespace SilentOrbit.ProtocolBuffers //{ //public static partial class ProtocolParser //{ /// <summary> /// Reads past a varint for an unknown field. /// </summary> public static void ReadSkipVarInt(CitoStream stream) { while (true) { int b = stream.ReadByte(); if (b < 0) #if !CITO { throw new IOException("Stream ended too early"); } #else { return; } #endif if ((b & 0x80) == 0) { return; //end of varint } } }
/// <summary> /// Unsigned VarInt format /// </summary> public static int ReadUInt64(CitoStream stream) { int b; int val = 0; for (int n = 0; n < 10; n++) { b = stream.ReadByte(); if (b < 0) #if !CITO { throw new IOException("Stream ended too early"); } #else { return(0); } #endif //Check that it fits in 64 bits if ((n == 9) && (b & 0xFE) != 0) #if !CITO { throw new InvalidDataException("Got larger VarInt than 64 bit unsigned"); } #else { return(0); } #endif //End of check if ((b & 0x80) == 0) { //return val | (ulong)b << (7 * n); return(val | b << (7 * n)); } //val |= (ulong)(b & 0x7F) << (7 * n); val |= (b & 0x7F) << (7 * n); } #if !CITO throw new InvalidDataException("Got larger VarInt than 64 bit unsigned"); #else return(0); #endif }
/// <summary> /// Reads a length delimited byte array /// </summary> public static byte[] ReadBytes(CitoStream stream) { //VarInt length int length = ReadUInt32(stream); //Bytes byte[] buffer = new byte[length]; int read = 0; while (read < length) { int r = stream.Read(buffer, read, length - read); if (r == 0) #if !CITO { throw new InvalidDataException("Expected " + (length - read) + " got " + read); } #else { return(null); } #endif read += r; } return(buffer); }
public static byte[] ReadVarIntBytes(CitoStream stream) { byte[] buffer = new byte[10]; int offset = 0; while (true) { int b = stream.ReadByte(); if (b < 0) #if !CITO { throw new IOException("Stream ended too early"); } #else { return(null); } #endif #if !CITO buffer[offset] = (byte)b; #else buffer[offset] = b.LowByte; #endif offset += 1; if ((b & 0x80) == 0) { break; //end of varint } if (offset >= ProtoPlatform.ArrayLength(buffer)) #if !CITO { throw new InvalidDataException("VarInt too long, more than 10 bytes"); } #else { return(null); } #endif } byte[] ret = new byte[offset]; for (int i = 0; i < offset; i++) { ret[i] = buffer[i]; } return(ret); }
//#endregion //#region Varint: bool public static bool ReadBool(CitoStream stream) { int b = stream.ReadByte(); if (b < 0) #if !CITO { throw new IOException("Stream ended too early"); } #else { return(false); } #endif if (b == 1) { return(true); } if (b == 0) { return(false); } #if !CITO throw new InvalidDataException("Invalid boolean value"); #else return(false); #endif }
//} //} // // This file contain references on how to write and read // fixed integers and float/double. // //using System; //using System.IO; //namespace SilentOrbit.ProtocolBuffers //{ //public static partial class ProtocolParser //{ //#region Fixed Int, Only for reference //#endregion //} //} // // Reader/Writer for field key // //using System; //using System.IO; //namespace SilentOrbit.ProtocolBuffers //{ //public static partial class ProtocolParser //{ public static Key ReadKey(CitoStream stream) { int n = ReadUInt32(stream); return Key.Create(n >> 3, (n & 0x07)); }
//#endregion //#region VarInt: int64, UInt64, SInt64 //[Obsolete("Use (long)ReadUInt64(stream); instead")] /// <summary> /// Since the int64 format is inefficient for negative numbers we have avoided to implement it. /// The same functionality can be achieved using: (long)ReadUInt64(stream); /// </summary> public static int ReadInt64(CitoStream stream) { return(ReadUInt64(stream)); }
/// <summary> /// Zig-zag signed VarInt format /// </summary> public static int ReadZInt32(CitoStream stream) { int val = ReadUInt32(stream); return (val >> 1) ^ ((val << 31) >> 31); }
/// <summary> /// Skip the next varint length prefixed bytes. /// Alternative to ReadBytes when the data is not of interest. /// </summary> public static void SkipBytes(CitoStream stream) { int length = ReadUInt32(stream); if (stream.CanSeek()) stream.Seek(length, CitoSeekOrigin.Current); else ReadBytes(stream); }
public static string ReadString(CitoStream stream) { byte[] bytes = ReadBytes(stream); return ProtoPlatform.BytesToString(bytes, 0); }
/// <summary> /// Read the value for an unknown key as bytes. /// Used to preserve unknown keys during deserialization. /// Requires the message option preserveunknown=true. /// </summary> public static byte[] ReadValueBytes(CitoStream stream, Key key) { byte[] b; int offset = 0; switch (key.GetWireType()) { case Wire.Fixed32: b = new byte[4]; while (offset < 4) offset += stream.Read(b, offset, 4 - offset); return b; case Wire.Fixed64: b = new byte[8]; while (offset < 8) offset += stream.Read(b, offset, 8 - offset); return b; case Wire.LengthDelimited: //Read and include length in value buffer int length = ProtocolParser.ReadUInt32(stream); CitoMemoryStream ms = new CitoMemoryStream(); { //TODO: pass b directly to MemoryStream constructor or skip usage of it completely ProtocolParser.WriteUInt32(ms, length); b = new byte[length + ms.Length()]; byte[] arr = ms.ToArray(); for (int i = 0; i < ProtoPlatform.ArrayLength(arr); i++) { b[i] = arr[i]; } offset = ms.Length(); } //Read data into buffer while (offset < ProtoPlatform.ArrayLength(b)) offset += stream.Read(b, offset, ProtoPlatform.ArrayLength(b) - offset); return b; case Wire.Varint: return ProtocolParser.ReadVarIntBytes(stream); default: #if !CITO throw new NotImplementedException("Unknown wire type: " + key.GetWireType()); #else return null; #endif } }
public static string ReadString(CitoStream stream) { byte[] bytes = ReadBytes(stream); return(ProtoPlatform.BytesToString(bytes, 0)); }
//[Obsolete("Use WriteUInt64(stream, (ulong)val); //yes 64, negative numbers are encoded that way")] /// <summary> /// Since the int32 format is inefficient for negative numbers we have avoided to imlplement. /// The same functionality can be achieved using: WriteUInt64(stream, (uint)val); /// Note that 64 must always be used for int32 to generate the ten byte wire format. /// </summary> public static void WriteInt32(CitoStream stream, int val) { //signed varint is always encoded as 64 but values! WriteUInt64(stream, val); }
/// <summary> /// Zig-zag signed VarInt format /// </summary> public static int ReadZInt32(CitoStream stream) { int val = ReadUInt32(stream); return((val >> 1) ^ ((val << 31) >> 31)); }
/// <summary> /// Zig-zag signed VarInt format /// </summary> public static void WriteZInt64(CitoStream stream, int val) { WriteUInt64(stream, ((val << 1) ^ (val >> 63))); }
/// <summary> /// Zig-zag signed VarInt format /// </summary> public static int ReadZInt64(CitoStream stream) { int val = ReadUInt64(stream); return((val >> 1) ^ ((val << 63) >> 63)); }
//[Obsolete("Use WriteUInt64 (stream, (ulong)val); instead")] /// <summary> /// Since the int64 format is inefficient for negative numbers we have avoided to implement. /// The same functionality can be achieved using: WriteUInt64 (stream, (ulong)val); /// </summary> public static void WriteInt64(CitoStream stream, int val) { WriteUInt64(stream, val); }
public static Key ReadKey_(byte firstByte, CitoStream stream) { if (firstByte < 128) return Key.Create((firstByte >> 3), (firstByte & 0x07)); int fieldID = (ReadUInt32(stream) << 4) | ((firstByte >> 3) & 0x0F); return Key.Create(fieldID, (firstByte & 0x07)); }
public static void WriteKey(CitoStream stream, Key key) { int n = (key.GetField() << 3) | (key.GetWireType()); WriteUInt32_(stream, n); }
//} //} //using System; //using System.IO; //namespace SilentOrbit.ProtocolBuffers //{ //public static partial class ProtocolParser //{ /// <summary> /// Reads past a varint for an unknown field. /// </summary> public static void ReadSkipVarInt(CitoStream stream) { while (true) { int b = stream.ReadByte(); if (b < 0) #if !CITO throw new IOException("Stream ended too early"); #else return; #endif if ((b & 0x80) == 0) return; //end of varint } }
/// <summary> /// Unsigned VarInt format /// </summary> public static void WriteUInt32_(CitoStream stream, int val) { byte[] buffer = new byte[5]; int count = 0; while (true) { #if !CITO buffer[count] = (byte)(val & 0x7F); #else buffer[count] = (val & 0x7F).LowByte; #endif val = val >> 7; if (val == 0) break; buffer[count] |= 0x80; count += 1; } stream.Write(buffer, 0, count + 1); }
/// <summary> /// Unsigned VarInt format /// </summary> public static int ReadUInt64(CitoStream stream) { int b; int val = 0; for (int n = 0; n < 10; n++) { b = stream.ReadByte(); if (b < 0) #if !CITO throw new IOException("Stream ended too early"); #else return 0; #endif //Check that it fits in 64 bits if ((n == 9) && (b & 0xFE) != 0) #if !CITO throw new InvalidDataException("Got larger VarInt than 64 bit unsigned"); #else return 0; #endif //End of check if ((b & 0x80) == 0) //return val | (ulong)b << (7 * n); return val | b << (7 * n); //val |= (ulong)(b & 0x7F) << (7 * n); val |= (b & 0x7F) << (7 * n); } #if !CITO throw new InvalidDataException("Got larger VarInt than 64 bit unsigned"); #else return 0; #endif }
/// <summary> /// Zig-zag signed VarInt format /// </summary> public static void WriteZInt32(CitoStream stream, int val) { WriteUInt32_(stream, ((val << 1) ^ (val >> 31))); }
public static byte[] ReadVarIntBytes(CitoStream stream) { byte[] buffer = new byte[10]; int offset = 0; while (true) { int b = stream.ReadByte(); if (b < 0) #if !CITO throw new IOException("Stream ended too early"); #else return null; #endif #if !CITO buffer[offset] = (byte)b; #else buffer[offset] = b.LowByte; #endif offset += 1; if ((b & 0x80) == 0) break; //end of varint if (offset >= ProtoPlatform.ArrayLength(buffer)) #if !CITO throw new InvalidDataException("VarInt too long, more than 10 bytes"); #else return null; #endif } byte[] ret = new byte[offset]; for (int i = 0; i < offset; i++) { ret[i] = buffer[i]; } return ret; }
/// <summary> /// Zig-zag signed VarInt format /// </summary> public static int ReadZInt64(CitoStream stream) { int val = ReadUInt64(stream); return (val >> 1) ^ ((val << 63) >> 63); }
/// <summary> /// Reads a length delimited byte array /// </summary> public static byte[] ReadBytes(CitoStream stream) { //VarInt length int length = ReadUInt32(stream); //Bytes byte[] buffer = new byte[length]; int read = 0; while (read < length) { int r = stream.Read(buffer, read, length - read); if (r == 0) #if !CITO throw new InvalidDataException("Expected " + (length - read) + " got " + read); #else return null; #endif read += r; } return buffer; }
//#endregion //#region VarInt: int64, UInt64, SInt64 //[Obsolete("Use (long)ReadUInt64(stream); instead")] /// <summary> /// Since the int64 format is inefficient for negative numbers we have avoided to implement it. /// The same functionality can be achieved using: (long)ReadUInt64(stream); /// </summary> public static int ReadInt64(CitoStream stream) { return ReadUInt64(stream); }
/// <summary> /// Writes length delimited byte array /// </summary> public static void WriteBytes(CitoStream stream, byte[] val) { WriteUInt32_(stream, ProtoPlatform.ArrayLength(val)); stream.Write(val, 0, ProtoPlatform.ArrayLength(val)); }
public static void WriteString(CitoStream stream, string val) { WriteBytes(stream, ProtoPlatform.StringToBytes(val)); }
/// <summary> /// Unsigned VarInt format /// </summary> public static void WriteUInt64(CitoStream stream, int val) { byte[] buffer = new byte[10]; int count = 0; while (true) { #if !CITO buffer[count] = (byte)(val & 0x7F); #else buffer[count] = (val & 0x7F).LowByte; #endif val = ProtoPlatform.logical_right_shift(val, 7); if (val == 0) break; buffer[count] |= 0x80; count += 1; } stream.Write(buffer, 0, count + 1); }
//#endregion //#region Varint: bool public static bool ReadBool(CitoStream stream) { int b = stream.ReadByte(); if (b < 0) #if !CITO throw new IOException("Stream ended too early"); #else return false; #endif if (b == 1) return true; if (b == 0) return false; #if !CITO throw new InvalidDataException("Invalid boolean value"); #else return false; #endif }
//} //} // // This file contain references on how to write and read // fixed integers and float/double. // //using System; //using System.IO; //namespace SilentOrbit.ProtocolBuffers //{ //public static partial class ProtocolParser //{ //#region Fixed Int, Only for reference //#endregion //} //} // // Reader/Writer for field key // //using System; //using System.IO; //namespace SilentOrbit.ProtocolBuffers //{ //public static partial class ProtocolParser //{ public static Key ReadKey(CitoStream stream) { int n = ReadUInt32(stream); return(Key.Create(n >> 3, (n & 0x07))); }