Agony
Agony

Reputation: 844

C# reading binary data with fixed length ANSI string and serializing it to xml in readable format

I am reading data from a binary files with the purpose of converting it to xml. For this i have class with all the marshaling defined to read it.

The text values are as 32byte fixed length strings - in ANSI korean codepage.

I use XmlSerializer Serialize() to save it as xml.

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public byte[] pName;

However XmlSerializer only supports base64/hex with byte[].

I cannot use

UnmanagedType.ByValTStr

Because it does not allow specifying codepage and i get incorrect, corrupt strings like:

µðÆúÆ®º§¶óÅä³²ÀÚÀå°©1

How can i get the data to read as EUC-KR string or provide a custom serialization for these specific 32 byte arrays to convert it to readable format myself?

In total i am dealing with ~20 files, each with different structure - but usig same 32 byte strings for text.

So manual conversions and looping through nested data with various class structures is not a viable option.

UPDATE: example struct:

   [StructLayout(LayoutKind.Sequential)]
    public struct ClientData
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint index;
        [MarshalAs(UnmanagedType.U4)]
        public uint serial;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string pName;
        public string StrName { get { return System.Text.Encoding.GetEncoding("EUC-KR").GetString(pName, 0, 32); } }

    }

Upvotes: 0

Views: 612

Answers (1)

xanatos
xanatos

Reputation: 111890

Based on the comment I wrote, use something like:

public class MyClass
{
    private static readonly Encoding koreanEncoding = Encoding.GetEncoding("EUC-KR");

    [XmlIgnore]
    public byte[] pName;

    public string pNameString
    {
        get => koreanEncoding.GetString(pName).TrimEnd('\0');
        set
        {
            var temp = koreanEncoding.GetBytes(value);
            Array.Resize(ref temp, 32);
            pName = temp;
        }
    }
}

So create a proxy pNameString that transform pName and use [XmlIgnore] to remove it from the xml. XmlSerializer probably requires both a get and a set in a property to be serialized.

Upvotes: 1

Related Questions