mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2024-11-23 22:50:58 +01:00
First work for CPK archives
This commit is contained in:
parent
e3aa58f135
commit
3cc98ff257
@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcbEditor", "Source\AcbEdit
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsbEditor", "Source\CsbEditor\CsbEditor.csproj", "{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsbEditor", "Source\CsbEditor\CsbEditor.csproj", "{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsbBuilder", "Source\CsbBuilder\CsbBuilder.csproj", "{4CF49665-3DFD-4A5C-B231-B97842F091B9}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -32,6 +34,10 @@ Global
|
|||||||
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{91F6B6A6-5D95-4C7A-B22E-A35BD32DB67A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4CF49665-3DFD-4A5C-B231-B97842F091B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
6
Source/CsbBuilder/App.config
Normal file
6
Source/CsbBuilder/App.config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
48
Source/CsbBuilder/CriTableAax.cs
Normal file
48
Source/CsbBuilder/CriTableAax.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[CriSerializable("AAX")]
|
||||||
|
[Serializable]
|
||||||
|
public class CriTableAax
|
||||||
|
{
|
||||||
|
public enum EnumLoopFlag
|
||||||
|
{
|
||||||
|
Intro = 0,
|
||||||
|
Loop = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
private byte[] _data = new byte[0];
|
||||||
|
private EnumLoopFlag _lpflg = EnumLoopFlag.Intro;
|
||||||
|
|
||||||
|
[CriField("data", 0)]
|
||||||
|
public byte[] Data
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("lpflg", 1)]
|
||||||
|
public byte LoopFlag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (byte)_lpflg;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_lpflg = (EnumLoopFlag)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
Source/CsbBuilder/CriTableAisac.cs
Normal file
90
Source/CsbBuilder/CriTableAisac.cs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLISC")]
|
||||||
|
public class CriTableAisac
|
||||||
|
{
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private string _ptname = string.Empty;
|
||||||
|
private byte _type = 0;
|
||||||
|
private byte _rndrng = 0;
|
||||||
|
|
||||||
|
[CriField("name", 0)]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("ptname", 1)]
|
||||||
|
public string PathName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _ptname;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ptname = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("type", 2)]
|
||||||
|
public byte Type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriIgnore]
|
||||||
|
public List<CriTableAisacGraph> GraphList { get; set; }
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
[CriField("grph", 3)]
|
||||||
|
public byte[] Graph
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return CriTableSerializer.Serialize(GraphList, CriTableWriterSettings.AdxSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
GraphList = CriTableSerializer.Deserialize<CriTableAisacGraph>(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("rndrng", 4)]
|
||||||
|
public byte RandomRange
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _rndrng;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_rndrng = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
Source/CsbBuilder/CriTableAisacGraph.cs
Normal file
104
Source/CsbBuilder/CriTableAisacGraph.cs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLIGR")]
|
||||||
|
public class CriTableAisacGraph
|
||||||
|
{
|
||||||
|
private byte _type = 0;
|
||||||
|
private float _imax = 0;
|
||||||
|
private float _imin = 0;
|
||||||
|
private float _omax = 0;
|
||||||
|
private float _omin = 0;
|
||||||
|
|
||||||
|
[CriField("type", 0)]
|
||||||
|
public byte Type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("imax", 1)]
|
||||||
|
public float InMaximum
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _imax;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_imax = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("imin", 2)]
|
||||||
|
public float InMinimum
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _imin;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_imin = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("omax", 3)]
|
||||||
|
public float OutMaximum
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _omax;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_omax = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("omin", 4)]
|
||||||
|
public float OutMinimum
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _omin;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_omin = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriIgnore]
|
||||||
|
public List<CriTableAisacPoint> PointsList { get; set; }
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
[CriField("points", 5)]
|
||||||
|
public byte[] Points
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return CriTableSerializer.Serialize(PointsList, CriTableWriterSettings.AdxSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
PointsList = CriTableSerializer.Deserialize<CriTableAisacPoint>(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
Source/CsbBuilder/CriTableAisacPoint.cs
Normal file
42
Source/CsbBuilder/CriTableAisacPoint.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLIPT")]
|
||||||
|
public class CriTableAisacPoint
|
||||||
|
{
|
||||||
|
private ushort _in = 0;
|
||||||
|
private ushort _out = 0;
|
||||||
|
|
||||||
|
[CriField("in", 0)]
|
||||||
|
public ushort In
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _in;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_in = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("out", 1)]
|
||||||
|
public ushort Out
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _out;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_out = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
Source/CsbBuilder/CriTableCue.cs
Normal file
84
Source/CsbBuilder/CriTableCue.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLCUE")]
|
||||||
|
public class CriTableCue
|
||||||
|
{
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private uint _id = 0;
|
||||||
|
private string _synth = string.Empty;
|
||||||
|
private string _udata = string.Empty;
|
||||||
|
private byte _flags = 0;
|
||||||
|
|
||||||
|
[CriField("name", 0)]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("id", 1)]
|
||||||
|
public uint Index
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_id = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("synth", 2)]
|
||||||
|
public string Synth
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _synth;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_synth = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("udata", 3)]
|
||||||
|
public string UserData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _udata;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_udata = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("flags", 4)]
|
||||||
|
public byte Flags
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _flags;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_flags = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
134
Source/CsbBuilder/CriTableCueSheet.cs
Normal file
134
Source/CsbBuilder/CriTableCueSheet.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLCSB")]
|
||||||
|
public class CriTableCueSheet
|
||||||
|
{
|
||||||
|
public enum EnumTableType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Cue = 1,
|
||||||
|
Synth = 2,
|
||||||
|
SoundElement = 4,
|
||||||
|
Aisac = 5,
|
||||||
|
VoiceLimitGroup = 6,
|
||||||
|
VersionInfo = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private EnumTableType _ttype = EnumTableType.None;
|
||||||
|
|
||||||
|
[CriField("name", 0)]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("ttype", 1)]
|
||||||
|
public byte TableType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (byte)_ttype;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ttype = (EnumTableType)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriIgnore]
|
||||||
|
[XmlArray]
|
||||||
|
[XmlArrayItem(typeof(CriTableCue))]
|
||||||
|
[XmlArrayItem(typeof(CriTableSynth))]
|
||||||
|
[XmlArrayItem(typeof(CriTableSoundElement))]
|
||||||
|
[XmlArrayItem(typeof(CriTableAisac))]
|
||||||
|
[XmlArrayItem(typeof(CriTableVoiceLimitGroup))]
|
||||||
|
[XmlArrayItem(typeof(CriTableVersionInfo))]
|
||||||
|
public ArrayList DataList { get; set; }
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
[CriField("utf", 2)]
|
||||||
|
public byte[] Data
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (_ttype)
|
||||||
|
{
|
||||||
|
case EnumTableType.None:
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
case EnumTableType.Cue:
|
||||||
|
return CriTableSerializer.Serialize(DataList.OfType<CriTableCue>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||||
|
|
||||||
|
case EnumTableType.Synth:
|
||||||
|
return CriTableSerializer.Serialize(DataList.OfType<CriTableSynth>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||||
|
|
||||||
|
case EnumTableType.SoundElement:
|
||||||
|
return CriTableSerializer.Serialize(DataList.OfType<CriTableSoundElement>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||||
|
|
||||||
|
case EnumTableType.Aisac:
|
||||||
|
return CriTableSerializer.Serialize(DataList.OfType<CriTableAisac>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||||
|
|
||||||
|
case EnumTableType.VoiceLimitGroup:
|
||||||
|
return CriTableSerializer.Serialize(DataList.OfType<CriTableVoiceLimitGroup>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||||
|
|
||||||
|
case EnumTableType.VersionInfo:
|
||||||
|
return CriTableSerializer.Serialize(DataList.OfType<CriTableVersionInfo>().ToList(), CriTableWriterSettings.AdxSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException($"Unknown table type {_ttype}, please report the error with the file.", "_ttype");
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
switch (_ttype)
|
||||||
|
{
|
||||||
|
case EnumTableType.Cue:
|
||||||
|
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableCue));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnumTableType.Synth:
|
||||||
|
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableSynth));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnumTableType.SoundElement:
|
||||||
|
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableSoundElement));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnumTableType.Aisac:
|
||||||
|
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableAisac));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnumTableType.VoiceLimitGroup:
|
||||||
|
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableVoiceLimitGroup));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnumTableType.VersionInfo:
|
||||||
|
DataList = CriTableSerializer.Deserialize(value, typeof(CriTableVersionInfo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unknown table type {_ttype}, please report the error with the file.", "_ttype");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
130
Source/CsbBuilder/CriTableSoundElement.cs
Normal file
130
Source/CsbBuilder/CriTableSoundElement.cs
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLSDL")]
|
||||||
|
public class CriTableSoundElement
|
||||||
|
{
|
||||||
|
public enum EnumFormat
|
||||||
|
{
|
||||||
|
Adx = 0,
|
||||||
|
Dsp = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum EnumStreamFlag
|
||||||
|
{
|
||||||
|
Internal = 0,
|
||||||
|
External = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private EnumFormat _fmt = EnumFormat.Adx;
|
||||||
|
private byte _nch = 0;
|
||||||
|
private EnumStreamFlag _stmflg = EnumStreamFlag.Internal;
|
||||||
|
private uint _sfreq = 0;
|
||||||
|
private uint _nsmpl = 0;
|
||||||
|
|
||||||
|
[CriField("name", 0)]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriIgnore]
|
||||||
|
public List<CriTableAax> DataList { get; set; }
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
[CriField("data", 1)]
|
||||||
|
public byte[] Data
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return CriTableSerializer.Serialize(DataList, CriTableWriterSettings.AdxSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
DataList = CriTableSerializer.Deserialize<CriTableAax>(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("fmt", 2)]
|
||||||
|
public byte Format
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (byte)_fmt;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_fmt = (EnumFormat)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("nch", 3)]
|
||||||
|
public byte NumberChannels
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _nch;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_nch = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("stmflg", 4)]
|
||||||
|
public byte StreamFlag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (byte)_stmflg;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_stmflg = (EnumStreamFlag)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("sfreq", 5)]
|
||||||
|
public uint SoundFrequence
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _sfreq;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_sfreq = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("nsmpl", 6)]
|
||||||
|
public uint NumberSamples
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _nsmpl;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_nsmpl = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1328
Source/CsbBuilder/CriTableSynth.cs
Normal file
1328
Source/CsbBuilder/CriTableSynth.cs
Normal file
File diff suppressed because it is too large
Load Diff
42
Source/CsbBuilder/CriTableVersionInfo.cs
Normal file
42
Source/CsbBuilder/CriTableVersionInfo.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBL_INFO")]
|
||||||
|
public class CriTableVersionInfo
|
||||||
|
{
|
||||||
|
private uint _DataFmtVer = 0x940000;
|
||||||
|
private uint _ExtSize = 0;
|
||||||
|
|
||||||
|
[CriField("DataFmtVer", 0)]
|
||||||
|
public uint DataFormatVersion
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _DataFmtVer;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_DataFmtVer = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("ExtSize", 1)]
|
||||||
|
public uint ExtensionSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _ExtSize;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ExtSize = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
Source/CsbBuilder/CriTableVoiceLimitGroup.cs
Normal file
42
Source/CsbBuilder/CriTableVoiceLimitGroup.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System.IO;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[CriSerializable("TBLVLG")]
|
||||||
|
public class CriTableVoiceLimitGroup
|
||||||
|
{
|
||||||
|
private string _vlgname = string.Empty;
|
||||||
|
private uint _vlgnvoice = 0;
|
||||||
|
|
||||||
|
[CriField("vlgname", 0)]
|
||||||
|
public string VoiceLimitGroupName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _vlgname;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_vlgname = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CriField("vlgnvoice", 1)]
|
||||||
|
public uint VoiceLimitGroupNum
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _vlgnvoice;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_vlgnvoice = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
Source/CsbBuilder/CsbBuilder.csproj
Normal file
88
Source/CsbBuilder/CsbBuilder.csproj
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{4CF49665-3DFD-4A5C-B231-B97842F091B9}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>CsbBuilder</RootNamespace>
|
||||||
|
<AssemblyName>CsbBuilder</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\..\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>..\..\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="CriTableAax.cs" />
|
||||||
|
<Compile Include="CriTableAisac.cs" />
|
||||||
|
<Compile Include="CriTableAisacGraph.cs" />
|
||||||
|
<Compile Include="CriTableAisacPoint.cs" />
|
||||||
|
<Compile Include="CriTableCue.cs" />
|
||||||
|
<Compile Include="CriTableCueSheet.cs" />
|
||||||
|
<Compile Include="CriTableSoundElement.cs" />
|
||||||
|
<Compile Include="CriTableSynth.cs" />
|
||||||
|
<Compile Include="CriTableVersionInfo.cs" />
|
||||||
|
<Compile Include="CriTableVoiceLimitGroup.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\SonicAudioLib\SonicAudioLib.csproj">
|
||||||
|
<Project>{63138773-1f47-474c-9345-15eb6183ecc6}</Project>
|
||||||
|
<Name>SonicAudioLib</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
73
Source/CsbBuilder/Program.cs
Normal file
73
Source/CsbBuilder/Program.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using SonicAudioLib.CriMw;
|
||||||
|
using SonicAudioLib.CriMw.Serialization;
|
||||||
|
using SonicAudioLib.IO;
|
||||||
|
using SonicAudioLib.Archive;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CsbBuilder
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
Console.WriteLine(Properties.Resources.Description);
|
||||||
|
Console.ReadLine();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (args[0].EndsWith(".csb"))
|
||||||
|
{
|
||||||
|
List<CriTableCueSheet> cueSheets = CriTableSerializer.Deserialize<CriTableCueSheet>(args[0]);
|
||||||
|
//CriTableSerializer.Serialize(args[0] + ".new", cueSheets, CriTableWriterSettings.AdxSettings);
|
||||||
|
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(List<CriTableCueSheet>));
|
||||||
|
using (Stream dest = File.Create(Path.GetFileNameWithoutExtension(args[0]) + ".xml"))
|
||||||
|
{
|
||||||
|
serializer.Serialize(dest, cueSheets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (File.GetAttributes(args[0]).HasFlag(FileAttributes.Directory))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (args[0].EndsWith(".xml"))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(List<CriTableCueSheet>));
|
||||||
|
using (Stream dest = File.OpenRead(args[0]))
|
||||||
|
{
|
||||||
|
CriTableSerializer.Serialize(Path.GetFileNameWithoutExtension(args[0]) + ".csb", (List<CriTableCueSheet>)serializer.Deserialize(dest), CriTableWriterSettings.AdxSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
//MessageBox.Show($"{exception.Message}", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadAdx(FileInfo fileInfo, out uint sampleRate, out byte numberChannels)
|
||||||
|
{
|
||||||
|
using (Stream source = fileInfo.OpenRead())
|
||||||
|
{
|
||||||
|
source.Seek(7, SeekOrigin.Begin);
|
||||||
|
numberChannels = EndianStream.ReadByte(source);
|
||||||
|
sampleRate = EndianStream.ReadUInt32BE(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Source/CsbBuilder/Properties/AssemblyInfo.cs
Normal file
36
Source/CsbBuilder/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("CsbBuilder")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("CsbBuilder")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("91f6b6a6-5d95-4c7a-b22e-a35bd32db67a")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
72
Source/CsbBuilder/Properties/Resources.Designer.cs
generated
Normal file
72
Source/CsbBuilder/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace CsbBuilder.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CsbBuilder.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to placeholder.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Description {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Description", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
Source/CsbBuilder/Properties/Resources.resx
Normal file
123
Source/CsbBuilder/Properties/Resources.resx
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="Description" xml:space="preserve">
|
||||||
|
<value>placeholder</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
@ -21,23 +21,47 @@ namespace SonicAudioCmd
|
|||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
CriCpkArchive archive = new CriCpkArchive();
|
if (args[0].EndsWith(".cpk"))
|
||||||
archive.Load(args[0]);
|
|
||||||
|
|
||||||
foreach (CriCpkEntry entry in archive)
|
|
||||||
{
|
{
|
||||||
using (Stream source = File.OpenRead(args[0]), substream = entry.Open(source))
|
CriCpkArchive archive = new CriCpkArchive();
|
||||||
|
archive.Load(args[0]);
|
||||||
|
archive.Print();
|
||||||
|
|
||||||
|
foreach (CriCpkEntry entry in archive)
|
||||||
{
|
{
|
||||||
FileInfo fileInfo = new FileInfo(Path.Combine(Path.GetFileNameWithoutExtension(args[0]), entry.DirectoryName, entry.Name));
|
using (Stream source = File.OpenRead(args[0]), substream = entry.Open(source))
|
||||||
fileInfo.Directory.Create();
|
|
||||||
using (Stream destination = fileInfo.Create())
|
|
||||||
{
|
{
|
||||||
substream.CopyTo(destination);
|
FileInfo fileInfo = new FileInfo(Path.Combine(Path.GetFileNameWithoutExtension(args[0]), entry.DirectoryName != null ? entry.DirectoryName : "", entry.Name != null ? entry.Name : entry.Id.ToString() + ".bin"));
|
||||||
|
fileInfo.Directory.Create();
|
||||||
|
using (Stream destination = fileInfo.Create())
|
||||||
|
{
|
||||||
|
substream.CopyTo(destination);
|
||||||
|
}
|
||||||
|
fileInfo.LastWriteTime = entry.UpdateDateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.ReadLine();
|
else
|
||||||
|
{
|
||||||
|
CriCpkArchive archive = new CriCpkArchive();
|
||||||
|
archive.Align = 16;
|
||||||
|
archive.Mode = CriCpkMode.FileName;
|
||||||
|
|
||||||
|
uint id = 0;
|
||||||
|
foreach (string file in Directory.GetFiles(args[0], "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
CriCpkEntry entry = new CriCpkEntry();
|
||||||
|
entry.Id = id;
|
||||||
|
entry.Name = Path.GetFileName(file);
|
||||||
|
entry.DirectoryName = Path.GetDirectoryName(file.Replace(args[0] + "\\", ""));
|
||||||
|
entry.FilePath = new FileInfo(file);
|
||||||
|
archive.Add(entry);
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
archive.Save(args[0] + ".cpk");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
using SonicAudioLib.IO;
|
using SonicAudioLib.IO;
|
||||||
using SonicAudioLib.Module;
|
using SonicAudioLib.Module;
|
||||||
@ -106,5 +107,29 @@ namespace SonicAudioLib.Archive
|
|||||||
{
|
{
|
||||||
return entries.GetEnumerator();
|
return entries.GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
public void Print()
|
||||||
|
{
|
||||||
|
Type archiveType = GetType();
|
||||||
|
Console.WriteLine("{0}:", archiveType.Name);
|
||||||
|
|
||||||
|
foreach (PropertyInfo property in archiveType.GetProperties().Where(p => p.GetIndexParameters().Length == 0))
|
||||||
|
{
|
||||||
|
Console.WriteLine(" {0}: {1}", property.Name, property.GetValue(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (T entry in entries)
|
||||||
|
{
|
||||||
|
Type entryType = entry.GetType();
|
||||||
|
|
||||||
|
Console.WriteLine("{0}:", entryType.Name);
|
||||||
|
foreach (PropertyInfo property in entryType.GetProperties().Where(p => p.GetIndexParameters().Length == 0))
|
||||||
|
{
|
||||||
|
Console.WriteLine(" {0}: {1}", property.Name, property.GetValue(entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ namespace SonicAudioLib.Archive
|
|||||||
EndianStream.WriteUInt32(destination, 1 | (CueIndexFieldLength << 16) | (PositionFieldLength << 8));
|
EndianStream.WriteUInt32(destination, 1 | (CueIndexFieldLength << 16) | (PositionFieldLength << 8));
|
||||||
EndianStream.WriteUInt32(destination, (ushort)entries.Count);
|
EndianStream.WriteUInt32(destination, (ushort)entries.Count);
|
||||||
EndianStream.WriteUInt32(destination, 1);
|
EndianStream.WriteUInt32(destination, 1);
|
||||||
|
|
||||||
// FIXME: Alignment support
|
// FIXME: Alignment support
|
||||||
VldPool vldPool = new VldPool(1);
|
VldPool vldPool = new VldPool(1);
|
||||||
|
|
||||||
|
@ -11,73 +11,537 @@ namespace SonicAudioLib.Archive
|
|||||||
{
|
{
|
||||||
public class CriCpkEntry : EntryBase
|
public class CriCpkEntry : EntryBase
|
||||||
{
|
{
|
||||||
|
private DateTime updateDateTime;
|
||||||
|
|
||||||
public string DirectoryName { get; set; }
|
public string DirectoryName { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public uint Index { get; set; }
|
public uint Id { get; set; }
|
||||||
public string Comment { get; set; }
|
public string Comment { get; set; }
|
||||||
public bool IsCompressed { get; set; }
|
public bool IsCompressed { get; set; }
|
||||||
|
|
||||||
|
public DateTime UpdateDateTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (FilePath != null)
|
||||||
|
{
|
||||||
|
return FilePath.LastWriteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
updateDateTime = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CriCpkMode
|
||||||
|
{
|
||||||
|
None = -1,
|
||||||
|
FileNameIdAndGroup = 5,
|
||||||
|
IdAndGroup = 4,
|
||||||
|
FileNameAndGroup = 3,
|
||||||
|
FileNameAndId = 2,
|
||||||
|
FileName = 1,
|
||||||
|
Id = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CriCpkArchive : ArchiveBase<CriCpkEntry>
|
public class CriCpkArchive : ArchiveBase<CriCpkEntry>
|
||||||
{
|
{
|
||||||
|
private ushort align = 1;
|
||||||
|
private CriCpkMode mode = CriCpkMode.FileName;
|
||||||
|
|
||||||
|
public ushort Align
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return align;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value <= 0)
|
||||||
|
{
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
align = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CriCpkMode Mode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mode = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Comment { get; set; }
|
||||||
|
|
||||||
public override void Read(Stream source)
|
public override void Read(Stream source)
|
||||||
{
|
{
|
||||||
using (CriTableReader reader = CriCpkSection.Open(source, source.Position))
|
using (CriTableReader reader = CriCpkSection.Open(source, source.Position))
|
||||||
{
|
{
|
||||||
reader.Read();
|
reader.Read();
|
||||||
|
|
||||||
if (reader.GetUInt32("CpkMode") != 1)
|
#if DEBUG
|
||||||
|
for (int i = 0; i < reader.NumberOfFields; i++)
|
||||||
{
|
{
|
||||||
throw new Exception("Unsupported CPK type! Only TOC CPKs are supported for now.");
|
Console.WriteLine("{0} ({1}): {2}", reader.GetFieldName(i), reader.GetFieldFlag(i), reader.GetValue(i));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mode = (CriCpkMode)reader.GetUInt32("CpkMode");
|
||||||
|
|
||||||
|
// No need to waste time, stop right there.
|
||||||
|
if (mode == CriCpkMode.None)
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long tocPosition = (long)reader.GetUInt64("TocOffset");
|
long tocPosition = (long)reader.GetUInt64("TocOffset");
|
||||||
|
long itocPosition = (long)reader.GetUInt64("ItocOffset");
|
||||||
|
long etocPosition = (long)reader.GetUInt64("EtocOffset");
|
||||||
long contentPosition = (long)reader.GetUInt64("ContentOffset");
|
long contentPosition = (long)reader.GetUInt64("ContentOffset");
|
||||||
ushort align = reader.GetUInt16("Align");
|
|
||||||
|
|
||||||
using (CriTableReader tocReader = CriCpkSection.Open(source, tocPosition))
|
align = reader.GetUInt16("Align");
|
||||||
|
|
||||||
|
if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId)
|
||||||
{
|
{
|
||||||
while (tocReader.Read())
|
using (CriTableReader tocReader = CriCpkSection.Open(source, tocPosition))
|
||||||
|
using (CriTableReader etocReader = CriCpkSection.Open(source, etocPosition))
|
||||||
{
|
{
|
||||||
CriCpkEntry entry = new CriCpkEntry();
|
while (tocReader.Read())
|
||||||
entry.DirectoryName = tocReader.GetString("DirName");
|
|
||||||
entry.Name = tocReader.GetString("FileName");
|
|
||||||
entry.Length = tocReader.GetUInt32("FileSize");
|
|
||||||
entry.Position = (long)tocReader.GetUInt64("FileOffset");
|
|
||||||
entry.Index = tocReader.GetUInt32("ID");
|
|
||||||
entry.Comment = tocReader.GetString("UserString");
|
|
||||||
|
|
||||||
if (entry.Length != tocReader.GetUInt32("ExtractSize"))
|
|
||||||
{
|
{
|
||||||
entry.IsCompressed = true;
|
CriCpkEntry entry = new CriCpkEntry();
|
||||||
}
|
entry.DirectoryName = tocReader.GetString("DirName");
|
||||||
|
entry.Name = tocReader.GetString("FileName");
|
||||||
|
entry.Length = tocReader.GetUInt32("FileSize");
|
||||||
|
entry.Position = (long)tocReader.GetUInt64("FileOffset");
|
||||||
|
entry.Id = tocReader.GetUInt32("ID");
|
||||||
|
entry.Comment = tocReader.GetString("UserString");
|
||||||
|
|
||||||
if (contentPosition < tocPosition)
|
if (entry.Length != tocReader.GetUInt32("ExtractSize"))
|
||||||
|
{
|
||||||
|
entry.IsCompressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentPosition < tocPosition)
|
||||||
|
{
|
||||||
|
entry.Position += contentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.Position += tocPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((entry.Position % align) != 0)
|
||||||
|
{
|
||||||
|
entry.Position++;
|
||||||
|
}
|
||||||
|
|
||||||
|
etocReader.MoveToRow(tocReader.CurrentRow);
|
||||||
|
entry.UpdateDateTime = DateTimeFromCpkDateTime(etocReader.GetUInt64("UpdateDateTime"));
|
||||||
|
|
||||||
|
entries.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == CriCpkMode.FileNameAndId)
|
||||||
|
{
|
||||||
|
using (CriTableReader itocReader = CriCpkSection.Open(source, itocPosition))
|
||||||
{
|
{
|
||||||
entry.Position += contentPosition;
|
while (itocReader.Read())
|
||||||
|
{
|
||||||
|
entries[itocReader.GetInt32("TocIndex")].Id = (uint)itocReader.GetInt32("ID");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry.Position += tocPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((entry.Position % align) != 0)
|
|
||||||
{
|
|
||||||
entry.Position++;
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.Add(entry);
|
|
||||||
|
|
||||||
Console.WriteLine(Path.Combine(entry.DirectoryName, entry.Name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (mode == CriCpkMode.Id)
|
||||||
|
{
|
||||||
|
long currentPosition = contentPosition;
|
||||||
|
|
||||||
|
using (CriTableReader itocReader = CriCpkSection.Open(source, itocPosition))
|
||||||
|
{
|
||||||
|
while (itocReader.Read())
|
||||||
|
{
|
||||||
|
if (itocReader.GetUInt32("FilesL") > 0)
|
||||||
|
{
|
||||||
|
using (CriTableReader dataReader = itocReader.GetCriTableReader("DataL"))
|
||||||
|
{
|
||||||
|
while (dataReader.Read())
|
||||||
|
{
|
||||||
|
CriCpkEntry entry = new CriCpkEntry();
|
||||||
|
entry.Id = dataReader.GetUInt16("ID");
|
||||||
|
entry.Length = dataReader.GetUInt16("FileSize");
|
||||||
|
|
||||||
|
if (entry.Length != dataReader.GetUInt16("ExtractSize"))
|
||||||
|
{
|
||||||
|
entry.IsCompressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((currentPosition % align) != 0)
|
||||||
|
{
|
||||||
|
currentPosition++;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.Position = currentPosition;
|
||||||
|
entries.Add(entry);
|
||||||
|
|
||||||
|
currentPosition += entry.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itocReader.GetUInt32("FilesH") > 0)
|
||||||
|
{
|
||||||
|
using (CriTableReader dataReader = itocReader.GetCriTableReader("DataH"))
|
||||||
|
{
|
||||||
|
while (dataReader.Read())
|
||||||
|
{
|
||||||
|
CriCpkEntry entry = new CriCpkEntry();
|
||||||
|
entry.Id = dataReader.GetUInt16("ID");
|
||||||
|
entry.Length = dataReader.GetUInt32("FileSize");
|
||||||
|
|
||||||
|
if (entry.Length != dataReader.GetUInt32("ExtractSize"))
|
||||||
|
{
|
||||||
|
entry.IsCompressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((currentPosition % align) != 0)
|
||||||
|
{
|
||||||
|
currentPosition++;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.Position = currentPosition;
|
||||||
|
entries.Add(entry);
|
||||||
|
|
||||||
|
currentPosition += entry.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"This CPK mode ({mode}) needs to be implemented. Please report this error with the file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Comment = reader.GetString("Comment");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(Stream destination)
|
public override void Write(Stream destination)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// FIXME: Alignment support (ugh same thing for AFS2 archives)
|
||||||
|
VldPool vldPool = new VldPool();
|
||||||
|
|
||||||
|
using (CriCpkSection cpkSection = new CriCpkSection(destination, "CPK "))
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteStartTable("CpkHeader");
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("UpdateDateTime", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("FileSize", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("ContentOffset", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("ContentSize", typeof(ulong));
|
||||||
|
|
||||||
|
if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId)
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteField("TocOffset", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("TocSize", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("TocCrc", typeof(uint), null);
|
||||||
|
cpkSection.Writer.WriteField("EtocOffset", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("EtocSize", typeof(ulong));
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteField("TocOffset", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("TocSize", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("TocCrc", typeof(uint), null);
|
||||||
|
cpkSection.Writer.WriteField("EtocOffset", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("EtocSize", typeof(ulong), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == CriCpkMode.Id || mode == CriCpkMode.FileNameAndId)
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteField("ItocOffset", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("ItocSize", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("ItocCrc", typeof(uint), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteField("ItocOffset", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("ItocSize", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("ItocCrc", typeof(uint), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("GtocOffset", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("GtocSize", typeof(ulong), null);
|
||||||
|
cpkSection.Writer.WriteField("GtocCrc", typeof(uint), null);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("EnabledPackedSize", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("EnabledDataSize", typeof(ulong));
|
||||||
|
cpkSection.Writer.WriteField("TotalDataSize", typeof(ulong), null);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("Tocs", typeof(uint), null);
|
||||||
|
cpkSection.Writer.WriteField("Files", typeof(uint));
|
||||||
|
cpkSection.Writer.WriteField("Groups", typeof(uint));
|
||||||
|
cpkSection.Writer.WriteField("Attrs", typeof(uint));
|
||||||
|
cpkSection.Writer.WriteField("TotalFiles", typeof(uint), null);
|
||||||
|
cpkSection.Writer.WriteField("Directories", typeof(uint), null);
|
||||||
|
cpkSection.Writer.WriteField("Updates", typeof(uint), null);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("Version", typeof(ushort));
|
||||||
|
cpkSection.Writer.WriteField("Revision", typeof(ushort));
|
||||||
|
cpkSection.Writer.WriteField("Align", typeof(ushort));
|
||||||
|
cpkSection.Writer.WriteField("Sorted", typeof(ushort));
|
||||||
|
cpkSection.Writer.WriteField("EID", typeof(ushort), null);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("CpkMode", typeof(uint));
|
||||||
|
cpkSection.Writer.WriteField("Tvers", typeof(string));
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Comment))
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteField("Comment", typeof(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteField("Comment", typeof(string), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteField("Codec", typeof(uint));
|
||||||
|
cpkSection.Writer.WriteField("DpkItoc", typeof(uint));
|
||||||
|
|
||||||
|
MemoryStream tocMemoryStream = null;
|
||||||
|
MemoryStream itocMemoryStream = null;
|
||||||
|
MemoryStream etocMemoryStream = null;
|
||||||
|
|
||||||
|
if (mode == CriCpkMode.FileName || mode == CriCpkMode.FileNameAndId)
|
||||||
|
{
|
||||||
|
tocMemoryStream = new MemoryStream();
|
||||||
|
etocMemoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
using (CriCpkSection tocSection = new CriCpkSection(tocMemoryStream, "TOC "))
|
||||||
|
using (CriCpkSection etocSection = new CriCpkSection(etocMemoryStream, "ETOC"))
|
||||||
|
{
|
||||||
|
tocSection.Writer.WriteStartTable("CpkTocInfo");
|
||||||
|
|
||||||
|
tocSection.Writer.WriteField("DirName", typeof(string));
|
||||||
|
tocSection.Writer.WriteField("FileName", typeof(string));
|
||||||
|
tocSection.Writer.WriteField("FileSize", typeof(uint));
|
||||||
|
tocSection.Writer.WriteField("ExtractSize", typeof(uint));
|
||||||
|
tocSection.Writer.WriteField("FileOffset", typeof(ulong));
|
||||||
|
tocSection.Writer.WriteField("ID", typeof(uint));
|
||||||
|
tocSection.Writer.WriteField("UserString", typeof(string));
|
||||||
|
|
||||||
|
etocSection.Writer.WriteStartTable("CpkEtocInfo");
|
||||||
|
|
||||||
|
etocSection.Writer.WriteField("UpdateDateTime", typeof(ulong));
|
||||||
|
etocSection.Writer.WriteField("LocalDir", typeof(string));
|
||||||
|
|
||||||
|
foreach (CriCpkEntry entry in entries)
|
||||||
|
{
|
||||||
|
tocSection.Writer.WriteRow(true, entry.DirectoryName, entry.Name, Convert.ToUInt32(entry.Length), Convert.ToUInt32(entry.Length), Convert.ToUInt64(vldPool.Put(entry.FilePath)), entry.Id, entry.Comment);
|
||||||
|
etocSection.Writer.WriteRow(true, CpkDateTimeFromDateTime(entry.UpdateDateTime), entry.DirectoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
tocSection.Writer.WriteEndTable();
|
||||||
|
etocSection.Writer.WriteEndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == CriCpkMode.FileNameAndId)
|
||||||
|
{
|
||||||
|
itocMemoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
using (CriCpkSection itocSection = new CriCpkSection(itocMemoryStream, "ITOC"))
|
||||||
|
{
|
||||||
|
itocSection.Writer.WriteStartTable("CpkExtendId");
|
||||||
|
|
||||||
|
itocSection.Writer.WriteField("ID", typeof(int));
|
||||||
|
itocSection.Writer.WriteField("TocIndex", typeof(int));
|
||||||
|
|
||||||
|
foreach (CriCpkEntry entry in entries)
|
||||||
|
{
|
||||||
|
itocSection.Writer.WriteRow(true, Convert.ToInt32(entry.Id), entries.IndexOf(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
itocSection.Writer.WriteEndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (mode == CriCpkMode.Id)
|
||||||
|
{
|
||||||
|
itocMemoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
using (CriCpkSection itocSection = new CriCpkSection(itocMemoryStream, "ITOC"))
|
||||||
|
{
|
||||||
|
itocSection.Writer.WriteStartTable("CpkItocInfo");
|
||||||
|
|
||||||
|
itocSection.Writer.WriteField("FilesL", typeof(uint));
|
||||||
|
itocSection.Writer.WriteField("FilesH", typeof(uint));
|
||||||
|
itocSection.Writer.WriteField("DataL", typeof(byte[]));
|
||||||
|
itocSection.Writer.WriteField("DataH", typeof(byte[]));
|
||||||
|
|
||||||
|
List<CriCpkEntry> filesL = entries.Where(entry => entry.Length < ushort.MaxValue).ToList();
|
||||||
|
List<CriCpkEntry> filesH = entries.Where(entry => entry.Length > ushort.MaxValue).ToList();
|
||||||
|
|
||||||
|
ushort id = 0;
|
||||||
|
|
||||||
|
itocSection.Writer.WriteStartRow();
|
||||||
|
|
||||||
|
using (MemoryStream dataMemoryStream = new MemoryStream())
|
||||||
|
using (CriTableWriter dataWriter = CriTableWriter.Create(dataMemoryStream))
|
||||||
|
{
|
||||||
|
dataWriter.WriteStartTable("CpkItocL");
|
||||||
|
|
||||||
|
dataWriter.WriteField("ID", typeof(ushort));
|
||||||
|
dataWriter.WriteField("FileSize", typeof(ushort));
|
||||||
|
dataWriter.WriteField("ExtractSize", typeof(ushort));
|
||||||
|
|
||||||
|
foreach (CriCpkEntry entry in filesL)
|
||||||
|
{
|
||||||
|
dataWriter.WriteRow(true, id, Convert.ToUInt16(entry.Length), Convert.ToUInt16(entry.Length));
|
||||||
|
vldPool.Put(entry.FilePath);
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataWriter.WriteEndTable();
|
||||||
|
|
||||||
|
itocSection.Writer.WriteValue("DataL", dataMemoryStream.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
using (MemoryStream dataMemoryStream = new MemoryStream())
|
||||||
|
using (CriTableWriter dataWriter = CriTableWriter.Create(dataMemoryStream))
|
||||||
|
{
|
||||||
|
dataWriter.WriteStartTable("CpkItocH");
|
||||||
|
|
||||||
|
dataWriter.WriteField("ID", typeof(ushort));
|
||||||
|
dataWriter.WriteField("FileSize", typeof(uint));
|
||||||
|
dataWriter.WriteField("ExtractSize", typeof(uint));
|
||||||
|
|
||||||
|
foreach (CriCpkEntry entry in filesH)
|
||||||
|
{
|
||||||
|
dataWriter.WriteRow(true, id, Convert.ToUInt32(entry.Length), Convert.ToUInt32(entry.Length));
|
||||||
|
vldPool.Put(entry.FilePath);
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataWriter.WriteEndTable();
|
||||||
|
|
||||||
|
itocSection.Writer.WriteValue("DataH", dataMemoryStream.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
itocSection.Writer.WriteValue("FilesL", (uint)filesL.Count);
|
||||||
|
itocSection.Writer.WriteValue("FilesH", (uint)filesH.Count);
|
||||||
|
itocSection.Writer.WriteEndRow();
|
||||||
|
itocSection.Writer.WriteEndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"This CPK mode ({mode}) isn't implemented yet! Please choose another mode.");
|
||||||
|
}
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteStartRow();
|
||||||
|
cpkSection.Writer.WriteValue("UpdateDateTime", CpkDateTimeFromDateTime(DateTime.Now));
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteValue("ContentOffset", Convert.ToUInt64(2048));
|
||||||
|
cpkSection.Writer.WriteValue("ContentSize", Convert.ToUInt64(vldPool.Length));
|
||||||
|
|
||||||
|
if (tocMemoryStream != null)
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteValue("TocOffset", Convert.ToUInt64(2048 + vldPool.Put(tocMemoryStream)));
|
||||||
|
cpkSection.Writer.WriteValue("TocSize", Convert.ToUInt64(tocMemoryStream.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itocMemoryStream != null)
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteValue("ItocOffset", Convert.ToUInt64(2048 + vldPool.Put(itocMemoryStream)));
|
||||||
|
cpkSection.Writer.WriteValue("ItocSize", Convert.ToUInt64(itocMemoryStream.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (etocMemoryStream != null)
|
||||||
|
{
|
||||||
|
cpkSection.Writer.WriteValue("EtocOffset", Convert.ToUInt64(2048 + vldPool.Put(etocMemoryStream)));
|
||||||
|
cpkSection.Writer.WriteValue("EtocSize", Convert.ToUInt64(etocMemoryStream.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint totalDataSize = 0;
|
||||||
|
foreach (CriCpkEntry entry in entries)
|
||||||
|
{
|
||||||
|
totalDataSize += (uint)entry.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteValue("EnabledPackedSize", totalDataSize);
|
||||||
|
cpkSection.Writer.WriteValue("EnabledDataSize", totalDataSize);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteValue("Files", Convert.ToUInt32(entries.Count));
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteValue("Version", (ushort)7);
|
||||||
|
cpkSection.Writer.WriteValue("Revision", (ushort)2);
|
||||||
|
cpkSection.Writer.WriteValue("Align", (ushort)1);
|
||||||
|
cpkSection.Writer.WriteValue("Sorted", (ushort)1);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteValue("CpkMode", (uint)mode);
|
||||||
|
cpkSection.Writer.WriteValue("Tvers", "SonicAudioLib");
|
||||||
|
cpkSection.Writer.WriteValue("Comment", Comment);
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteValue("FileSize", Convert.ToUInt64(2048 + (ulong)vldPool.Length));
|
||||||
|
|
||||||
|
cpkSection.Writer.WriteEndRow();
|
||||||
|
cpkSection.Writer.WriteEndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((destination.Position % 2042) != 0)
|
||||||
|
{
|
||||||
|
destination.WriteByte(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndianStream.WriteCString(destination, "(c)CRI", 6);
|
||||||
|
|
||||||
|
vldPool.Write(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime DateTimeFromCpkDateTime(ulong dateTime)
|
||||||
|
{
|
||||||
|
if (dateTime == 0)
|
||||||
|
{
|
||||||
|
return new DateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DateTime(
|
||||||
|
(int)(uint)(dateTime >> 32) >> 16, // year
|
||||||
|
(int)(uint)(dateTime >> 32) >> 8 & byte.MaxValue, // month
|
||||||
|
(int)(uint)(dateTime >> 32) & byte.MaxValue, // day
|
||||||
|
(int)(uint)dateTime >> 24, // hour
|
||||||
|
(int)(uint)dateTime >> 16 & byte.MaxValue, // minute
|
||||||
|
(int)(uint)dateTime >> 8 & byte.MaxValue // second
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ulong CpkDateTimeFromDateTime(DateTime dateTime)
|
||||||
|
{
|
||||||
|
return ((((ulong)dateTime.Year * 0x100 + (uint)dateTime.Month) * 0x100 + (uint)dateTime.Day) * 0x100000000) +
|
||||||
|
((((ulong)dateTime.Hour * 0x100 + (uint)dateTime.Minute) * 0x100 + (uint)dateTime.Second) * 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CriCpkSection : IDisposable
|
private class CriCpkSection : IDisposable
|
||||||
@ -100,7 +564,7 @@ namespace SonicAudioLib.Archive
|
|||||||
writer.Dispose();
|
writer.Dispose();
|
||||||
|
|
||||||
long position = destination.Position;
|
long position = destination.Position;
|
||||||
uint length = (uint)(position - (headerPosition - 8));
|
uint length = (uint)(position - (headerPosition) - 16);
|
||||||
|
|
||||||
destination.Seek(headerPosition + 8, SeekOrigin.Begin);
|
destination.Seek(headerPosition + 8, SeekOrigin.Begin);
|
||||||
EndianStream.WriteUInt32(destination, length);
|
EndianStream.WriteUInt32(destination, length);
|
||||||
@ -117,7 +581,15 @@ namespace SonicAudioLib.Archive
|
|||||||
uint tableLength = EndianStream.ReadUInt32(source);
|
uint tableLength = EndianStream.ReadUInt32(source);
|
||||||
uint unknown = EndianStream.ReadUInt32(source);
|
uint unknown = EndianStream.ReadUInt32(source);
|
||||||
|
|
||||||
return CriTableReader.Create(new Substream(source, source.Position, tableLength));
|
try
|
||||||
|
{
|
||||||
|
return CriTableReader.Create(new Substream(source, source.Position, tableLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new Exception("CPK file decryption needs to be implemented or it's an unknown error. Please report this error with the file.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CriCpkSection(Stream destination, string signature)
|
public CriCpkSection(Stream destination, string signature)
|
||||||
@ -127,9 +599,9 @@ namespace SonicAudioLib.Archive
|
|||||||
|
|
||||||
EndianStream.WriteCString(destination, signature, 4);
|
EndianStream.WriteCString(destination, signature, 4);
|
||||||
EndianStream.WriteUInt32(destination, byte.MaxValue);
|
EndianStream.WriteUInt32(destination, byte.MaxValue);
|
||||||
destination.Seek(8, SeekOrigin.Begin);
|
destination.Seek(8, SeekOrigin.Current);
|
||||||
|
|
||||||
writer = CriTableWriter.Create(destination);
|
writer = CriTableWriter.Create(destination, new CriTableWriterSettings() { LeaveOpen = true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,9 +101,23 @@ namespace SonicAudioLib.CriMw
|
|||||||
writer.WriteStartFieldCollection();
|
writer.WriteStartFieldCollection();
|
||||||
foreach (CriField criField in fields)
|
foreach (CriField criField in fields)
|
||||||
{
|
{
|
||||||
if (!rows.Any(row => row[criField] != criField.DefaultValue))
|
bool useDefaultValue = false;
|
||||||
|
object defaultValue = null;
|
||||||
|
|
||||||
|
if (rows.Count > 1)
|
||||||
{
|
{
|
||||||
writer.WriteField(criField.FieldName, criField.FieldType, criField.DefaultValue);
|
useDefaultValue = true;
|
||||||
|
defaultValue = rows[0][criField];
|
||||||
|
|
||||||
|
if (rows.Any(row => !row[criField].Equals(defaultValue)))
|
||||||
|
{
|
||||||
|
useDefaultValue = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useDefaultValue)
|
||||||
|
{
|
||||||
|
writer.WriteField(criField.FieldName, criField.FieldType, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -166,14 +166,14 @@ namespace SonicAudioLib.CriMw
|
|||||||
return fields[fieldIndex].Value;
|
return fields[fieldIndex].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte GetFieldFlag(string fieldName)
|
internal CriFieldFlag GetFieldFlag(string fieldName)
|
||||||
{
|
{
|
||||||
return (byte)fields[fieldName].Flag;
|
return fields[fieldName].Flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte GetFieldFlag(int fieldIndex)
|
internal CriFieldFlag GetFieldFlag(int fieldIndex)
|
||||||
{
|
{
|
||||||
return (byte)fields[fieldIndex].Flag;
|
return fields[fieldIndex].Flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object GetFieldValue(string fieldName)
|
public object GetFieldValue(string fieldName)
|
||||||
@ -438,6 +438,16 @@ namespace SonicAudioLib.CriMw
|
|||||||
return GetData(fields.IndexOf(fieldName));
|
return GetData(fields.IndexOf(fieldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CriTableReader GetCriTableReader(string fieldName)
|
||||||
|
{
|
||||||
|
return new CriTableReader(GetSubstream(fieldName), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CriTableReader GetCriTableReader(int fieldIndex)
|
||||||
|
{
|
||||||
|
return new CriTableReader(GetSubstream(fieldIndex), false);
|
||||||
|
}
|
||||||
|
|
||||||
public uint GetLength(int fieldIndex)
|
public uint GetLength(int fieldIndex)
|
||||||
{
|
{
|
||||||
if (fieldIndex < 0 || fieldIndex >= fields.Count)
|
if (fieldIndex < 0 || fieldIndex >= fields.Count)
|
||||||
@ -583,7 +593,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
if (strResult == "<NULL>" ||
|
if (strResult == "<NULL>" ||
|
||||||
(strResult == header.TableName && stringPosition == 0))
|
(strResult == header.TableName && stringPosition == 0))
|
||||||
{
|
{
|
||||||
return null;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
return strResult;
|
return strResult;
|
||||||
|
@ -28,7 +28,6 @@ namespace SonicAudioLib.CriMw
|
|||||||
private VldPool vldPool;
|
private VldPool vldPool;
|
||||||
private StringPool stringPool;
|
private StringPool stringPool;
|
||||||
private uint headerPosition;
|
private uint headerPosition;
|
||||||
private uint endPosition;
|
|
||||||
|
|
||||||
private Status status = Status.Begin;
|
private Status status = Status.Begin;
|
||||||
|
|
||||||
@ -115,6 +114,8 @@ namespace SonicAudioLib.CriMw
|
|||||||
destination.WriteByte(0);
|
destination.WriteByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long previousPosition = destination.Position;
|
||||||
|
|
||||||
header.Length = (uint)destination.Position - headerPosition;
|
header.Length = (uint)destination.Position - headerPosition;
|
||||||
|
|
||||||
header.FirstBoolean = false;
|
header.FirstBoolean = false;
|
||||||
@ -131,7 +132,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
WriteUInt16(header.NumberOfFields);
|
WriteUInt16(header.NumberOfFields);
|
||||||
WriteUInt16(header.RowLength);
|
WriteUInt16(header.RowLength);
|
||||||
WriteUInt32(header.NumberOfRows);
|
WriteUInt32(header.NumberOfRows);
|
||||||
destination.Seek(0, SeekOrigin.End);
|
destination.Seek(previousPosition, SeekOrigin.Begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteStartFieldCollection()
|
public void WriteStartFieldCollection()
|
||||||
@ -269,7 +270,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
|
|
||||||
public void WriteValue(string fieldName, object rowValue)
|
public void WriteValue(string fieldName, object rowValue)
|
||||||
{
|
{
|
||||||
WriteValue(fields.IndexOf(fieldName));
|
WriteValue(fields.IndexOf(fieldName), rowValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GoToValue(int fieldIndex)
|
private void GoToValue(int fieldIndex)
|
||||||
@ -654,7 +655,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
leaveOpen = true;
|
leaveOpen = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,7 +691,7 @@ namespace SonicAudioLib.CriMw
|
|||||||
{
|
{
|
||||||
return new CriTableWriterSettings()
|
return new CriTableWriterSettings()
|
||||||
{
|
{
|
||||||
Align = 4,
|
Align = 8,
|
||||||
PutBlankString = true,
|
PutBlankString = true,
|
||||||
RemoveDuplicateStrings = true,
|
RemoveDuplicateStrings = true,
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,28 @@ namespace SonicAudioLib.CriMw.Serialization
|
|||||||
{
|
{
|
||||||
public static class CriTableSerializer
|
public static class CriTableSerializer
|
||||||
{
|
{
|
||||||
|
public static byte[] Serialize<T>(List<T> objects, CriTableWriterSettings settings)
|
||||||
|
{
|
||||||
|
using (MemoryStream destination = new MemoryStream())
|
||||||
|
{
|
||||||
|
Serialize(destination, objects, settings);
|
||||||
|
return destination.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Serialize<T>(string destinationFileName, List<T> objects, CriTableWriterSettings settings)
|
||||||
|
{
|
||||||
|
using (Stream destination = File.Create(destinationFileName))
|
||||||
|
{
|
||||||
|
Serialize(destination, objects, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Serialize<T>(Stream destination, List<T> objects, CriTableWriterSettings settings)
|
||||||
|
{
|
||||||
|
Serialize(destination, typeof(T), objects, settings);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Serialize(Stream destination, Type type, ICollection objects, CriTableWriterSettings settings)
|
public static void Serialize(Stream destination, Type type, ICollection objects, CriTableWriterSettings settings)
|
||||||
{
|
{
|
||||||
ArrayList arrayList = null;
|
ArrayList arrayList = null;
|
||||||
@ -45,11 +67,11 @@ namespace SonicAudioLib.CriMw.Serialization
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also ignore the properties that are not supportable (except FileInfo, Stream and ICollection<>)
|
// Also ignore the properties that are not supportable (except FileInfo and Stream)
|
||||||
if (propertyInfo.PropertyType != typeof(FileInfo) &&
|
if (propertyInfo.PropertyType != typeof(FileInfo) &&
|
||||||
propertyInfo.PropertyType != typeof(Stream) &&
|
propertyInfo.PropertyType != typeof(Stream) &&
|
||||||
!CriField.FieldTypes.Contains(propertyInfo.PropertyType))
|
!CriField.FieldTypes.Contains(propertyInfo.PropertyType))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,26 +116,33 @@ namespace SonicAudioLib.CriMw.Serialization
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if all the rows have the same value for this field
|
bool useDefaultValue = false;
|
||||||
bool useDefaultValue = true;
|
|
||||||
|
|
||||||
if (arrayList != null && arrayList.Count > 0)
|
if (arrayList != null && arrayList.Count > 1)
|
||||||
{
|
{
|
||||||
useDefaultValue = true;
|
useDefaultValue = true;
|
||||||
|
|
||||||
foreach (object obj in arrayList)
|
defaultValue = propertyInfo.GetValue(arrayList[0]);
|
||||||
|
|
||||||
|
for (int i = 1; i < arrayList.Count; i++)
|
||||||
{
|
{
|
||||||
if (propertyInfo.GetValue(obj) != propertyInfo.GetValue(arrayList[0]))
|
object objectValue = propertyInfo.GetValue(arrayList[i]);
|
||||||
|
if (defaultValue != null)
|
||||||
|
{
|
||||||
|
if (!defaultValue.Equals(objectValue))
|
||||||
|
{
|
||||||
|
useDefaultValue = false;
|
||||||
|
defaultValue = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (objectValue != null)
|
||||||
{
|
{
|
||||||
useDefaultValue = false;
|
useDefaultValue = false;
|
||||||
|
defaultValue = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useDefaultValue)
|
|
||||||
{
|
|
||||||
defaultValue = propertyInfo.GetValue(arrayList[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useDefaultValue)
|
if (useDefaultValue)
|
||||||
@ -155,6 +184,37 @@ namespace SonicAudioLib.CriMw.Serialization
|
|||||||
tableWriter.Dispose();
|
tableWriter.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<T> Deserialize<T>(byte[] sourceByteArray)
|
||||||
|
{
|
||||||
|
return Deserialize(sourceByteArray, typeof(T)).OfType<T>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<T> Deserialize<T>(string sourceFileName)
|
||||||
|
{
|
||||||
|
return Deserialize(sourceFileName, typeof(T)).OfType<T>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<T> Deserialize<T>(Stream source)
|
||||||
|
{
|
||||||
|
return Deserialize(source, typeof(T)).OfType<T>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList Deserialize(byte[] sourceByteArray, Type type)
|
||||||
|
{
|
||||||
|
using (MemoryStream source = new MemoryStream(sourceByteArray))
|
||||||
|
{
|
||||||
|
return Deserialize(source, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList Deserialize(string sourceFileName, Type type)
|
||||||
|
{
|
||||||
|
using (Stream source = File.OpenRead(sourceFileName))
|
||||||
|
{
|
||||||
|
return Deserialize(source, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static ArrayList Deserialize(Stream source, Type type)
|
public static ArrayList Deserialize(Stream source, Type type)
|
||||||
{
|
{
|
||||||
ArrayList arrayList = new ArrayList();
|
ArrayList arrayList = new ArrayList();
|
||||||
@ -185,6 +245,11 @@ namespace SonicAudioLib.CriMw.Serialization
|
|||||||
if (fieldName == fieldNameMatch)
|
if (fieldName == fieldNameMatch)
|
||||||
{
|
{
|
||||||
object value = tableReader.GetValue(i);
|
object value = tableReader.GetValue(i);
|
||||||
|
if (propertyInfo.PropertyType == typeof(byte[]) && value is Substream)
|
||||||
|
{
|
||||||
|
value = ((Substream)value).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
propertyInfo.SetValue(obj, value);
|
propertyInfo.SetValue(obj, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user