Esempio n. 1
0
 bool GetDataCustom() => _DataLocation.HasValue ? BinaryPrimitives.ReadInt32LittleEndian(HeaderTranslation.ExtractSubrecordMemory(_data, _DataLocation.Value, _package.MetaData.Constants)) != 0 : default;
Esempio n. 2
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);
                }
            }
        }
Esempio n. 3
0
            static partial void CustomBinaryEndImport(MutagenFrame frame, IWorldspaceInternal obj)
            {
                try
                {
                    if (!frame.Reader.TryReadGroup(out var groupHeader))
                    {
                        return;
                    }
                    if (groupHeader.GroupType == (int)GroupTypeEnum.WorldChildren)
                    {
                        obj.SubCellsTimestamp = BinaryPrimitives.ReadInt32LittleEndian(groupHeader.LastModifiedData);
                        obj.SubCellsUnknown   = BinaryPrimitives.ReadInt32LittleEndian(groupHeader.HeaderData.Slice(groupHeader.HeaderLength - 4));
                        var formKey = FormKeyBinaryTranslation.Instance.Parse(groupHeader.ContainedRecordTypeData, frame.MetaData.MasterReferences !);
                        if (formKey != obj.FormKey)
                        {
                            throw new ArgumentException("Cell children group did not match the FormID of the parent worldspace.");
                        }
                    }
                    else
                    {
                        frame.Reader.Position -= groupHeader.HeaderLength;
                        return;
                    }
                    frame.MetaData.InWorldspace = true;
                    try
                    {
                        var subFrame = MutagenFrame.ByLength(frame.Reader, groupHeader.ContentLength);
                        for (int i = 0; i < 2; i++)
                        {
                            if (subFrame.Complete)
                            {
                                return;
                            }
                            var subType = HeaderTranslation.GetNextSubrecordType(frame.Reader, out var subLen);
                            switch (subType.TypeInt)
                            {
                            case 0x4C4C4543:     // "CELL":
                                if (LoquiBinaryTranslation <Cell> .Instance.Parse(subFrame, out var topCell))
                                {
                                    obj.TopCell = topCell;
                                }
                                else
                                {
                                    obj.TopCell = default;
                                }
                                break;

                            case 0x50555247:     // "GRUP":
                                obj.SubCells.SetTo(
                                    Mutagen.Bethesda.Binary.ListBinaryTranslation <WorldspaceBlock> .Instance.Parse(
                                        frame: frame,
                                        triggeringRecord: RecordTypes.GRUP,
                                        transl: LoquiBinaryTranslation <WorldspaceBlock> .Instance.Parse));
                                break;

                            default:
                                return;
                            }
                        }
                    }
                    finally
                    {
                        frame.MetaData.InWorldspace = false;
                    }
                }
                catch (Exception ex)
                {
                    throw RecordException.Enrich(ex, obj);
                }
            }
Esempio n. 4
0
        private static void AlignWorldChildren(
            IMutagenReadStream reader,
            MutagenWriter writer)
        {
            reader.WriteTo(writer.BaseStream, 4);
            ReadOnlyMemorySlice <byte>?        roadStorage = null;
            ReadOnlyMemorySlice <byte>?        cellStorage = null;
            List <ReadOnlyMemorySlice <byte> > grupBytes   = new List <ReadOnlyMemorySlice <byte> >();

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

                case "CELL":
                    if (cellStorage != null)
                    {
                        throw new ArgumentException();
                    }
                    var cellMajorMeta = reader.GetMajorRecord();
                    var startPos      = reader.Position;
                    reader.Position += cellMajorMeta.HeaderLength;
                    long cellGroupLen = 0;
                    if (reader.TryGetGroup(out var cellSubGroupMeta) &&
                        cellSubGroupMeta.GroupType == writer.MetaData.Constants.GroupConstants.Cell.TopGroupType)
                    {
                        cellGroupLen = cellSubGroupMeta.TotalLength;
                    }
                    reader.Position = startPos;
                    cellStorage     = reader.ReadMemory(checked ((int)(cellMajorMeta.TotalLength + cellGroupLen)));
                    break;

                case "GRUP":
                    if (roadStorage != null &&
                        cellStorage != null)
                    {
                        i = 3;     // end loop
                        continue;
                    }
                    grupBytes.Add(reader.ReadMemory(checked ((int)reader.GetGroup().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);
            }
        }
Esempio n. 5
0
 public CameraPath.ZoomType GetZoomCustom() => _zoomLoc.HasValue ? (CameraPath.ZoomType)(HeaderTranslation.ExtractSubrecordMemory(_data, _zoomLoc.Value, _package.MetaData.Constants)[0] % 128) : default;