public StructureValueCollection Serialize() { var result = new StructureValueCollection(); result.SetInteger("string count", (uint)StringCount); result.SetInteger("locale table size", LocaleData != null ? (uint)LocaleData.Size : 0); if (LocaleIndexTableLocation != null) { result.SetInteger("locale index table offset", (uint)LocaleIndexTableLocation.AsPointer()); } if (LocaleDataLocation != null) { result.SetInteger("locale data index offset", (uint)LocaleDataLocation.AsPointer()); } if (IndexTableHash != null) { result.SetRaw("index table hash", IndexTableHash); } if (StringDataHash != null) { result.SetRaw("string data hash", StringDataHash); } return(result); }
public List <LocalizedString> LoadStrings(IReader reader) { var result = new List <LocalizedString>(); if (StringCount == 0) { return(result); } byte[] stringData = ReadLocaleData(reader); using (var stringReader = new EndianReader(new MemoryStream(stringData), reader.Endianness)) { reader.SeekTo(LocaleIndexTableLocation.AsOffset()); // Read each locale for (int i = 0; i < StringCount; i++) { // Read the offset and stringID StringID id; int offset; ReadLocalePointer(reader, out id, out offset); if (offset >= stringReader.Length) { break; // Bad table - bail out so we don't end up in a huge memory-hogging loop } stringReader.SeekTo(offset); string locale = stringReader.ReadUTF8(); result.Add(new LocalizedString(id, locale)); } } return(result); }
public void SaveStrings(IStream stream, List <LocalizedString> locales) { var offsetData = new MemoryStream(); var stringData = new MemoryStream(); var offsetWriter = new EndianWriter(offsetData, Endian.BigEndian); var stringWriter = new EndianWriter(stringData, Endian.BigEndian); try { // Write the string and offset data to buffers foreach (LocalizedString locale in locales) { WriteLocalePointer(offsetWriter, locale.Key, (int)stringWriter.Position); stringWriter.WriteUTF8(locale.Value); } // Round the size of the string data up var dataSize = (int)((stringData.Position + _sizeAlign - 1) & ~(_sizeAlign - 1)); stringData.SetLength(dataSize); // Update the two locale data hashes if we need to // (the hash arrays are set to null if the build doesn't need them) if (IndexTableHash != null) { IndexTableHash = SHA1.Transform(offsetData.GetBuffer(), 0, (int)offsetData.Length); } if (StringDataHash != null) { StringDataHash = SHA1.Transform(stringData.GetBuffer(), 0, dataSize); } // Make sure there's free space for the offset table and then write it to the file LocaleIndexTable.Resize((int)offsetData.Length, stream); stream.SeekTo(LocaleIndexTableLocation.AsOffset()); stream.WriteBlock(offsetData.GetBuffer(), 0, (int)offsetData.Length); // Encrypt the string data if necessary byte[] strings = stringData.GetBuffer(); if (_encryptionKey != null) { strings = AES.Encrypt(strings, 0, dataSize, _encryptionKey.Key, _encryptionKey.IV); } // Make sure there's free space for the string data and then write it to the file LocaleData.Resize(dataSize, stream); stream.SeekTo(LocaleDataLocation.AsOffset()); stream.WriteBlock(strings, 0, dataSize); // Update the string count and recalculate the language table offsets StringCount = locales.Count; } finally { offsetWriter.Close(); stringWriter.Close(); } }
public void SaveStrings(List <LocalizedString> locales, IStream stream) { if (LocaleData == null || LocaleIndexTable == null) { return; } using (var offsetData = new MemoryStream()) using (var stringData = new MemoryStream()) using (var offsetWriter = new EndianWriter(offsetData, stream.Endianness)) using (var stringWriter = new EndianWriter(stringData, stream.Endianness)) { // Write the string and offset data to buffers foreach (LocalizedString locale in locales) { WriteLocalePointer(offsetWriter, locale.Key, (int)stringWriter.Position); stringWriter.WriteUTF8(locale.Value); } // Round the size of the string data up var dataSize = (int)((stringData.Position + _sizeAlign - 1) & ~(_sizeAlign - 1)); stringData.SetLength(dataSize); // Make sure there's free space for the offset table and then write it to the file LocaleIndexTable.Resize((int)offsetData.Length, stream); stream.SeekTo(LocaleIndexTableLocation.AsOffset()); stream.WriteBlock(offsetData.ToArray(), 0, (int)offsetData.Length); byte[] strings = stringData.ToArray(); // Make sure there's free space for the string data and then write it to the file LocaleData.Resize(dataSize, stream); stream.SeekTo(LocaleDataLocation.AsOffset()); stream.WriteBlock(strings, 0, dataSize); // Update the string count and recalculate the language table offsets StringCount = locales.Count; } }