public void WriteValues <T>(Memory <T> memory) { var values = memory.Span; var buffer = _bufferOwner.Memory; var isPrimitive = PrimitiveTypes.Primitives.Contains(typeof(T)); var sizeOfElem = isPrimitive ? _sizing.SizeOf <T>() : 0; if (!isPrimitive) // no size check bc it's checked on write calls from cache { foreach (var value in values) { BinaryCache <T> .WriteValue(this, value); } return; } var sizeOf = sizeOfElem * values.Length; if (Remaining < sizeOf) { throw new ArgumentOutOfRangeException(nameof(Remaining), $"Not enough bytes remaining in the buffer to write {typeof(T).Name} array. " + $"Position : {Position}, Length : {Count}, Remaining : {Remaining}, SizeOf : {sizeOf}."); } var offset = Position; for (var i = 0; i < values.Length; i++, offset += sizeOfElem) { var dst = buffer.Slice(offset, sizeOfElem); PrimitiveBinaryCache <T> .WriteValue(dst.Span, values[i]); } Advance(sizeOf); }
public void WriteValue <T>(T value) { var isPrimitive = PrimitiveTypes.Primitives.Contains(typeof(T)); var sizeOf = isPrimitive ? _sizing.SizeOf <T>() : _sizing.SizeOf(value); if (Remaining < sizeOf) { throw new ArgumentOutOfRangeException(nameof(Remaining), $"Not enough bytes remaining in the buffer to write {typeof(T).Name}. " + $"Position : {Position}, Length : {Count}, Remaining : {Remaining}, SizeOf : {sizeOf}."); } if (!isPrimitive) { BinaryCache <T> .WriteValue(this, value); return; } var dst = _bufferOwner.Memory.Slice(Position, sizeOf); PrimitiveBinaryCache <T> .WriteValue(dst.Span, value); Advance(sizeOf); }
static void Main(string[] args) { bool is_verbose = false; bool show_help = false; OptionSet opts = new OptionSet() { { "v|verbose", "redirect debug traces to console", v => is_verbose = v != null }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List <string> eps = opts.Parse(args); if (show_help) { ShowHelp(opts); return; } if (is_verbose) { // Redirect debug log to the console Debug.Listeners.Add(new TextWriterTraceListener(Console.Out)); Debug.AutoFlush = true; } // always the first call to make Phlib.InitializePhLib(); BinaryCache.Instance.Load(); foreach (var peFilePath in eps) { PE Pe = BinaryCache.LoadPe(peFilePath); Console.WriteLine("Loaded PE file : {0:s}", Pe.Filepath); } BinaryCache.Instance.Unload(); }
public T[] ReadValues <T>(int count) { if (count == 0) { return(Array.Empty <T>()); } var value = new T[count]; if (!PrimitiveTypes.Primitives.Contains(typeof(T))) { for (var i = 0; i < count; i++) { value[i] = BinaryCache <T> .ReadValue(this); } return(value); } var sizeOfElem = PrimitiveBinaryCache <T> .SizeOf; var sizeOfArray = sizeOfElem * count; if (Remaining < sizeOfArray) { throw new ArgumentOutOfRangeException(nameof(Remaining), $"Not enough bytes remaining in the buffer to read {typeof(T).Name} array with elements count : {count}. " + $"Position : {Position}, Length : {Count}, Remaining : {Remaining}, SizeOf : {sizeOfArray}."); } var offset = Position; for (var i = 0; i < count; i++, offset += sizeOfElem) { var src = _buffer.Slice(offset, sizeOfElem); value[i] = PrimitiveBinaryCache <T> .ReadValue(src.Span); } Advance(sizeOfArray); return(value); }
public T ReadValue <T>() { if (!PrimitiveTypes.Primitives.Contains(typeof(T))) { return(BinaryCache <T> .ReadValue(this)); } var sizeOfT = PrimitiveBinaryCache <T> .SizeOf; if (Remaining < sizeOfT) { throw new ArgumentOutOfRangeException(nameof(Remaining), $"Not enough bytes remaining in the buffer to read {typeof(T).Name}. " + $"Position : {Position}, Length : {Count}, Remaining : {Remaining}, SizeOf : {sizeOfT}."); } var src = _buffer.Slice(Position, sizeOfT); var value = PrimitiveBinaryCache <T> .ReadValue(src.Span); Advance(sizeOfT); return(value); }
public DisplayPeImport( PeImport PeImport, PhSymbolProvider SymPrv, string ModuleFilePath ) { Info.ordinal = PeImport.Ordinal; Info.hint = PeImport.Hint; Info.name = PeImport.Name; Info.moduleName = PeImport.ModuleName; Info.modulePath = ModuleFilePath; Info.UndecoratedName = SymPrv.UndecorateName(PeImport.Name); Info.delayedImport = PeImport.DelayImport; Info.importAsCppName = (PeImport.Name.Length > 0 && PeImport.Name[0] == '?'); Info.importByOrdinal = PeImport.ImportByOrdinal; Info.importNotFound = !BinaryCache.LookupImport(ModuleFilePath, PeImport.Name, PeImport.Ordinal, PeImport.ImportByOrdinal); AddNewEventHandler("Undecorate", "Undecorate", "Name", this.GetDisplayName); AddNewEventHandler("FullPath", "FullPath", "ModuleName", this.GetPathDisplayName); }
/// <inheritdoc /> public void SendJson(object item, bool asText = false, bool?prettyPrint = null, bool ignoreNulls = false) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (!BinaryCache.TryGet(item, out var body)) { Formatting _prettyPrint; if (prettyPrint == null) { _prettyPrint = Admin.Settings._PrettyPrint ? Formatting.Indented : Formatting.None; } else { _prettyPrint = prettyPrint.Value ? Formatting.Indented : Formatting.None; } var stream = Providers.Json.SerializeStream(item, _prettyPrint, ignoreNulls); body = stream.ToArray(); BinaryCache.Cache(item, body); } _SendBinary(body, asText, 0, body.Length); }
private static StandartSerializeResult InternalSerialize(object data, BinarySerializerContext context) { int realLength; byte[] serializedBody = null; StandartSerializeResult composeSerializeResult = null; var examined = 0; if (context.ReflectionData.BodyProperty != null) { var bodyValue = context.ReflectionData.BodyProperty.Get(data); if (bodyValue == null) { throw BinaryException.SerializerBodyPropertyIsNull(); } serializedBody = context.BitConverterHelper.ConvertToBytes(bodyValue, context.ReflectionData.BodyProperty.Type, context.ReflectionData.BodyProperty.Attribute.Reverse); realLength = CalculateRealLength(context.ReflectionData.LengthProperty, data, context.ReflectionData.MetaLength, serializedBody.Length); } else if (context.ReflectionData.ComposeProperty != null) { var composeValue = context.ReflectionData.ComposeProperty.Get(data); if (composeValue == null) { throw BinaryException.SerializerComposePropertyIsNull(); } if (context.ReflectionData.ComposeProperty.Type.IsPrimitive) { serializedBody = context.BitConverterHelper.ConvertToBytes(composeValue, context.ReflectionData.ComposeProperty.Type, context.ReflectionData.ComposeProperty.Attribute.Reverse); realLength = CalculateRealLength(context.ReflectionData.LengthProperty, data, context.ReflectionData.MetaLength, serializedBody.Length); } else { var composeContext = BinaryCache.GetOrAddContext(context.ReflectionData.ComposeProperty.Type, context.BitConverterHelper); composeSerializeResult = InternalSerialize(composeValue, composeContext); realLength = CalculateRealLength(context.ReflectionData.LengthProperty, data, context.ReflectionData.MetaLength, composeSerializeResult.Length); } } else { realLength = context.ReflectionData.MetaLength; } var serializeResult = new StandartSerializeResult(realLength, composeSerializeResult); var bytes = serializeResult.Bytes; foreach (var property in context.ReflectionData.Properties) { if (!property.Type.IsPrimitive && property.Attribute.BinaryDataType == BinaryDataType.Compose && composeSerializeResult != null) { Array.Copy( composeSerializeResult.Bytes, 0, bytes, property.Attribute.Index, composeSerializeResult.Length ); } else { var value = property.Attribute.BinaryDataType == BinaryDataType.Body || property.Attribute.BinaryDataType == BinaryDataType.Compose ? serializedBody ?? throw BinaryException.SerializerBodyPropertyIsNull() : context.BitConverterHelper.ConvertToBytes(property.Get(data), property.Type, property.Attribute.Reverse); var valueLength = value.Length; if (property.Attribute.BinaryDataType != BinaryDataType.Body && property.Attribute.BinaryDataType != BinaryDataType.Compose && valueLength > property.Attribute.Length) { throw BinaryException.SerializerLengthOutOfRange(property.Type.ToString(), valueLength.ToString(), property.Attribute.Length.ToString()); } value.CopyTo(bytes, property.Attribute.Index); } if (++examined == context.ReflectionData.Properties.Count) { break; } } return(serializeResult);
public void BodyAndComposeAttributeAtSameTimeTest() { Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(ComposeAndBodyAttribute <MockOnlyMetaData>), new BitConverterHelper(null))); }
public void DuplicateComposeAttributeErrorTest() { Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(DuplicateComposeAttribute <MockOnlyMetaData>), new BitConverterHelper(null))); }
public void KeyDoesNotHaveSetterErrorTest() { Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(KeyDoesNotHaveSetter), new BitConverterHelper(null))); }
public void DoesNotHaveBodyLengthAttributeErrorTest() { Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(DoesNotHaveBodyLengthAttribute), new BitConverterHelper(null))); }
private static bool ReadBinaryTemplate(string FileName, System.IO.BinaryReader Reader, int FloatingPointSize, Template Template, bool Inline, ref BinaryCache Cache, out Structure Structure) { const short TOKEN_NAME = 0x1; const short TOKEN_STRING = 0x2; const short TOKEN_INTEGER = 0x3; const short TOKEN_INTEGER_LIST = 0x6; const short TOKEN_FLOAT_LIST = 0x7; const short TOKEN_OBRACE = 0xA; const short TOKEN_CBRACE = 0xB; const short TOKEN_COMMA = 0x13; const short TOKEN_SEMICOLON = 0x14; Structure = new Structure(Template.Name, new object[] { }); System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture; System.Text.ASCIIEncoding Ascii = new System.Text.ASCIIEncoding(); int m; for (m = 0; m < Template.Members.Length; m++) { if (Template.Members[m] == "[???]") { // unknown template int Level = 0; if (Cache.IntegersRemaining != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "An integer list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); } else if (Cache.FloatsRemaining != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "A float list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); } short Token = Reader.ReadInt16(); switch (Token) { case TOKEN_NAME: { Level++; int n = Reader.ReadInt32(); if (n < 1) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_NAME at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } Reader.BaseStream.Position += n; Token = Reader.ReadInt16(); if (Token != TOKEN_OBRACE) { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_OBRACE expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } break; case TOKEN_INTEGER: { Reader.BaseStream.Position += 4; } break; case TOKEN_INTEGER_LIST: { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_INTEGER_LIST at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } Reader.BaseStream.Position += 4 * n; } break; case TOKEN_FLOAT_LIST: { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_FLOAT_LIST at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } Reader.BaseStream.Position += (FloatingPointSize >> 3) * n; } break; case TOKEN_STRING: { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_STRING at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } Reader.BaseStream.Position += n; Token = Reader.ReadInt16(); if (Token != TOKEN_COMMA & Token != TOKEN_SEMICOLON) { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_COMMA or TOKEN_SEMICOLON expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } break; case TOKEN_OBRACE: Interface.AddMessage(Interface.MessageType.Error, false, "Unexpected token TOKEN_OBRACE encountered at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; case TOKEN_CBRACE: if (Level == 0) return true; Level--; break; default: Interface.AddMessage(Interface.MessageType.Error, false, "Unknown token encountered at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } m--; } else if (Template.Members[m] == "[...]") { // any template if (Cache.IntegersRemaining != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "An integer list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); } else if (Cache.FloatsRemaining != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "A float list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); } if (Template.Name.Length == 0 && Reader.BaseStream.Position == Reader.BaseStream.Length) { // end of file return true; } short Token = Reader.ReadInt16(); switch (Token) { case TOKEN_NAME: int n = Reader.ReadInt32(); if (n < 1) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_NAME at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } string Name = new string(Ascii.GetChars(Reader.ReadBytes(n))); Token = Reader.ReadInt16(); if (Token != TOKEN_OBRACE) { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_OBRACE expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } Structure o; if (!ReadBinaryTemplate(FileName, Reader, FloatingPointSize, GetTemplate(Name), false, ref Cache, out o)) { return false; } Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = o; break; case TOKEN_CBRACE: if (Template.Name.Length == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "Unexpected TOKEN_CBRACE encountered at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } m++; break; default: Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_NAME or TOKEN_CBRACE expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } m--; } else if (Template.Members[m].EndsWith("]", StringComparison.Ordinal)) { // inlined array expected string r = Template.Members[m].Substring(0, Template.Members[m].Length - 1); int h = r.IndexOf('['); if (h >= 0) { string z = r.Substring(h + 1, r.Length - h - 1); r = r.Substring(0, h); if (!int.TryParse(z, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out h)) { Interface.AddMessage(Interface.MessageType.Error, false, "The internal format description for a template array is invalid in template " + Template.Name + " in binary X object file " + FileName); return false; } if (h < 0 || h >= Structure.Data.Length || !(Structure.Data[h] is int)) { Interface.AddMessage(Interface.MessageType.Error, false, "The internal format description for a template array is invalid in template " + Template.Name + " in binary X object file " + FileName); return false; } h = (int)Structure.Data[h]; } else { Interface.AddMessage(Interface.MessageType.Error, false, "The internal format description for a template array is invalid in template " + Template.Name + " in binary X object file " + FileName); return false; } if (r == "DWORD") { // dword array int[] o = new int[h]; for (int i = 0; i < h; i++) { if (Cache.IntegersRemaining != 0) { // use cached integer int a = Cache.Integers[Cache.IntegersRemaining - 1]; Cache.IntegersRemaining--; o[i] = a; } else if (Cache.FloatsRemaining != 0) { // cannot use cached float Interface.AddMessage(Interface.MessageType.Error, false, "A float list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } else { while (true) { short Token = Reader.ReadInt16(); if (Token == TOKEN_INTEGER) { int a = Reader.ReadInt32(); o[i] = a; break; } else if (Token == TOKEN_INTEGER_LIST) { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_INTEGER_LIST at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } if (n != 0) { Cache.Integers = new int[n]; for (int j = 0; j < n; i++) { Cache.Integers[n - j - 1] = Reader.ReadInt32(); } Cache.IntegersRemaining = n - 1; int a = Cache.Integers[Cache.IntegersRemaining]; o[i] = a; break; } } else { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_INTEGER or TOKEN_INTEGER_LIST expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } } } Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = o; } else if (r == "float") { // float array double[] o = new double[h]; for (int i = 0; i < h; i++) { if (Cache.IntegersRemaining != 0) { // cannot use cached integer Interface.AddMessage(Interface.MessageType.Error, false, "An integer list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } else if (Cache.FloatsRemaining != 0) { // use cached float double a = Cache.Floats[Cache.FloatsRemaining - 1]; Cache.FloatsRemaining--; o[i] = a; } else { while (true) { short Token = Reader.ReadInt16(); if (Token == TOKEN_FLOAT_LIST) { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_FLOAT_LIST at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } if (n != 0) { Cache.Floats = new double[n]; for (int j = 0; j < n; i++) { if (FloatingPointSize == 32) { Cache.Floats[n - j - 1] = (double)Reader.ReadSingle(); } else if (FloatingPointSize == 64) { Cache.Floats[n - j - 1] = Reader.ReadDouble(); } } Cache.FloatsRemaining = n - 1; double a = Cache.Floats[Cache.FloatsRemaining]; o[i] = a; break; } } else { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_FLOAT_LIST expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } } } Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = o; } else { // template array Structure[] o = new Structure[h]; for (int i = 0; i < h; i++) { ReadBinaryTemplate(FileName, Reader, FloatingPointSize, GetTemplate(r), true, ref Cache, out o[i]); } Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = o; } } else { // inlined template or primitive expected switch (Template.Members[m]) { case "DWORD": // dword expected if (Cache.IntegersRemaining != 0) { // use cached integer int a = Cache.Integers[Cache.IntegersRemaining - 1]; Cache.IntegersRemaining--; Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = a; } else if (Cache.FloatsRemaining != 0) { // cannot use cached float Interface.AddMessage(Interface.MessageType.Error, false, "A float list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } else { // read new data while (true) { short Token = Reader.ReadInt16(); if (Token == TOKEN_INTEGER) { int a = Reader.ReadInt32(); Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = a; break; } else if (Token == TOKEN_INTEGER_LIST) { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_INTEGER_LIST at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } if (n != 0) { Cache.Integers = new int[n]; for (int i = 0; i < n; i++) { Cache.Integers[n - i - 1] = Reader.ReadInt32(); } Cache.IntegersRemaining = n - 1; int a = Cache.Integers[Cache.IntegersRemaining]; Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = a; break; } } else { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_INTEGER or TOKEN_INTEGER_LIST expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } } break; case "float": // float expected if (Cache.IntegersRemaining != 0) { // cannot use cached integer Interface.AddMessage(Interface.MessageType.Error, false, "An integer list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } else if (Cache.FloatsRemaining != 0) { // use cached float double a = Cache.Floats[Cache.FloatsRemaining - 1]; Cache.FloatsRemaining--; Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = a; } else { // read new data while (true) { short Token = Reader.ReadInt16(); if (Token == TOKEN_FLOAT_LIST) { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_FLOAT_LIST at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } if (n != 0) { Cache.Floats = new double[n]; for (int i = 0; i < n; i++) { if (FloatingPointSize == 32) { Cache.Floats[n - i - 1] = (double)Reader.ReadSingle(); } else if (FloatingPointSize == 64) { Cache.Floats[n - i - 1] = Reader.ReadDouble(); } } Cache.FloatsRemaining = n - 1; double a = Cache.Floats[Cache.FloatsRemaining]; Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = a; break; } } else { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_FLOAT_LIST expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } } break; case "string": { // string expected if (Cache.IntegersRemaining != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "An integer list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); } else if (Cache.FloatsRemaining != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "A float list was not depleted at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); } short Token = Reader.ReadInt16(); if (Token == TOKEN_STRING) { int n = Reader.ReadInt32(); if (n < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "count is invalid in TOKEN_STRING at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } string s = new string(Ascii.GetChars(Reader.ReadBytes(n))); Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = s; Token = Reader.ReadInt16(); if (Token != TOKEN_SEMICOLON) { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_SEMICOLON expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } else { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_STRING expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } break; default: // inlined template expected Structure o; ReadBinaryTemplate(FileName, Reader, FloatingPointSize, GetTemplate(Template.Members[m]), true, ref Cache, out o); Array.Resize<object>(ref Structure.Data, Structure.Data.Length + 1); Structure.Data[Structure.Data.Length - 1] = o; break; } } } if (Inline) { return true; } else { string s = Template.Members[Template.Members.Length - 1]; if (s != "[???]" & s != "[...]") { int Token = Reader.ReadInt16(); if (Token != TOKEN_CBRACE) { Interface.AddMessage(Interface.MessageType.Error, false, "TOKEN_CBRACE expected at position 0x" + Reader.BaseStream.Position.ToString("X", Culture) + " in binary X object file " + FileName); return false; } } return true; } }
// ================================ // load binary x private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, System.Text.Encoding Encoding, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { // parse file Structure Structure; try { bool Result; using (System.IO.MemoryStream Stream = new System.IO.MemoryStream(Data)) { using (System.IO.BinaryReader Reader = new System.IO.BinaryReader(Stream)) { Stream.Position = StartingPosition; BinaryCache Cache = new BinaryCache(); Cache.IntegersRemaining = 0; Cache.FloatsRemaining = 0; Result = ReadBinaryTemplate(FileName, Reader, FloatingPointSize, new Template("", new string[] { "[...]" }), false, ref Cache, out Structure); Reader.Close(); } Stream.Close(); } if (!Result) { return null; } } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Error, false, "Unhandled error (" + ex.Message + ") encountered in binary X object file " + FileName); return null; } // process structure ObjectManager.StaticObject Object; if (!ProcessStructure(FileName, Structure, out Object, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY)) { return null; } return Object; }
/// <inheritdoc /> public void SendResult(IResult result, TimeSpan?timeElapsed = null, bool writeHeaders = false, bool disposeResult = true) { try { switch (Status) { case WebSocketStatus.Open: break; case var other: throw new InvalidOperationException($"Unable to send results to a WebSocket with status '{other}'"); } if (result is WebSocketUpgradeSuccessful) { return; } var serialized = result.IsSerialized ? (ISerializedResult)result : result.Serialize(); if (serialized is Content content && content.IsLocked) { throw new InvalidOperationException("Unable to send a result that is already assigned to a Websocket streaming " + "job. Streaming results are locked, and can only be streamed once."); } var foundCached = BinaryCache.TryGet(serialized, out var body); if (!foundCached && serialized.Body?.CanRead == false) { throw new InvalidOperationException($"Unable to send a disposed result over Websocket '{Id}'. To send the " + "same result multiple times, set 'disposeResult' to false in the call to " + "'SendResult()'."); } var info = result.Headers.Info; var errorInfo = result.Headers.Error; var timeInfo = ""; if (timeElapsed != null) { timeInfo = $" ({timeElapsed.Value.TotalMilliseconds} ms)"; } var tail = ""; if (info != null) { tail += $". {info}"; } if (errorInfo != null) { tail += $" (see {errorInfo})"; } _SendText($"{result.StatusCode.ToCode()}: {result.StatusDescription}{timeInfo}{tail}"); if (writeHeaders) { SendJson(result.Headers, true); } if (body == null && serialized.Body != null && (!serialized.Body.CanSeek || serialized.Body.Length > 0)) { body = serialized.Body.ToByteArray(); } if (body != null) { if (!foundCached) { BinaryCache.Cache(serialized, body); } SendBinary(body, 0, body.Length); } } finally { if (disposeResult) { result.Dispose(); } } }