Esempio n. 1
0
        // Methods to write Binary Serialization Record onto the stream, a record is composed of primitive types

        internal void WriteSerializationHeader(int topId, int headerId, int minorVersion, int majorVersion)
        {
            SerializationHeaderRecord record = new SerializationHeaderRecord(BinaryHeaderEnum.SerializedStreamHeader, topId, headerId, minorVersion, majorVersion);

            record.Dump();
            record.Write(this);
        }
        IRecordObject IRecordTypeHandler.Handle(IAnalyze analyze)
        {
            //EOF
            //感觉是无意义的数据
            while (analyze.Reader.BaseStream.Position < analyze.Reader.BaseStream.Length)
            {
                if (analyze.Reader.BaseStream.Position == 1)
                {
                    break;
                }
                else
                {
                    return(null);
                }
            }

            var record = new SerializationHeaderRecord();

            record.RootId       = analyze.Reader.ReadInt32();
            record.HeaderId     = analyze.Reader.ReadInt32();
            record.MajorVersion = analyze.Reader.ReadInt32();
            record.MinorVersion = analyze.Reader.ReadInt32();

            return(record);
        }
Esempio n. 3
0
        /// <summary>
        /// Attempt to dump a set of classes that can be used to deserialize a .NET binary stream
        /// </summary>
        /// <param name="argument">The file to parse</param>
        /// <param name="classPrefix">Search for classes with the specified prefix (supports multiple)</param>
        /// <param name="fullScan">Search every possible class structure</param>
        /// <param name="namespaceToOutput">The namespace to use in the output files</param>
        /// <param name="outputPath">Where to output the files, if not supplied will create an 'generated' directory in the input directory</param>
        /// <returns></returns>
        private static int Main(
            FileInfo argument,
            string[] classPrefix,
            bool fullScan,
            string namespaceToOutput = "DeserializeClassBuilder",
            DirectoryInfo outputPath = null
            )
        {
            if (!fullScan && (classPrefix == null || classPrefix.Length < 1))
            {
                Console.WriteLine("Either --full-scan or --class-prefix must be specified");
                return(1);
            }

            if (fullScan && classPrefix != null && classPrefix.Length > 0)
            {
                Console.WriteLine("You must choose either --full-scan or --class-prefix, not both.");
                return(1);
            }

            try
            {
                var outputPathString = outputPath == null
                    ? Path.Combine(Path.GetDirectoryName(argument.FullName), $"{argument.Name}.generated")
                    : outputPath.FullName;

                if (!Directory.Exists(outputPathString) && !Directory.CreateDirectory(outputPathString).Exists)
                {
                    Console.WriteLine($"Failed to create output path: \"{argument.FullName}\"");
                    return(1);
                }

                using var fileStream = File.OpenRead(argument.FullName);
                using var reader     = new DeserializeReader(fileStream);

                // Make sure we have a valid header before looking
                // TODO Improve the structure checking in SerializationHeaderRecord, it currenly only checks the first
                //      byte while checking the type.
                var header = new SerializationHeaderRecord(reader);

                // Search through the file for positions to check
                var positions = FindPositions(fileStream, fullScan, classPrefix);

                Console.WriteLine(
                    $"Found {positions.Length.ToString("N0", CultureInfo.InvariantCulture)} locations to check in" +
                    $" \"{argument.Name}\""
                    );

                // Store the percent so we only re-render when changed
                var renderedPercent = 0.0;

                // Check the found positions for class structures
                var classes = ScanForClasses(reader, positions, (int currentIndex) =>
                {
                    var percent = Math.Round((double)currentIndex / (double)positions.Length * 100, 0);
                    if (renderedPercent != percent)
                    {
                        Console.Write($"\r({percent}%) ");
                        renderedPercent = percent;
                    }
                });

                // Overwrite the last % line
                Console.Write($"\r{new string(' ', "(100.00%) ".Length)}\r");

                foreach (var structure in classes)
                {
                    WriteClass(structure, outputPathString, namespaceToOutput);
                }

                return(0);
            }
            catch (Exception e) when(e is DirectoryNotFoundException || e is FileNotFoundException)
            {
                Console.WriteLine($"File not found: \"{argument.FullName}\"");
                return(1);
            }
            catch (DeserializeException e)
            {
                Console.WriteLine($"Unexpected file structure: {e.Message}");
                return(1);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception e)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                Console.WriteLine($"Fatal error: {e.Message}");
#if DEBUG
                Debugger.Break();
#endif
                return(1);
            }
        }