[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>
TapePartitionBlock = 0x54425054,
/// <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

View File

@@ -37,6 +37,8 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml;
using System.Xml.Serialization;
using Aaru.Checksums;
@@ -912,6 +914,47 @@ public sealed partial class AaruFormat
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
case BlockType.DumpHardwareBlock:
_structureBytes = new byte[Marshal.SizeOf<DumpHardwareHeader>()];

View File

@@ -255,11 +255,20 @@ public sealed partial class AaruFormat
public byte flags;
}
/// <summary>Geometry block, contains physical geometry information</summary>
/// <summary>CICM Metadata XML block</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CicmMetadataBlock
{
/// <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 uint length;
}

View File

@@ -38,6 +38,8 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml;
using System.Xml.Serialization;
using Aaru.Checksums;
@@ -1095,6 +1097,48 @@ public sealed partial class AaruFormat
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
case BlockType.DumpHardwareBlock:
_structureBytes = new byte[Marshal.SizeOf<DumpHardwareHeader>()];
@@ -2849,35 +2893,44 @@ public sealed partial class AaruFormat
_index.Add(idxEntry);
}
// If we have CICM XML metadata, write it
// If we have Aaru Metadata, write it
if(AaruMetadata != null)
{
var cicmMs = new MemoryStream();
var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(cicmMs, AaruMetadata);
var jsonMs = new MemoryStream();
JsonSerializer.Serialize(jsonMs, new MetadataJson
{
AaruMetadata = AaruMetadata
}, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
WriteIndented = true
});
idxEntry = new IndexEntry
{
blockType = BlockType.CicmBlock,
blockType = BlockType.AaruMetadataJsonBlock,
dataType = DataType.NoData,
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);
var cicmBlock = new CicmMetadataBlock
var jsonBlock = new AaruMetadataJsonBlock
{
identifier = BlockType.CicmBlock,
length = (uint)cicmMs.Length
identifier = BlockType.AaruMetadataJsonBlock,
length = (uint)jsonMs.Length
};
_structureBytes = new byte[Marshal.SizeOf<CicmMetadataBlock>()];
MemoryMarshal.Write(_structureBytes, ref cicmBlock);
_structureBytes = new byte[Marshal.SizeOf<AaruMetadataJsonBlock>()];
MemoryMarshal.Write(_structureBytes, ref jsonBlock);
_imageStream.Write(_structureBytes, 0, _structureBytes.Length);
_imageStream.Write(cicmMs.ToArray(), 0, (int)cicmMs.Length);
_imageStream.Write(jsonMs.ToArray(), 0, (int)jsonMs.Length);
_index.RemoveAll(t => t is { blockType: BlockType.CicmBlock, dataType: DataType.NoData });
// 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.AaruMetadataJsonBlock, dataType: DataType.NoData });
_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">
<value>The specified sector size does not correspond with the requested image extension.</value>
</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>