mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2024-11-24 15:10:11 +01:00
239 lines
6.6 KiB
C#
239 lines
6.6 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
using SonicAudioLib.IO;
|
|
using SonicAudioLib.FileBases;
|
|
using System.Xml;
|
|
using System.Xml.Linq;
|
|
|
|
namespace SonicAudioLib.CriMw
|
|
{
|
|
public class CriTable : FileXmlBase
|
|
{
|
|
private CriFieldCollection fields;
|
|
private CriRowCollection rows;
|
|
private string tableName = "(no name)";
|
|
private CriTableWriterSettings writerSettings;
|
|
|
|
public CriFieldCollection Fields
|
|
{
|
|
get
|
|
{
|
|
return fields;
|
|
}
|
|
}
|
|
|
|
public CriRowCollection Rows
|
|
{
|
|
get
|
|
{
|
|
return rows;
|
|
}
|
|
}
|
|
|
|
public string TableName
|
|
{
|
|
get
|
|
{
|
|
return tableName;
|
|
}
|
|
|
|
set
|
|
{
|
|
tableName = value;
|
|
}
|
|
}
|
|
|
|
public CriTableWriterSettings WriterSettings
|
|
{
|
|
get
|
|
{
|
|
return writerSettings;
|
|
}
|
|
|
|
set
|
|
{
|
|
writerSettings = value;
|
|
}
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
rows.Clear();
|
|
fields.Clear();
|
|
}
|
|
|
|
public CriRow NewRow()
|
|
{
|
|
CriRow criRow = new CriRow(this);
|
|
|
|
foreach (CriField criField in fields)
|
|
{
|
|
criRow.Records.Add(new CriRowRecord { Field = criField, Value = criField.DefaultValue });
|
|
}
|
|
|
|
return criRow;
|
|
}
|
|
|
|
public override void Read(Stream source)
|
|
{
|
|
using (CriTableReader reader = CriTableReader.Create(source))
|
|
{
|
|
tableName = reader.TableName;
|
|
|
|
for (int i = 0; i < reader.NumberOfFields; i++)
|
|
{
|
|
fields.Add(reader.GetFieldName(i), reader.GetFieldType(i), reader.GetFieldValue(i));
|
|
}
|
|
|
|
while (reader.Read())
|
|
{
|
|
rows.Add(reader.GetValueArray());
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void Write(Stream destination)
|
|
{
|
|
using (CriTableWriter writer = CriTableWriter.Create(destination, writerSettings))
|
|
{
|
|
writer.WriteStartTable(tableName);
|
|
|
|
writer.WriteStartFieldCollection();
|
|
foreach (CriField criField in fields)
|
|
{
|
|
bool useDefaultValue = false;
|
|
object defaultValue = null;
|
|
|
|
if (rows.Count > 1)
|
|
{
|
|
useDefaultValue = true;
|
|
defaultValue = rows[0][criField];
|
|
|
|
if (rows.Any(row => !row[criField].Equals(defaultValue)))
|
|
{
|
|
useDefaultValue = false;
|
|
}
|
|
}
|
|
|
|
else if (rows.Count == 0)
|
|
{
|
|
useDefaultValue = true;
|
|
}
|
|
|
|
if (useDefaultValue)
|
|
{
|
|
writer.WriteField(criField.FieldName, criField.FieldType, defaultValue);
|
|
}
|
|
|
|
else
|
|
{
|
|
writer.WriteField(criField.FieldName, criField.FieldType);
|
|
}
|
|
}
|
|
writer.WriteEndFieldCollection();
|
|
|
|
foreach (CriRow criRow in rows)
|
|
{
|
|
writer.WriteRow(true, criRow.GetValueArray());
|
|
}
|
|
|
|
writer.WriteEndTable();
|
|
}
|
|
}
|
|
|
|
public override void ReadXml(XmlReader reader)
|
|
{
|
|
var document = XDocument.Load(reader);
|
|
|
|
foreach (XElement element in document.Root.Element(nameof(Fields)).Elements(nameof(CriField)))
|
|
{
|
|
fields.Add(
|
|
element.Element(nameof(CriField.FieldName)).Value,
|
|
Type.GetType(element.Element(nameof(CriField.FieldType)).Value)
|
|
);
|
|
}
|
|
|
|
foreach (XElement element in document.Root.Element(nameof(Rows)).Elements(nameof(CriRow)))
|
|
{
|
|
CriRow row = NewRow();
|
|
|
|
foreach (CriRowRecord record in row.Records)
|
|
{
|
|
if (record.Field.FieldType == typeof(byte[]))
|
|
{
|
|
record.Value = Convert.FromBase64String(element.Element(record.Field.FieldName).Value);
|
|
}
|
|
|
|
else
|
|
{
|
|
record.Value = Convert.ChangeType(element.Element(record.Field.FieldName).Value, record.Field.FieldType);
|
|
}
|
|
}
|
|
|
|
rows.Add(row);
|
|
}
|
|
}
|
|
|
|
public override void WriteXml(XmlWriter writer)
|
|
{
|
|
var document = new XDocument(new XElement(nameof(CriTable)));
|
|
document.Root.Add(new XElement(nameof(TableName), TableName));
|
|
|
|
var fieldsElement = new XElement(nameof(Fields));
|
|
|
|
foreach (CriField field in fields)
|
|
{
|
|
var fieldElement = new XElement(nameof(CriField));
|
|
|
|
fieldElement.Add(
|
|
new XElement(nameof(field.FieldName), field.FieldName),
|
|
new XElement(nameof(field.FieldType), field.FieldType.Name)
|
|
);
|
|
|
|
fieldsElement.Add(fieldElement);
|
|
}
|
|
|
|
document.Root.Add(fieldsElement);
|
|
|
|
var rowsElement = new XElement(nameof(Rows));
|
|
|
|
foreach (CriRow row in rows)
|
|
{
|
|
var rowElement = new XElement(nameof(CriRow));
|
|
|
|
foreach (CriRowRecord record in row.Records)
|
|
{
|
|
if (record.Value is byte[] bytes)
|
|
{
|
|
rowElement.Add(new XElement(record.Field.FieldName, Convert.ToBase64String(bytes)));
|
|
}
|
|
|
|
else
|
|
{
|
|
rowElement.Add(new XElement(record.Field.FieldName, record.Value));
|
|
}
|
|
}
|
|
|
|
rowsElement.Add(rowElement);
|
|
}
|
|
|
|
document.Root.Add(rowsElement);
|
|
document.Save(writer);
|
|
}
|
|
|
|
public CriTable()
|
|
{
|
|
fields = new CriFieldCollection(this);
|
|
rows = new CriRowCollection(this);
|
|
writerSettings = new CriTableWriterSettings();
|
|
}
|
|
|
|
public CriTable(string tableName) : this()
|
|
{
|
|
this.tableName = tableName;
|
|
}
|
|
}
|
|
}
|