コード例 #1
0
        void WriteFirstByte <T>(ref BitTarget target, T data, CompressedDataInfo dataInfo) where T : INumberContainer
        {
            bool isExtendedByte        = target.FreeBits < 4;
            bool byteWillHaveFreeSpace = dataInfo.HeaderLen < target.FreeBits;

            // Write the header
            target.WriteInteger(dataInfo.Header, dataInfo.HeaderLen);

            // Handle extended starts (yyy-xxxxxxxx)
            if (isExtendedByte)
            {
                // Write any free "y"s.
                if (byteWillHaveFreeSpace)
                {
                    target.WriteInteger((byte)(data.ShiftRight(dataInfo.BitsToGo) >> 8), target.FreeBits);
                }

                // The next byte will definitely have some free space, as we can not physically fill all of the remaining "xxxxxxxx"s with the header.
                // Ensure we're definitely ready for the next byte.
                if (target.FreeBits == 0)
                {
                    target.Apply();
                }

                byteWillHaveFreeSpace = true;
            }

            if (byteWillHaveFreeSpace)
            {
                target.WriteInteger((byte)data.ShiftRight(dataInfo.BitsToGo), target.FreeBits);
            }

            target.Apply();
        }
コード例 #2
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        void SerializeItemNoSetup(object obj, MapItemInfo info, ref BitTarget header, bool skipHeader)
        {
            Converter item = info.Converter;

            ABSaveUtils.WaitUntilNotGenerating(item);

            SerializeConverter(obj, info.Converter, ref header, skipHeader);
        }
コード例 #3
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        void SerializeActualType(object obj, Type type)
        {
            MapItemInfo info = GetRuntimeMapItem(type);

            var newTarget = new BitTarget(this);

            SerializeItemNoSetup(obj, info, ref newTarget, true);
        }
コード例 #4
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
 public void SerializePossibleNullableItem(object obj, MapItemInfo info, ref BitTarget header)
 {
     // Say it's "not null" if it is nullable.
     if (info.IsNullable)
     {
         header.WriteBitOn();
     }
     SerializeItemNoSetup(obj, info, ref header, info.IsNullable);
 }
コード例 #5
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        // Returns: Whether the type has changed.
        bool WriteHeaderNullAndInheritance(Type actualType, Converter item, ref BitTarget target)
        {
            target.WriteBitOn(); // Null

            bool sameType = item.ItemType == actualType;

            target.WriteBitWith(sameType);
            return(sameType);
        }
コード例 #6
0
        public void WriteUTF8(ReadOnlySpan <char> data, ref BitTarget header)
        {
            int         maxSize = Encoding.UTF8.GetMaxByteCount(data.Length);
            Span <byte> buffer  = maxSize <= ABSaveUtils.MAX_STACK_SIZE ? stackalloc byte[maxSize] : GetStringBufferFor(maxSize);

            int actualSize = Encoding.UTF8.GetBytes(data, buffer);

            WriteCompressedInt((uint)actualSize, ref header);
            WriteBytes(buffer.Slice(0, actualSize));
        }
コード例 #7
0
 public void WriteText(ReadOnlySpan <char> chars, ref BitTarget header)
 {
     if (Settings.UseUTF8)
     {
         WriteUTF8(chars, ref header);
     }
     else
     {
         WriteCompressedInt((uint)chars.Length);
         FastWriteShorts(MemoryMarshal.Cast <char, short>(chars));
     }
 }
コード例 #8
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        public void SerializeItem(object?obj, MapItemInfo item, ref BitTarget header)
        {
            if (obj == null)
            {
                header.WriteBitOff();
                header.Apply();
            }

            else
            {
                SerializePossibleNullableItem(obj, item, ref header);
            }
        }
コード例 #9
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        uint WriteNewVersionInfo(Converter item, ref BitTarget target)
        {
            uint targetVersion = 0;

            // Try to get the custom target version and if there is none use the latest.
            if (TargetVersions?.TryGetValue(item.ItemType, out targetVersion) != true)
            {
                targetVersion = item.HighestVersion;
            }

            WriteCompressedInt(targetVersion, ref target);
            return(targetVersion);
        }
コード例 #10
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        public void SerializeItem(object?obj, MapItemInfo item)
        {
            if (obj == null)
            {
                WriteByte(0);
            }

            else
            {
                var currentHeader = new BitTarget(this);
                SerializePossibleNullableItem(obj, item, ref currentHeader);
            }
        }
コード例 #11
0
        void WriteCompressedSlow <T>(T data, ref BitTarget target) where T : INumberContainer
        {
            var dataInfo = GetCompressedDataInfo(data, target.FreeBits);

            // Write the first byte
            WriteFirstByte(ref target, data, dataInfo);

            // Write the data in the remaining bytes
            while (dataInfo.BitsToGo > 0)
            {
                dataInfo.BitsToGo -= 8;
                WriteByte((byte)data.ShiftRight(dataInfo.BitsToGo));
            }
        }
コード例 #12
0
        public void WriteString(string?str)
        {
            var header = new BitTarget(this);

            if (str == null)
            {
                header.WriteBitOff();
            }
            else
            {
                header.WriteBitOn();
                WriteNonNullString(str !);
            }
        }
コード例 #13
0
        void WriteCompressed <T>(T data, ref BitTarget target) where T : INumberContainer
        {
            if (target.FreeBits == 0)
            {
                target.Apply();
            }

            if (Settings.LazyCompressedWriting)
            {
                WriteCompressedLazyFast(data, ref target);
            }
            else
            {
                WriteCompressedSlow(data, ref target);
            }
        }
コード例 #14
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        /// <summary>
        /// Handles the version info for a given converter. If the version hasn't been written yet, it's written now. If not, nothing is written.
        /// </summary>
        /// <returns>Whether the item already exists</returns>
        internal bool HandleVersionNumber(Converter item, out VersionInfo info, ref BitTarget header)
        {
            if (item._instanceId >= _currentVersionInfos.Length)
            {
                Array.Resize(ref _currentVersionInfos, (int)Map._highestConverterInstanceId);
            }

            // If the version has already been written, do nothing
            VersionInfo?existingInfo = _currentVersionInfos[item._instanceId];

            if (existingInfo != null)
            {
                info = existingInfo;
                return(true);
            }

            uint version = WriteNewVersionInfo(item, ref header);

            info = Map.GetVersionInfo(item, version);
            _currentVersionInfos[item._instanceId] = info;
            return(false);
        }
コード例 #15
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        void SerializeConverter(object obj, Converter converter, ref BitTarget header, bool skipHeader)
        {
            Type?actualType = obj.GetType();

            bool appliedHeader = true;

            // Write the null and inheritance bits.
            bool sameType = true;

            if (!converter.IsValueItemType && !skipHeader)
            {
                sameType      = WriteHeaderNullAndInheritance(actualType, converter, ref header);
                appliedHeader = false;
            }

            // Write and get the info for a version, if necessary
            if (!HandleVersionNumber(converter, out VersionInfo info, ref header))
            {
                appliedHeader = true;
            }

            // Handle inheritance if needed.
            if (info._inheritanceInfo != null && !sameType)
            {
                SerializeActualType(obj, info._inheritanceInfo, converter.ItemType, actualType, ref header);
                return;
            }

            // Apply the header if it's not being used and hasn't already been applied.
            if (!info.UsesHeader && !appliedHeader)
            {
                header.Apply();
            }

            var serializeInfo = new Converter.SerializeInfo(obj, actualType, info);

            converter.Serialize(in serializeInfo, ref header);
        }
コード例 #16
0
        void WriteCompressedLazyFast <T>(T data, ref BitTarget target) where T : INumberContainer
        {
            // This should be blazing fast, we're literally just going to write whether the number takes up more than a byte, and that's it.
            if (data.LessThan(255))
            {
                target.OrAndApply(1);
                WriteByte(data.ToByte());
            }
            else
            {
                target.OrAndApply(0);

                // This check is optimized away by the JIT.
                if (typeof(T) == typeof(Int32Container))
                {
                    WriteInt32(data.ToInt32());
                }
                else if (typeof(T) == typeof(Int64Container))
                {
                    WriteInt64(data.ToInt64());
                }
            }
        }
コード例 #17
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
 public void SerializeExactNonNullItem(object obj, MapItemInfo item, ref BitTarget header) =>
 SerializeItemNoSetup(obj, item, ref header, true);
コード例 #18
0
 // NOTE: All uses of "INumberContainer" virtual calls in here are elided by the JIT thanks to generics.
 public void WriteCompressedInt(uint data, ref BitTarget target) => WriteCompressed(new Int32Container((int)data), ref target);
コード例 #19
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        void WriteKeyInheritance(SaveInheritanceAttribute info, Type baseType, Type actualType, ref BitTarget header)
        {
            string key = KeyInheritanceHandler.GetOrAddTypeKeyFromCache(baseType, actualType, info);

            WriteString(key, ref header);
        }
コード例 #20
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        bool TryWriteListInheritance(SaveInheritanceAttribute info, Type actualType, bool writeOnIfSuccessful, ref BitTarget header)
        {
            if (info.IndexSerializeCache !.TryGetValue(actualType, out uint pos))
            {
                if (writeOnIfSuccessful)
                {
                    header.WriteBitOn();
                }
                WriteCompressedInt(pos, ref header);
                return(true);
            }

            return(false);
        }
コード例 #21
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        // Returns: Whether the sub-type was converted in here and we should return now.
        void SerializeActualType(object obj, SaveInheritanceAttribute info, Type baseType, Type actualType, ref BitTarget header)
        {
            switch (info.Mode)
            {
            case SaveInheritanceMode.Index:
                if (!TryWriteListInheritance(info, actualType, false, ref header))
                {
                    throw new UnsupportedSubTypeException(baseType, actualType);
                }

                break;

            case SaveInheritanceMode.Key:
                WriteKeyInheritance(info, baseType, actualType, ref header);

                break;

            case SaveInheritanceMode.IndexOrKey:
                if (!TryWriteListInheritance(info, actualType, true, ref header))
                {
                    header.WriteBitOff();
                    WriteKeyInheritance(info, baseType, actualType, ref header);
                }

                break;
            }

            // Serialize the actual type now.
            SerializeItemNoSetup(obj, GetRuntimeMapItem(actualType), ref header, true);
        }
コード例 #22
0
 public void WriteCompressedLong(ulong data, ref BitTarget target) => WriteCompressed(new Int64Container((long)data), ref target);
コード例 #23
0
        public void WriteNonNullString(string str)
        {
            var header = new BitTarget(this);

            WriteString(str, ref header);
        }
コード例 #24
0
        public void WriteCompressedLong(ulong data)
        {
            var target = new BitTarget(this);

            WriteCompressedLong(data, ref target);
        }
コード例 #25
0
 public void WriteString(string str, ref BitTarget header) => WriteText(str.AsSpan(), ref header);
コード例 #26
0
ファイル: ABSaveSerializer.cs プロジェクト: ABCo-Src/ABSave
        public void SerializeExactNonNullItem(object obj, MapItemInfo item)
        {
            var currentHeader = new BitTarget(this);

            SerializeItemNoSetup(obj, item, ref currentHeader, true);
        }
コード例 #27
0
        public void WriteCompressedInt(uint data)
        {
            var target = new BitTarget(this);

            WriteCompressedInt(data, ref target);
        }