コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
            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();
            }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
    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);
    }
コード例 #7
0
 /// <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);
 }
コード例 #8
0
        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);
コード例 #9
0
 public void BodyAndComposeAttributeAtSameTimeTest()
 {
     Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(ComposeAndBodyAttribute <MockOnlyMetaData>), new BitConverterHelper(null)));
 }
コード例 #10
0
 public void DuplicateComposeAttributeErrorTest()
 {
     Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(DuplicateComposeAttribute <MockOnlyMetaData>), new BitConverterHelper(null)));
 }
コード例 #11
0
 public void KeyDoesNotHaveSetterErrorTest()
 {
     Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(KeyDoesNotHaveSetter), new BitConverterHelper(null)));
 }
コード例 #12
0
 public void DoesNotHaveBodyLengthAttributeErrorTest()
 {
     Assert.Catch(typeof(BinaryException), () => BinaryCache.GetOrAddContext(typeof(DoesNotHaveBodyLengthAttribute), new BitConverterHelper(null)));
 }
コード例 #13
0
ファイル: XObjectParser.cs プロジェクト: noidelsucre/OpenBVE
		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;
			}
		}
コード例 #14
0
ファイル: XObjectParser.cs プロジェクト: noidelsucre/OpenBVE
		// ================================

		// 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;
		}
コード例 #15
0
        /// <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();
                }
            }
        }