예제 #1
0
 protected BinaryOverlay(
     ReadOnlyMemorySlice <byte> bytes,
     BinaryOverlayFactoryPackage package)
 {
     this._data    = bytes;
     this._package = package;
 }
예제 #2
0
        public static IReadOnlyList <T> FactoryByCountLength(
            ReadOnlyMemorySlice <byte> mem,
            BinaryOverlayFactoryPackage package,
            int itemLength,
            byte countLength,
            BinaryOverlay.SpanFactory <T> getter)
        {
            uint count;

            switch (countLength)
            {
            case 4:
                count = BinaryPrimitives.ReadUInt32LittleEndian(mem);
                break;

            default:
                throw new NotImplementedException();
            }
            if (((mem.Length - countLength) / itemLength) < count)
            {
                throw new ArgumentException("Item count and expected size did not match.");
            }
            return(new BinaryOverlayListByStartIndex(
                       mem.Slice(countLength, checked ((int)(count * itemLength))),
                       package,
                       getter,
                       itemLength));
        }
예제 #3
0
 public BinaryOverlayListByStartIndexWithRecord(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     BinaryOverlay.SpanFactory <T> getter,
     int itemLength,
     RecordType recordType,
     bool skipHeader)
 {
     this._mem             = mem;
     this._package         = package;
     this._getter          = getter;
     this._itemLength      = itemLength;
     this._recordType      = recordType;
     this._totalItemLength = itemLength + this._package.MetaData.Constants.SubConstants.HeaderLength;
     if (skipHeader)
     {
         _sliceOffset = this._package.MetaData.Constants.SubConstants.HeaderLength;
         _itemOffset  = 0;
     }
     else
     {
         _sliceOffset = 0;
         _itemOffset  = this._package.MetaData.Constants.SubConstants.HeaderLength;
     }
 }
예제 #4
0
        public static IReadOnlyList <string> FactoryByCountLength <T>(
            ReadOnlyMemorySlice <byte> mem,
            BinaryOverlayFactoryPackage package,
            byte countLength,
            BinaryOverlay.SpanFactory <string> getter)
        {
            var count = countLength switch
            {
                4 => BinaryPrimitives.ReadUInt32LittleEndian(mem),
                _ => throw new NotImplementedException(),
            };

            int[] locs = new int[count];
            int   loc  = 0;

            for (int i = 0; i < count - 1; i++)
            {
                locs[i] = loc;
                var len = BinaryPrimitives.ReadUInt16LittleEndian(mem.Slice(loc));
                loc += len + 2;
            }
            return(FactoryByArray(
                       mem.Slice(countLength),
                       package,
                       getter,
                       locs));
        }
예제 #5
0
 public static IReadOnlyList <T> FactoryByLazyParse <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     byte countLength,
     BinaryOverlay.Factory <T> getter)
 {
     return(FactoryByLazyParse(mem.Slice(countLength), package, getter));
 }
예제 #6
0
 public BinaryOverlayLazyList(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     Func <ReadOnlyMemorySlice <byte>, BinaryOverlayFactoryPackage, IReadOnlyList <T> > getter)
 {
     this._mem     = mem;
     this._getter  = getter;
     this._package = package;
     this._list    = new Lazy <IReadOnlyList <T> >(ConstructList, isThreadSafe: true);
 }
예제 #7
0
 public static IReadOnlyList <T> FactoryByLazyParse <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     Func <ReadOnlyMemorySlice <byte>, BinaryOverlayFactoryPackage, IReadOnlyList <T> > getter)
 {
     return(new BinaryOverlayLazyList <T>(
                mem,
                package,
                getter));
 }
예제 #8
0
 public static IReadOnlyList <T> FactoryForLoqui <T>(
     ReadOnlyMemorySlice <byte> mem,
     int amount,
     int length,
     BinaryOverlayFactoryPackage package,
     RecordTypeConverter recordTypeConverter,
     BinaryOverlay.ConverterFactory <T> getter)
 {
     return(new NumberedLoquiList <T>(mem, amount, length, package, recordTypeConverter, getter));
 }
예제 #9
0
 public BinaryOverlayListByLocationArray(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     BinaryOverlay.SpanFactory <T> getter,
     int[] locs)
 {
     this._mem       = mem;
     this._getter    = getter;
     this._package   = package;
     this._locations = locs;
 }
예제 #10
0
 public BinaryOverlayListByStartIndex(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     BinaryOverlay.SpanFactory <T> getter,
     int itemLength)
 {
     this._mem        = mem;
     this._package    = package;
     this._getter     = getter;
     this._itemLength = itemLength;
 }
예제 #11
0
 public static IReadOnlyList <T> FactoryByStartIndex <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     int itemLength,
     BinaryOverlay.SpanFactory <T> getter)
 {
     return(new BinaryOverlayListByStartIndex <T>(
                mem,
                package,
                getter,
                itemLength));
 }
예제 #12
0
 public static IReadOnlyList <T> FactoryByArray <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     BinaryOverlay.SpanFactory <T> getter,
     int[] locs)
 {
     return(new BinaryOverlayListByLocationArray <T>(
                mem,
                package,
                getter,
                locs));
 }
예제 #13
0
        public static void FillModTypes(
            IBinaryReadStream stream,
            ModTypeFillWrapper fill,
            BinaryOverlayFactoryPackage package)
        {
            int?      lastParsed      = null;
            ModHeader headerMeta      = stream.GetModHeader(package);
            var       minimumFinalPos = checked ((int)(stream.Position + headerMeta.TotalLength));

            fill(
                stream: stream,
                finalPos: minimumFinalPos,
                offset: 0,
                type: headerMeta.RecordType,
                lastParsed: lastParsed,
                recordTypeConverter: null);
            stream.Position = (int)headerMeta.TotalLength;
            while (!stream.Complete)
            {
                GroupHeader groupMeta = stream.GetGroup(package);
                if (!groupMeta.IsGroup)
                {
                    throw new ArgumentException("Did not see GRUP header as expected.");
                }
                if (groupMeta.ContentLength == 0)
                {
                    stream.Position += groupMeta.TotalLength;
                    continue;
                }
                minimumFinalPos = checked ((int)(stream.Position + groupMeta.TotalLength));
                var parsed = fill(
                    stream: stream,
                    finalPos: minimumFinalPos,
                    offset: 0,
                    type: groupMeta.ContainedRecordType,
                    lastParsed: lastParsed,
                    recordTypeConverter: null);
                if (!parsed.KeepParsing)
                {
                    break;
                }
                if (!parsed.KeepParsing)
                {
                    break;
                }
                if (minimumFinalPos > stream.Position)
                {
                    stream.Position = checked ((int)minimumFinalPos);
                }
                lastParsed = parsed.ParsedIndex;
            }
        }
예제 #14
0
 public BinaryOverlayRecordListByLocationArray(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     RecordTypeConverter?recordTypeConverter,
     BinaryOverlay.SpanRecordFactory <T> getter,
     int[] locs)
 {
     this._mem                 = mem;
     this._getter              = getter;
     this._package             = package;
     this._recordTypeConverter = recordTypeConverter;
     this._locations           = locs;
 }
예제 #15
0
        public static IReadOnlyList <T> FactoryByCountPerItem <T>(
            OverlayStream stream,
            BinaryOverlayFactoryPackage package,
            int countLength,
            RecordType subrecordType,
            RecordType countType,
            RecordTypeConverter?recordTypeConverter,
            BinaryOverlay.SpanRecordFactory <T> getter,
            bool skipHeader = true)
        {
            var mem           = stream.RemainingMemory;
            var initialHeader = package.MetaData.Constants.SubrecordFrame(mem);
            var recType       = initialHeader.RecordType;

            if (recType == countType)
            {
                var count = countLength switch
                {
                    1 => initialHeader.Content[0],
                    2 => BinaryPrimitives.ReadUInt16LittleEndian(initialHeader.Content),
                    4 => BinaryPrimitives.ReadUInt32LittleEndian(initialHeader.Content),
                    _ => throw new NotImplementedException(),
                };
                stream.Position += initialHeader.TotalLength;
                return(FactoryByArray(
                           mem: stream.RemainingMemory,
                           package: package,
                           recordTypeConverter: recordTypeConverter,
                           getter: getter,
                           locs: BinaryOverlay.ParseRecordLocationsByCount(
                               stream: stream,
                               count: count,
                               trigger: subrecordType,
                               constants: package.MetaData.Constants.SubConstants,
                               skipHeader: false)));
            }
            else
            {
                return(FactoryByArray(
                           mem: stream.RemainingMemory,
                           package: package,
                           recordTypeConverter: recordTypeConverter,
                           getter: getter,
                           locs: BinaryOverlay.ParseRecordLocations(
                               stream: stream,
                               constants: package.MetaData.Constants.SubConstants,
                               trigger: subrecordType,
                               skipHeader: skipHeader,
                               recordTypeConverter: recordTypeConverter)));
            }
        }
예제 #16
0
 public static IReadOnlyList <T> FactoryByArray <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     RecordTypeConverter?recordTypeConverter,
     BinaryOverlay.SpanRecordFactory <T> getter,
     int[] locs)
 {
     return(new BinaryOverlayRecordListByLocationArray <T>(
                mem,
                package,
                recordTypeConverter,
                getter,
                locs));
 }
예제 #17
0
        public static IReadOnlyList <T> FactoryByCount <T>(
            OverlayStream stream,
            BinaryOverlayFactoryPackage package,
            uint count,
            BinaryOverlay.StreamFactory <T> getter)
        {
            var ret = new List <T>(checked ((int)count));

            for (uint i = 0; i < count; i++)
            {
                ret.Add(getter(stream, package));
            }
            return(ret);
        }
예제 #18
0
 public GenderedItemBinaryOverlay(
     ReadOnlyMemorySlice <byte> bytes,
     BinaryOverlayFactoryPackage package,
     int?male,
     int?female,
     Func <ReadOnlyMemorySlice <byte>, BinaryOverlayFactoryPackage, T> creator,
     T fallback)
     : base(bytes, package)
 {
     this._male     = male;
     this._female   = female;
     this._creator  = creator;
     this._fallback = fallback;
 }
예제 #19
0
 public BinaryOverlayListByStartIndexWithRecordSet(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     BinaryOverlay.SpanFactory <T> getter,
     int itemLength,
     ICollectionGetter <RecordType> recordTypes)
 {
     this._mem             = mem;
     this._package         = package;
     this._getter          = getter;
     this._itemLength      = itemLength;
     this._recordTypes     = recordTypes;
     this._totalItemLength = itemLength + this._package.MetaData.Constants.SubConstants.HeaderLength;
 }
예제 #20
0
 public NumberedLoquiList(
     ReadOnlyMemorySlice <byte> mem,
     int amount,
     int length,
     BinaryOverlayFactoryPackage package,
     RecordTypeConverter recordTypeConverter,
     BinaryOverlay.ConverterFactory <T> getter)
 {
     this.Amount              = amount;
     this.Memory              = mem;
     this.Length              = length;
     this.Package             = package;
     this.Getter              = getter;
     this.RecordTypeConverter = recordTypeConverter;
 }
예제 #21
0
 public static ReadOnlyMemorySlice <T> LoquiSliceFromFixedSize <T>(
     ReadOnlyMemorySlice <byte> mem,
     int amount,
     int length,
     BinaryOverlayFactoryPackage package,
     RecordTypeConverter?recordTypeConverter,
     BinaryOverlay.ConverterFactory <T> getter)
 {
     T[] ret = new T[amount];
     for (int i = 0; i < amount; i++)
     {
         ret[i] = getter(new OverlayStream(mem.Slice(i * length), package), package, recordTypeConverter);
     }
     return(ret);
 }
예제 #22
0
        public static IReadOnlyList <T> FactoryByCount <T>(
            OverlayStream stream,
            BinaryOverlayFactoryPackage package,
            int itemLength,
            int countLength,
            RecordType subrecordType,
            RecordType countType,
            BinaryOverlay.SpanFactory <T> getter)
        {
            var mem           = stream.RemainingMemory;
            var initialHeader = package.MetaData.Constants.SubrecordFrame(mem);
            var recType       = initialHeader.RecordType;

            if (recType == countType)
            {
                var count = countLength switch
                {
                    1 => initialHeader.Content[0],
                    2 => (int)BinaryPrimitives.ReadUInt16LittleEndian(initialHeader.Content),
                    4 => checked ((int)BinaryPrimitives.ReadUInt32LittleEndian(initialHeader.Content)),
                    _ => throw new NotImplementedException(),
                };
                stream.Position += initialHeader.TotalLength;
                if (!stream.TryReadSubrecordFrame(subrecordType, out var contentFrame))
                {
                    if (count == 0)
                    {
                        return(Array.Empty <T>());
                    }
                    throw new ArgumentException($"List with a non zero {initialHeader.RecordType} counter did not follow up with expected type: {subrecordType}");
                }
                return(new BinaryOverlayListByStartIndex <T>(
                           contentFrame.Content,
                           package,
                           getter,
                           itemLength));
            }
            else
            {
                return(FactoryByStartIndex(
                           mem: stream.RemainingMemory,
                           package: package,
                           getter: getter,
                           itemLength: itemLength));
            }
        }
예제 #23
0
 public static IReadOnlyList <T> FactoryByCount <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     int itemLength,
     uint count,
     BinaryOverlay.SpanFactory <T> getter)
 {
     if ((mem.Length / itemLength) != count)
     {
         throw new ArgumentException("Item count and expected size did not match.");
     }
     return(new BinaryOverlayListByStartIndex <T>(
                mem,
                package,
                getter,
                itemLength));
 }
예제 #24
0
        public static IReadOnlyList <T>?FactoryByCountNullIfZero <T>(
            OverlayStream stream,
            BinaryOverlayFactoryPackage package,
            int itemLength,
            int countLength,
            RecordType subrecordType,
            RecordType countType,
            BinaryOverlay.SpanFactory <T> getter)
        {
            var mem           = stream.RemainingMemory;
            var initialHeader = package.MetaData.Constants.SubrecordFrame(mem);
            var recType       = initialHeader.RecordType;

            if (recType == countType)
            {
                var count = countLength switch
                {
                    1 => initialHeader.Content[0],
                    2 => (int)BinaryPrimitives.ReadUInt16LittleEndian(initialHeader.Content),
                    4 => checked ((int)BinaryPrimitives.ReadUInt32LittleEndian(initialHeader.Content)),
                    _ => throw new NotImplementedException(),
                };
                stream.Position += initialHeader.TotalLength;
                if (count == 0)
                {
                    return(null);
                }
                var contentFrame = stream.ReadSubrecordFrame(subrecordType);
                return(new BinaryOverlayListByStartIndex <T>(
                           contentFrame.Content,
                           package,
                           getter,
                           itemLength));
            }
            else
            {
                return(FactoryByStartIndex(
                           mem: stream.RemainingMemory,
                           package: package,
                           getter: getter,
                           itemLength: itemLength));
            }
        }
예제 #25
0
 public static IReadOnlyList <T> FactoryByCount <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     ICollectionGetter <RecordType> subrecordType,
     int itemLength,
     uint count,
     BinaryOverlay.SpanFactory <T> getter)
 {
     if ((mem.Length / (itemLength + package.MetaData.Constants.SubConstants.HeaderLength)) != count)
     {
         throw new ArgumentException("Item count and expected size did not match.");
     }
     return(new BinaryOverlayListByStartIndexWithRecordSet <T>(
                mem,
                package,
                getter,
                itemLength,
                subrecordType));
 }
예제 #26
0
 public static IReadOnlyList <T> FactoryByLazyParse <T>(
     ReadOnlyMemorySlice <byte> mem,
     BinaryOverlayFactoryPackage package,
     BinaryOverlay.Factory <T> getter)
 {
     return(new BinaryOverlayLazyList <T>(
                mem,
                package,
                (m, p) =>
     {
         var ret = new List <T>();
         using (var stream = new OverlayStream(m, package))
         {
             while (!stream.Complete)
             {
                 ret.Add(getter(stream, p));
             }
         }
         return ret;
     }));
 }