/// <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> /// 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 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> /// 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)); }
public static string ReadString(CitoStream stream) { byte[] bytes = ReadBytes(stream); return(ProtoPlatform.BytesToString(bytes, 0)); }