public static WideStringTableContainer FromData(SaveState state)
            {
                int wideStringCount = state.ReadVariableLengthOffset();
                var container       = new WideStringTableContainer();

                for (int i = 0; i < wideStringCount; i++)
                {
                    int    stringLength = state.ReadVariableLengthOffset() * sizeof(short);
                    string str          = Encoding.Unicode.GetString(state.Reader.ReadBytesStrict(stringLength));

                    container.Table.Add(str);
                }

                return(container);
            }
        private void ReadHeaderData()
        {
            Reader.BaseStream.Position = SaveDataOffset + SaveDataLength - 0x8;
            uint typeDataChunkOffset = Reader.ReadUInt32();
            uint rawDataChunkOffset  = Reader.ReadUInt32();

            // String/GUID tables
            Reader.BaseStream.Position = SaveDataOffset + rawDataChunkOffset;
            {
                // UTF-8 strings
                StringPool = StringTableContainer.FromData(this);

                // UTF-16 strings
                WideStringPool = WideStringTableContainer.FromData(this);

                // GUIDs
                if (SaveVersion >= 26)
                {
                    GUIDPool = GUIDTableContainer.FromData(this);
                }
            }

            // Serialized type information and object instances
            Reader.BaseStream.Position = SaveDataOffset + typeDataChunkOffset;
            {
                // Create basic objects that are immediately registered with the engine
                int objectInstanceTypeCount = ReadVariableLengthOffset();
                LocalSaveObjects = new Dictionary <int, object>();

                for (int i = 0; i < objectInstanceTypeCount; i++)
                {
                    Type objectType    = RTTI.GetTypeByName(ReadIndexedString());
                    int  instanceCount = ReadVariableLengthOffset();

                    for (int j = 0; j < instanceCount; j++)
                    {
                        int objectId = ReadVariableLengthOffset();

                        LocalSaveObjects.Add(objectId, RTTI.CreateObjectInstance(objectType));
                    }
                }

                // Handles to game data objects
                int gameDataObjectCount = ReadVariableLengthOffset();
                GameDataObjects = new Dictionary <int, BaseGGUUID>();

                for (int i = 0; i < gameDataObjectCount; i++)
                {
                    int objectId = ReadVariableLengthOffset();
                    var guid     = new BaseGGUUID().FromData(Reader);

                    GameDataObjects.Add(objectId, guid);
                }

                // RTTI/class member layouts
                RTTIContainer = RTTIMapContainer.FromData(this);

                // File prefetch
                int prefetchFileCount = ReadVariableLengthOffset();
                PrefetchFilePaths = new List <string>(prefetchFileCount);

                for (int i = 0; i < prefetchFileCount; i++)
                {
                    PrefetchFilePaths.Add(ReadIndexedString());
                }
            }

            Reader.BaseStream.Position = SaveDataOffset;
        }