private void ParseBuffer() { int protoBufLength = (FileContent[0] << 24) | (FileContent[1] << 16) | (FileContent[2] << 8) | FileContent[3]; if (protoBufLength > 0x10000) { throw new InvalidDataException(); } byte[] protoBuf = new byte[protoBufLength]; int payloadStart = protoBufLength + 4; int payloadLength = FileContent.Length - payloadStart; byte[] payload = new byte[payloadLength]; Array.Copy(FileContent, 4, protoBuf, 0, protoBufLength); Array.Copy(FileContent, protoBufLength + 4, payload, 0, payloadLength); var coder = new ProtoCoder(); FileHeader header = coder.Deserialize <FileHeader>(protoBuf); var prov = new SHA1CryptoServiceProvider(); var hash = prov.ComputeHash(payload); HashCorrect = true; if (!hash.SequenceEqual(header.Hash)) { HashCorrect = false; } byte[] data = coder.Serialize(header); HeaderLength = data.Length; Audio = payload; Header = header; }
private void WriteHeader() { int expectedSize = 0x1000 - 4; /* set protobuf header size */ FileContent[0] = (byte)(expectedSize >> 24); FileContent[1] = (byte)(expectedSize >> 16); FileContent[2] = (byte)(expectedSize >> 8); FileContent[3] = (byte)(expectedSize >> 0); /* first use one byte padding */ Header.Padding = new byte[1]; var stream = new MemoryStream(); var coder = new ProtoCoder(); byte[] dataPre = coder.Serialize <FileHeader>(Header); /* then determine how many extra bytes to fill */ long padding = expectedSize - dataPre.Length; Header.Padding = new byte[padding]; byte[] data = coder.Serialize <FileHeader>(Header); Array.Copy(data, 0, FileContent, 4, data.Length); }
private void AddObject <T>(T obj) where T : class { Type destObjectType = obj.GetType(); var objFields = destObjectType.GetFields(); ulong field = 1; for (int pos = 0; pos < objFields.Length; pos++) { var objField = objFields[pos]; var objFieldType = objField.FieldType; if (objField.CustomAttributes.Where(a => a.AttributeType.Name == "SkipEncodeAttribute").Count() != 0) { continue; } if (objFieldType.IsArray) { if (objFieldType.Name == "Byte[]") { AddStringField(field, (byte[])objField.GetValue(obj)); } else { ProtoCoder subCoder = new ProtoCoder(); switch (objFieldType.Name) { case "Int16[]": ((Int16[])objField.GetValue(obj)).ToList().ForEach(v => subCoder.AddVariant((ulong)v)); break; case "Int32[]": ((Int32[])objField.GetValue(obj)).ToList().ForEach(v => subCoder.AddVariant((ulong)v)); break; case "Int64[]": ((Int64[])objField.GetValue(obj)).ToList().ForEach(v => subCoder.AddVariant((ulong)v)); break; case "UInt16[]": ((UInt16[])objField.GetValue(obj)).ToList().ForEach(v => subCoder.AddVariant((ulong)v)); break; case "UInt32[]": ((UInt32[])objField.GetValue(obj)).ToList().ForEach(v => subCoder.AddVariant((ulong)v)); break; case "UInt64[]": ((UInt64[])objField.GetValue(obj)).ToList().ForEach(v => subCoder.AddVariant((ulong)v)); break; } byte[] data = subCoder.Payload.ToArray(); AddStringField(field, data); } } else { switch (objFieldType.Name) { case "Boolean": AddVariantField(field, ((Boolean)objField.GetValue(obj)) ? 1 : 0); break; case "Byte": AddVariantField(field, (Byte)objField.GetValue(obj)); break; case "Int16": AddVariantField(field, (Int16)objField.GetValue(obj)); break; case "Int32": AddVariantField(field, (Int32)objField.GetValue(obj)); break; case "Int64": AddVariantField(field, (Int64)objField.GetValue(obj)); break; case "UInt16": AddVariantField(field, (UInt16)objField.GetValue(obj)); break; case "UInt32": AddVariantField(field, (UInt32)objField.GetValue(obj)); break; case "UInt64": AddVariantField(field, (UInt64)objField.GetValue(obj)); break; default: Console.WriteLine("Unexpected type '" + objFieldType.Name + "'"); break; } } field++; } }