public byte[] Export(string[] Content) { using (var Strm = new MemoryStream()) using (StructWriter Writer = new StructWriter(Strm, Encoding: Encoding)) { var File = new TextDataFormat(); File.Content = Content; File.Count = Content.Length; File.Offsets = new TextDataEntryOffset[File.Count]; var Offset = 16 + (16 * File.Count); for (int i = 0; i < Content.Length; i++) { File.Offsets[i] = new TextDataEntryOffset() { Offset = Offset }; Offset += Encoding.GetByteCount(Content[i] + '\x0'); } Writer.WriteStruct(ref File); Writer.Flush(); foreach (var String in Content) { Writer.WriteString(String, StringStyle.CString); } return(Strm.ToArray()); } }
public void SaveFile(string filename) { // Sort the values before we save them to the sfo file _values.Sort(); using (FileStream stream = File.Create(filename)) { using (StructWriter sw = new StructWriter(ByteOrder.LSB, stream)) { INDEX_TABLE_ENTRY[] indexes = new INDEX_TABLE_ENTRY[_values.Count]; string[] variablenames = new string[_values.Count]; int curkeynameoffset = 0; uint curvalueoffset = 0; for (int idx = 0; idx < _values.Count; idx++) { SFOValue value = _values[idx]; DATA_TYPE datatype = DATA_TYPE.BinaryData; uint datasize = 0; switch (value.ValueType) { case SFOType.Binary: { datatype = DATA_TYPE.BinaryData; datasize = (uint)value.ValueBinary.Length; break; } case SFOType.Int: { datatype = DATA_TYPE.Si32Integer; datasize = 4; break; } case SFOType.Text: { datatype = DATA_TYPE.Utf8Text; datasize = (uint)Encoding.UTF8.GetBytes(value.ValueString).Length + 1; break; } default: { throw new Exception("Unknown SFOType!"); } } indexes[idx].KeyNameOffset = (ushort)curkeynameoffset; indexes[idx].Unknown = 4; indexes[idx].DataType = datatype; indexes[idx].ValueDataSize = datasize; indexes[idx].ValueDataSizePlusPadding = GetPaddingSize(value.KeyName, datasize); indexes[idx].DataValueOffset = curvalueoffset; variablenames[idx] = value.KeyName; curkeynameoffset += value.KeyName.Length + 1; curvalueoffset += indexes[idx].ValueDataSizePlusPadding; } SFO_HEADER sfoheader = new SFO_HEADER(); sfoheader.magic = 0; sfoheader.signature = new char[] { 'P', 'S', 'F' }; sfoheader.FileVersionHigh = 1; sfoheader.FileVersionLow = 1; sfoheader.Unknown1 = 0; sfoheader.Start_of_Variable_Name_Table = PadOffset(Marshal.SizeOf(sfoheader) + (indexes.Length * Marshal.SizeOf(typeof(INDEX_TABLE_ENTRY)))); sfoheader.Start_of_Variable_Data_Table = PadOffset(sfoheader.Start_of_Variable_Name_Table + curkeynameoffset); sfoheader.NumberOfVariables = (uint)_values.Count; sw.WriteStruct(sfoheader); // Write variable information... sw.WriteStructs <INDEX_TABLE_ENTRY>(indexes); WritePadBytes(sw, sw.BaseStream.Position, sfoheader.Start_of_Variable_Name_Table); // Write variable names... sw.WriteStrings(StringType.NullTerminated, variablenames); WritePadBytes(sw, sw.BaseStream.Position, sfoheader.Start_of_Variable_Data_Table); // Write variable data... for (int idx = 0; idx < _values.Count; idx++) { SFOValue value = _values[idx]; switch (value.ValueType) { case SFOType.Binary: { sw.Write(value.ValueBinary); break; } case SFOType.Int: { sw.Write((Int32)value.ValueInt); break; } case SFOType.Text: { sw.WriteString(StringType.NullTerminated, value.ValueString); break; } } long pos = sw.BaseStream.Position; WritePadBytes(sw, indexes[idx].ValueDataSize, indexes[idx].ValueDataSizePlusPadding); } } } }