[AaruFormat] Read and write Aaru Metadata JSON to image.

This commit is contained in:
2022-12-16 02:37:17 +00:00
parent 4390b73d4d
commit df33cc260b
6 changed files with 8152 additions and 5130 deletions

View File

@@ -254,7 +254,9 @@ public sealed partial class AaruFormat
/// <summary>Block containing list of partitions for a tape image</summary> /// <summary>Block containing list of partitions for a tape image</summary>
TapePartitionBlock = 0x54425054, TapePartitionBlock = 0x54425054,
/// <summary>Block containing list of indexes for Compact Disc tracks</summary> /// <summary>Block containing list of indexes for Compact Disc tracks</summary>
CompactDiscIndexesBlock = 0x58494443 CompactDiscIndexesBlock = 0x58494443,
/// <summary>Block containing JSON version of Aaru Metadata</summary>
AaruMetadataJsonBlock = 0x444D534A
} }
enum ChecksumAlgorithm : byte enum ChecksumAlgorithm : byte

View File

@@ -37,6 +37,8 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml; using System.Xml;
using System.Xml.Serialization; using System.Xml.Serialization;
using Aaru.Checksums; using Aaru.Checksums;
@@ -912,6 +914,47 @@ public sealed partial class AaruFormat
break; break;
// Aaru Metadata JSON block
case BlockType.AaruMetadataJsonBlock:
_structureBytes = new byte[Marshal.SizeOf<AaruMetadataJsonBlock>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
AaruMetadataJsonBlock aaruMetadataBlock =
Marshal.SpanToStructureLittleEndian<AaruMetadataJsonBlock>(_structureBytes);
if(aaruMetadataBlock.identifier != BlockType.AaruMetadataJsonBlock)
break;
AaruConsole.DebugWriteLine("Aaru Format plugin",
Localization.Found_Aaru_Metadata_block_at_position_0, entry.offset);
AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes,
GC.GetTotalMemory(false));
byte[] jsonBytes = new byte[aaruMetadataBlock.length];
_imageStream.EnsureRead(jsonBytes, 0, jsonBytes.Length);
try
{
AaruMetadata = JsonSerializer.Deserialize<MetadataJson>(jsonBytes, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true
})?.AaruMetadata;
}
catch(JsonException ex)
{
AaruConsole.DebugWriteLine("Aaru Format plugin",
Localization.Exception_0_processing_Aaru_Metadata_block, ex.Message);
AaruMetadata = null;
}
AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes,
GC.GetTotalMemory(false));
break;
// Dump hardware block // Dump hardware block
case BlockType.DumpHardwareBlock: case BlockType.DumpHardwareBlock:
_structureBytes = new byte[Marshal.SizeOf<DumpHardwareHeader>()]; _structureBytes = new byte[Marshal.SizeOf<DumpHardwareHeader>()];

View File

@@ -255,11 +255,20 @@ public sealed partial class AaruFormat
public byte flags; public byte flags;
} }
/// <summary>Geometry block, contains physical geometry information</summary> /// <summary>CICM Metadata XML block</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CicmMetadataBlock struct CicmMetadataBlock
{ {
/// <summary>Identifier, <see cref="BlockType.CicmBlock" /></summary> /// <summary>Identifier, <see cref="BlockType.CicmBlock" /></summary>
public readonly BlockType identifier;
public readonly uint length;
}
/// <summary>Aaru Metadata JSON block</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AaruMetadataJsonBlock
{
/// <summary>Identifier, <see cref="BlockType.AaruMetadataJsonBlock" /></summary>
public BlockType identifier; public BlockType identifier;
public uint length; public uint length;
} }

View File

@@ -38,6 +38,8 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml; using System.Xml;
using System.Xml.Serialization; using System.Xml.Serialization;
using Aaru.Checksums; using Aaru.Checksums;
@@ -1095,6 +1097,48 @@ public sealed partial class AaruFormat
break; break;
// Aaru Metadata JSON block
case BlockType.AaruMetadataJsonBlock:
_structureBytes = new byte[Marshal.SizeOf<AaruMetadataJsonBlock>()];
_imageStream.EnsureRead(_structureBytes, 0, _structureBytes.Length);
AaruMetadataJsonBlock aaruMetadataBlock =
Marshal.SpanToStructureLittleEndian<AaruMetadataJsonBlock>(_structureBytes);
if(aaruMetadataBlock.identifier != BlockType.AaruMetadataJsonBlock)
break;
AaruConsole.DebugWriteLine("Aaru Format plugin",
Localization.Found_Aaru_Metadata_block_at_position_0, entry.offset);
AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes,
GC.GetTotalMemory(false));
byte[] jsonBytes = new byte[aaruMetadataBlock.length];
_imageStream.EnsureRead(jsonBytes, 0, jsonBytes.Length);
try
{
AaruMetadata = JsonSerializer.Deserialize<MetadataJson>(jsonBytes, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true
})?.AaruMetadata;
}
catch(JsonException ex)
{
AaruConsole.DebugWriteLine("Aaru Format plugin",
Localization.Exception_0_processing_Aaru_Metadata_block,
ex.Message);
AaruMetadata = null;
}
AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Memory_snapshot_0_bytes,
GC.GetTotalMemory(false));
break;
// Dump hardware block // Dump hardware block
case BlockType.DumpHardwareBlock: case BlockType.DumpHardwareBlock:
_structureBytes = new byte[Marshal.SizeOf<DumpHardwareHeader>()]; _structureBytes = new byte[Marshal.SizeOf<DumpHardwareHeader>()];
@@ -2849,35 +2893,44 @@ public sealed partial class AaruFormat
_index.Add(idxEntry); _index.Add(idxEntry);
} }
// If we have CICM XML metadata, write it // If we have Aaru Metadata, write it
if(AaruMetadata != null) if(AaruMetadata != null)
{ {
var cicmMs = new MemoryStream(); var jsonMs = new MemoryStream();
var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(cicmMs, AaruMetadata); JsonSerializer.Serialize(jsonMs, new MetadataJson
{
AaruMetadata = AaruMetadata
}, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
WriteIndented = true
});
idxEntry = new IndexEntry idxEntry = new IndexEntry
{ {
blockType = BlockType.CicmBlock, blockType = BlockType.AaruMetadataJsonBlock,
dataType = DataType.NoData, dataType = DataType.NoData,
offset = (ulong)_imageStream.Position offset = (ulong)_imageStream.Position
}; };
AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Writing_CICM_XML_block_to_position_0, AaruConsole.DebugWriteLine("Aaru Format plugin", Localization.Writing_Aaru_Metadata_block_to_position_0,
idxEntry.offset); idxEntry.offset);
var cicmBlock = new CicmMetadataBlock var jsonBlock = new AaruMetadataJsonBlock
{ {
identifier = BlockType.CicmBlock, identifier = BlockType.AaruMetadataJsonBlock,
length = (uint)cicmMs.Length length = (uint)jsonMs.Length
}; };
_structureBytes = new byte[Marshal.SizeOf<CicmMetadataBlock>()]; _structureBytes = new byte[Marshal.SizeOf<AaruMetadataJsonBlock>()];
MemoryMarshal.Write(_structureBytes, ref cicmBlock); MemoryMarshal.Write(_structureBytes, ref jsonBlock);
_imageStream.Write(_structureBytes, 0, _structureBytes.Length); _imageStream.Write(_structureBytes, 0, _structureBytes.Length);
_imageStream.Write(cicmMs.ToArray(), 0, (int)cicmMs.Length); _imageStream.Write(jsonMs.ToArray(), 0, (int)jsonMs.Length);
// Ensure no CICM XML block is recorded altogether
_index.RemoveAll(t => t is { blockType: BlockType.CicmBlock, dataType : DataType.NoData }); _index.RemoveAll(t => t is { blockType: BlockType.CicmBlock, dataType : DataType.NoData });
_index.RemoveAll(t => t is { blockType: BlockType.AaruMetadataJsonBlock, dataType: DataType.NoData });
_index.Add(idxEntry); _index.Add(idxEntry);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2903,4 +2903,13 @@
<data name="The_specified_sector_size_does_not_correspond_with_the_requested_image_extension" xml:space="preserve"> <data name="The_specified_sector_size_does_not_correspond_with_the_requested_image_extension" xml:space="preserve">
<value>The specified sector size does not correspond with the requested image extension.</value> <value>The specified sector size does not correspond with the requested image extension.</value>
</data> </data>
<data name="Found_Aaru_Metadata_block_at_position_0" xml:space="preserve">
<value>Found Aaru Metadata block at position {0}</value>
</data>
<data name="Exception_0_processing_Aaru_Metadata_block" xml:space="preserve">
<value>Exception {0} processing Aaru Metadata block</value>
</data>
<data name="Writing_Aaru_Metadata_block_to_position_0" xml:space="preserve">
<value>Writing Aaru Metadata block to position {0}</value>
</data>
</root> </root>