From 7c5b22a7736abb017c73b809bac9e5050c790411 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 20 Oct 2025 14:53:12 +0100 Subject: [PATCH] [AaruFormat] Implement handling for ISRC and Track Flags sector tags --- Aaru.Images/AaruFormat/Read.cs | 34 +++++++++ Aaru.Images/AaruFormat/Write.cs | 119 +++++++++++++++++++------------- 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs index a693de36e..f53da9d9a 100644 --- a/Aaru.Images/AaruFormat/Read.cs +++ b/Aaru.Images/AaruFormat/Read.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Structs; @@ -138,6 +139,39 @@ public sealed partial class AaruFormat public ErrorNumber ReadSectorTag(ulong sectorAddress, SectorTagType tag, out byte[] buffer) { buffer = null; + + switch(tag) + { + // Due to how we cache the tracks, we need to handle ISRC tags ourselves + case SectorTagType.CdTrackIsrc when _trackIsrcs != null: + { + if(_trackIsrcs.TryGetValue((int)sectorAddress, out string isrc)) + { + buffer = new byte[13]; + byte[] isrcBytes = Encoding.UTF8.GetBytes(isrc ?? ""); + Array.Copy(isrcBytes, 0, buffer, 0, Math.Min(isrcBytes.Length, 13)); + + return ErrorNumber.NoError; + } + + break; + } + + // Due to how we cache the tracks, we need to handle Track Flags ourselves + case SectorTagType.CdTrackFlags when _trackFlags != null: + { + if(_trackFlags.TryGetValue((int)sectorAddress, out byte flags)) + { + buffer = new byte[1]; + buffer[0] = flags; + + return ErrorNumber.NoError; + } + + break; + } + } + uint length = 0; Status res = aaruf_read_sector_tag(_context, sectorAddress, false, buffer, ref length, tag); diff --git a/Aaru.Images/AaruFormat/Write.cs b/Aaru.Images/AaruFormat/Write.cs index 7be41cc8d..09ad10833 100644 --- a/Aaru.Images/AaruFormat/Write.cs +++ b/Aaru.Images/AaruFormat/Write.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; @@ -10,6 +11,54 @@ namespace Aaru.Images; public sealed partial class AaruFormat { + // AARU_EXPORT int32_t AARU_CALL aaruf_write_sector(void *context, uint64_t sector_address, bool negative, + // const uint8_t *data, uint8_t sector_status, uint32_t length) + [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_sector", SetLastError = true)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] + private static partial Status aaruf_write_sector(IntPtr context, ulong sectorAddress, + [MarshalAs(UnmanagedType.I4)] bool negative, [In] byte[] data, + SectorStatus sectorStatus, uint length); + + // AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_long(void *context, uint64_t sector_address, bool negative, + // const uint8_t *data, uint8_t sector_status, uint32_t length) + [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_sector_long", SetLastError = true)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] + private static partial Status aaruf_write_sector_long(IntPtr context, ulong sectorAddress, + [MarshalAs(UnmanagedType.I4)] bool negative, [In] byte[] data, + SectorStatus sectorStatus, uint length); + + // AARU_EXPORT int32_t AARU_CALL aaruf_write_media_tag(void *context, const uint8_t *data, const int32_t type, + // const uint32_t length) + [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_media_tag", SetLastError = true)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] + private static partial Status aaruf_write_media_tag(IntPtr context, [In] byte[] data, MediaTagType type, + uint length); + + // AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_tag(void *context, const uint64_t sector_address, const bool negative, + // const uint8_t *data, const size_t length, const int32_t tag) + [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_sector_tag", SetLastError = true)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] + private static partial Status aaruf_write_sector_tag(IntPtr context, ulong sectorAddress, + [MarshalAs(UnmanagedType.I4)] bool negative, [In] byte[] data, + nuint length, SectorTagType tag); + + // AARU_EXPORT void AARU_CALL *aaruf_create(const char *filepath, const uint32_t media_type, const uint32_t sector_size, + // const uint64_t user_sectors, const uint64_t negative_sectors, + // const uint64_t overflow_sectors, const char *options, + // const uint8_t *application_name, const uint8_t application_name_length, + // const uint8_t application_major_version, + // const uint8_t application_minor_version, const bool is_tape) + [LibraryImport("libaaruformat", + EntryPoint = "aaruf_create", + SetLastError = true, + StringMarshalling = StringMarshalling.Utf8)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] + private static partial IntPtr aaruf_create(string filepath, MediaType mediaType, uint sectorSize, ulong userSectors, + ulong negativeSectors, ulong overflowSectors, string options, + string applicationName, byte applicationNameLength, + byte applicationMajorVersion, byte applicationMinorVersion, + [MarshalAs(UnmanagedType.I4)] bool isTape); + #region IWritableOpticalImage Members /// @@ -52,6 +101,28 @@ public sealed partial class AaruFormat /// public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag) { + switch(tag) + { + // Due to how we cache the tracks, we need to handle ISRC tags ourselves + case SectorTagType.CdTrackIsrc: + _trackIsrcs ??= []; + _trackIsrcs[(int)sectorAddress] = Encoding.UTF8.GetString(data).TrimEnd('\0'); + + return true; + + // Due to how we cache the tracks, we need to handle Track Flags ourselves + case SectorTagType.CdTrackFlags: + { + _trackFlags ??= []; + + if(data.Length <= 0) return false; + + _trackFlags[(int)sectorAddress] = data[0]; + + return true; + } + } + Status res = aaruf_write_sector_tag(_context, sectorAddress, false, data, (nuint)data.Length, tag); if(res == Status.Ok) return true; @@ -149,52 +220,4 @@ public sealed partial class AaruFormat } #endregion - - // AARU_EXPORT int32_t AARU_CALL aaruf_write_sector(void *context, uint64_t sector_address, bool negative, - // const uint8_t *data, uint8_t sector_status, uint32_t length) - [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_sector", SetLastError = true)] - [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] - private static partial Status aaruf_write_sector(IntPtr context, ulong sectorAddress, - [MarshalAs(UnmanagedType.I4)] bool negative, [In] byte[] data, - SectorStatus sectorStatus, uint length); - - // AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_long(void *context, uint64_t sector_address, bool negative, - // const uint8_t *data, uint8_t sector_status, uint32_t length) - [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_sector_long", SetLastError = true)] - [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] - private static partial Status aaruf_write_sector_long(IntPtr context, ulong sectorAddress, - [MarshalAs(UnmanagedType.I4)] bool negative, [In] byte[] data, - SectorStatus sectorStatus, uint length); - - // AARU_EXPORT int32_t AARU_CALL aaruf_write_media_tag(void *context, const uint8_t *data, const int32_t type, - // const uint32_t length) - [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_media_tag", SetLastError = true)] - [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] - private static partial Status aaruf_write_media_tag(IntPtr context, [In] byte[] data, MediaTagType type, - uint length); - - // AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_tag(void *context, const uint64_t sector_address, const bool negative, - // const uint8_t *data, const size_t length, const int32_t tag) - [LibraryImport("libaaruformat", EntryPoint = "aaruf_write_sector_tag", SetLastError = true)] - [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] - private static partial Status aaruf_write_sector_tag(IntPtr context, ulong sectorAddress, - [MarshalAs(UnmanagedType.I4)] bool negative, [In] byte[] data, - nuint length, SectorTagType tag); - - // AARU_EXPORT void AARU_CALL *aaruf_create(const char *filepath, const uint32_t media_type, const uint32_t sector_size, - // const uint64_t user_sectors, const uint64_t negative_sectors, - // const uint64_t overflow_sectors, const char *options, - // const uint8_t *application_name, const uint8_t application_name_length, - // const uint8_t application_major_version, - // const uint8_t application_minor_version, const bool is_tape) - [LibraryImport("libaaruformat", - EntryPoint = "aaruf_create", - SetLastError = true, - StringMarshalling = StringMarshalling.Utf8)] - [UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])] - private static partial IntPtr aaruf_create(string filepath, MediaType mediaType, uint sectorSize, ulong userSectors, - ulong negativeSectors, ulong overflowSectors, string options, - string applicationName, byte applicationNameLength, - byte applicationMajorVersion, byte applicationMinorVersion, - [MarshalAs(UnmanagedType.I4)] bool isTape); } \ No newline at end of file