Exemplo n.º 1
0
 /// <summary>
 /// Extracts a color from binary span.
 /// If the span more than 3 bytes, the 4th byte will be interpreted as alpha.
 /// Will throw an exception if there is not at least 3 bytes.
 /// </summary>
 /// <param name="span">Span to read from</param>
 /// <param name="binaryType">Format to read the color as</param>
 /// <returns>Bytes converted to a Color object</returns>
 public static Color ReadColor(this ReadOnlyMemorySlice <byte> span, ColorBinaryType binaryType)
 {
     return(span.Span.ReadColor(binaryType));
 }
Exemplo n.º 2
0
 public static sbyte Int8(this ReadOnlyMemorySlice <byte> span)
 {
     return((sbyte)span[0]);
 }
Exemplo n.º 3
0
 public static int Int32(this ReadOnlyMemorySlice <byte> span)
 {
     return(BinaryPrimitives.ReadInt32LittleEndian(span));
 }
Exemplo n.º 4
0
 public static float Float(this ReadOnlyMemorySlice <byte> span) => BinaryPrimitives.ReadSingleLittleEndian(span);
Exemplo n.º 5
0
 public static string StringUTF8(this ReadOnlyMemorySlice <byte> span) => span.Span.StringUTF8();
Exemplo n.º 6
0
            private void ParseRegionData(OverlayStream stream, int offset)
            {
                int loc       = stream.Position - offset;
                var rdatFrame = stream.ReadSubrecordFrame();

                RegionData.RegionDataType dataType = (RegionData.RegionDataType)BinaryPrimitives.ReadUInt32LittleEndian(rdatFrame.Content);
                var len = rdatFrame.TotalLength;

                if (!stream.Complete)
                {
                    var contentMeta = stream.GetSubrecord();
                    var recType     = contentMeta.RecordType;
                    if (recType == RecordTypes.ICON)
                    {
                        var totalLen = contentMeta.TotalLength;
                        len += totalLen;
                        // Skip icon subrecord for now
                        contentMeta = stream.GetSubrecord(offset: rdatFrame.TotalLength + totalLen);
                    }
                    if (RegionBinaryCreateTranslation.IsExpected(dataType, contentMeta.RecordType))
                    {
                        len             += contentMeta.TotalLength;
                        stream.Position += contentMeta.TotalLength;
                    }
                }
                switch (dataType)
                {
                case RegionData.RegionDataType.Object:
                    _ObjectsSpan = this._data.Slice(loc, len);
                    break;

                case RegionData.RegionDataType.Map:
                    _MapSpan = this._data.Slice(loc, len);
                    break;

                case RegionData.RegionDataType.Grass:
                    _GrassesSpan = this._data.Slice(loc, len);
                    break;

                case RegionData.RegionDataType.Land:
                    _LandSpan = this._data.Slice(loc, len);
                    break;

                case RegionData.RegionDataType.Sound:
                    if (stream.TryGetSubrecord(out var nextRec) &&
                        (nextRec.RecordType.Equals(RegionBinaryCreateTranslation.RDSA) ||
                         nextRec.RecordType.Equals(RegionBinaryCreateTranslation.RDMO)))
                    {
                        len += nextRec.TotalLength;
                    }
                    _SoundsSpan = this._data.Slice(loc, len);
                    break;

                case RegionData.RegionDataType.Weather:
                    _WeatherSpan = this._data.Slice(loc, len);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
Exemplo n.º 7
0
        private static void AlignWorldChildren(
            IMutagenReadStream reader,
            MutagenWriter writer)
        {
            reader.WriteTo(writer.BaseStream, 4);
            ReadOnlyMemorySlice <byte>?roadStorage = null;
            ReadOnlyMemorySlice <byte>?cellStorage = null;
            var grupBytes = new List <ReadOnlyMemorySlice <byte> >();

            for (int i = 0; i < 3; i++)
            {
                MajorRecordHeader majorMeta = reader.GetMajorRecord();
                switch (majorMeta.RecordType.Type)
                {
                case "ROAD":
                    roadStorage = reader.ReadMemory(checked ((int)majorMeta.TotalLength));
                    break;

                case "CELL":
                    if (cellStorage != null)
                    {
                        throw new ArgumentException();
                    }
                    var startPos = reader.Position;
                    var cellMeta = reader.GetMajorRecord();
                    reader.Position += cellMeta.TotalLength;
                    var  cellGroupMeta = reader.GetGroup();
                    long cellGrupLen;
                    if (cellGroupMeta.IsGroup &&
                        cellGroupMeta.GroupType == (int)GroupTypeEnum.CellChildren)
                    {
                        cellGrupLen = cellGroupMeta.TotalLength;
                    }
                    else
                    {
                        cellGrupLen = 0;
                    }
                    reader.Position = startPos;
                    cellStorage     = reader.ReadMemory(checked ((int)(cellMeta.TotalLength + cellGrupLen)));
                    break;

                case "GRUP":
                    if (roadStorage != null &&
                        cellStorage != null)
                    {
                        i = 3;     // end loop
                        continue;
                    }
                    var groupMeta = reader.GetGroup();
                    grupBytes.Add(reader.ReadMemory(checked ((int)groupMeta.TotalLength)));
                    break;

                case "WRLD":
                    i = 3;     // end loop
                    continue;

                default:
                    throw new NotImplementedException();
                }
            }
            if (roadStorage != null)
            {
                writer.Write(roadStorage.Value);
            }
            if (cellStorage != null)
            {
                writer.Write(cellStorage.Value);
            }
            foreach (var item in grupBytes)
            {
                writer.Write(item);
            }
        }
Exemplo n.º 8
0
 public GroupHeader Group(ReadOnlyMemorySlice <byte> span) => new GroupHeader(this, span);
Exemplo n.º 9
0
 public GroupFrame GroupFrame(ReadOnlyMemorySlice <byte> span) => new GroupFrame(this, span);
Exemplo n.º 10
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="meta">Game metadata to use as reference for alignment</param>
 /// <param name="span">Span to overlay on, aligned to the start of the Group's header</param>
 public ModHeader(GameConstants meta, ReadOnlyMemorySlice <byte> span)
 {
     this.Meta = meta;
     this.Span = span.Slice(0, meta.ModHeaderLength);
 }
Exemplo n.º 11
0
 public ModHeader ModHeader(ReadOnlyMemorySlice <byte> span) => new ModHeader(this, span);
Exemplo n.º 12
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="constants">Record constants to use as reference for alignment</param>
 /// <param name="span">Span to overlay on, aligned to the start of the header</param>
 public VariableHeader(RecordHeaderConstants constants, ReadOnlyMemorySlice <byte> span)
 {
     this.Constants = constants;
     this.Span      = span.Slice(0, constants.HeaderLength);
 }
Exemplo n.º 13
0
 public NumberedEnumList(ReadOnlyMemorySlice <byte> mem, int amount, byte enumLength)
 {
     this.Amount     = amount;
     this.Memory     = mem;
     this.EnumLength = enumLength;
 }
Exemplo n.º 14
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="meta">Game metadata to use as reference for alignment</param>
 /// <param name="span">Span to overlay on, aligned to the start of the Major Record's header</param>
 public MajorRecordHeader(GameConstants meta, ReadOnlyMemorySlice <byte> span)
 {
     this.Meta       = meta;
     this.HeaderData = span.Slice(0, meta.MajorConstants.HeaderLength);
 }
Exemplo n.º 15
0
        public static ReadOnlyMemorySlice <byte> ExtractSubrecordMemory(ReadOnlyMemorySlice <byte> span, int loc, GameConstants meta)
        {
            var subMeta = meta.Subrecord(span.Slice(loc));

            return(span.Slice(loc + subMeta.HeaderLength, subMeta.ContentLength));
        }
Exemplo n.º 16
0
 public MajorRecordHeader MajorRecord(ReadOnlyMemorySlice <byte> span) => new MajorRecordHeader(this, span);
Exemplo n.º 17
0
        public static ReadOnlyMemorySlice <byte> ExtractSubrecordMemory(ReadOnlyMemorySlice <byte> span, GameConstants meta, TypedParseParams?parseParams = null)
        {
            var subMeta = meta.Subrecord(span);

            return(span.Slice(subMeta.HeaderLength, parseParams?.LengthOverride ?? subMeta.ContentLength));
        }
Exemplo n.º 18
0
 public MajorRecordFrame MajorRecordFrame(ReadOnlyMemorySlice <byte> span) => new MajorRecordFrame(this, span);
Exemplo n.º 19
0
        private static void AlignMajorRecordsByRules(
            IMutagenReadStream inputStream,
            MutagenWriter writer,
            AlignmentRules alignmentRules,
            RecordLocator.FileLocations fileLocs)
        {
            while (!inputStream.Complete)
            {
                // Import until next listed major record
                long noRecordLength;
                if (fileLocs.ListedRecords.TryGetInDirection(
                        inputStream.Position,
                        higher: true,
                        result: out var nextRec))
                {
                    var recordLocation = fileLocs.ListedRecords.Keys[nextRec.Key];
                    noRecordLength = recordLocation - inputStream.Position;
                }
                else
                {
                    noRecordLength = inputStream.Remaining;
                }
                inputStream.WriteTo(writer.BaseStream, (int)noRecordLength);

                // If complete overall, return
                if (inputStream.Complete)
                {
                    break;
                }

                var recType = HeaderTranslation.ReadNextRecordType(
                    inputStream,
                    out var len);
                IEnumerable <RecordType>?stopMarkers;
                if (!alignmentRules.StopMarkers.TryGetValue(recType, out stopMarkers))
                {
                    stopMarkers = null;
                }
                if (!alignmentRules.Alignments.TryGetValue(recType, out var alignments))
                {
                    throw new ArgumentException($"Encountered an unknown record: {recType}");
                }
                writer.Write(recType.TypeInt);
                writer.Write(len);
                inputStream.WriteTo(writer.BaseStream, 12);
                var endPos = inputStream.Position + len;
                Dictionary <RecordType, byte[]> dataDict = new Dictionary <RecordType, byte[]>();
                ReadOnlyMemorySlice <byte>?     rest     = null;
                while (inputStream.Position < endPos)
                {
                    var subType = HeaderTranslation.GetNextSubrecordType(
                        inputStream,
                        out var subLen);
                    if (stopMarkers?.Contains(subType) ?? false)
                    {
                        rest = inputStream.ReadMemory((int)(endPos - inputStream.Position), readSafe: true);
                        break;
                    }
                    if (!alignments.TryGetValue(subType, out var rule))
                    {
                        throw new ArgumentException($"Encountered an unknown record: {subType}");
                    }
                    dataDict[subType] = rule.GetBytes(inputStream);
                }
                foreach (var alignment in alignmentRules.Alignments[recType])
                {
                    if (dataDict.TryGetValue(
                            alignment.Key,
                            out var data))
                    {
                        writer.Write(data);
                        dataDict.Remove(alignment.Key);
                    }
                }
                if (dataDict.Count > 0)
                {
                    throw new ArgumentException($"Encountered an unknown record: {dataDict.First().Key}");
                }
                if (rest != null)
                {
                    writer.Write(rest.Value);
                }
            }
        }
Exemplo n.º 20
0
 public SubrecordHeader Subrecord(ReadOnlyMemorySlice <byte> span) => new SubrecordHeader(this, span);
Exemplo n.º 21
0
        /// <summary>
        /// Parses span data and enumerates pairs of record type -> locations
        ///
        /// It is assumed the span contains only subrecords
        /// </summary>
        /// <param name="span">Bytes containing subrecords</param>
        /// <param name="meta">Metadata to use in subrecord parsing</param>
        /// <returns>Enumerable of KeyValue pairs of encountered RecordTypes and their locations relative to the input span</returns>
        public static IEnumerable <KeyValuePair <RecordType, int> > EnumerateSubrecords(ReadOnlyMemorySlice <byte> span, GameConstants meta)
        {
            int loc = 0;

            while (span.Length > loc)
            {
                var subMeta = meta.Subrecord(span.Slice(loc));
                var len     = subMeta.TotalLength;
                yield return(new KeyValuePair <RecordType, int>(subMeta.RecordType, loc));

                loc += len;
            }
        }
Exemplo n.º 22
0
 public SubrecordFrame SubrecordFrame(ReadOnlyMemorySlice <byte> span) => new SubrecordFrame(this, span);
Exemplo n.º 23
0
 public static double Double(this ReadOnlyMemorySlice <byte> span) => BinaryPrimitives.ReadDoubleLittleEndian(span);
Exemplo n.º 24
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="meta">Game metadata to use as reference for alignment</param>
 /// <param name="span">Span to overlay on, aligned to the start of the header</param>
 public GroupFrame(GameConstants meta, ReadOnlyMemorySlice <byte> span)
 {
     this._header = meta.Group(span);
     this.HeaderAndContentData = span.Slice(0, checked ((int)this._header.TotalLength));
 }
Exemplo n.º 25
0
 public static byte UInt8(this ReadOnlyMemorySlice <byte> span)
 {
     return(span[0]);
 }
Exemplo n.º 26
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="header">Existing GroupHeader struct</param>
 /// <param name="span">Span to overlay on, aligned to the start of the Group's header</param>
 public GroupFrame(GroupHeader header, ReadOnlyMemorySlice <byte> span)
 {
     this._header = header;
     this.HeaderAndContentData = span.Slice(0, checked ((int)this._header.TotalLength));
 }
Exemplo n.º 27
0
 public static ushort UInt16(this ReadOnlyMemorySlice <byte> span)
 {
     return(BinaryPrimitives.ReadUInt16LittleEndian(span));
 }
Exemplo n.º 28
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="meta">Game metadata to use as reference for alignment</param>
 /// <param name="span">Span to overlay on, aligned to the start of the Group's header</param>
 public GroupHeader(GameConstants meta, ReadOnlyMemorySlice <byte> span)
 {
     this.Meta       = meta;
     this.HeaderData = span.Slice(0, meta.GroupConstants.HeaderLength);
 }
Exemplo n.º 29
0
 public static ulong UInt64(this ReadOnlyMemorySlice <byte> span)
 {
     return(BinaryPrimitives.ReadUInt64LittleEndian(span));
 }
Exemplo n.º 30
0
 public VariableHeader VariableMeta(ReadOnlyMemorySlice <byte> span) => new VariableHeader(this, span);