views:

143

answers:

1

Hi,

I have a byte array of around 10,000 bytes which is basically a blob from delphi that contains char, string, double and arrays of various types. This need to be read in and updated via C#.

I've created a very basic reader that gets the byte array from the db and converts the bytes to the relevant object type when accessing the property which works fine. My problem is when I try to write to a specific char[] item, it doesn't seem to update the byte array. I've created the following extensions for reading and writing:

public static class CharExtension
{
    public static byte ToByte( this char c )
    {
        return Convert.ToByte( c );
    }

    public static byte ToByte( this char c, int position, byte[] blob )
    {
        byte b = c.ToByte();
        blob[position] = b;
        return b;
    }
}

public static class CharArrayExtension
{
    public static byte[] ToByteArray( this char[] c )
    {
        byte[] b = new byte[c.Length];

        for ( int i = 1; i < c.Length; i++ )
        {
            b[i] = c[i].ToByte();
        }

        return b;
    }

    public static byte[] ToByteArray( this char[] c, int positon, int length, byte[] blob )
    {
        byte[] b = c.ToByteArray();

        Array.Copy( b, 0, blob, positon, length );

        return b;
    }
}

public static class ByteExtension
{
    public static char ToChar( this byte[] b, int position )
    {
        return Convert.ToChar( b[position] );
    }
}

public static class ByteArrayExtension
{
    public static char[] ToCharArray( this byte[] b, int position, int length )
    {
        char[] c = new char[length];

        for ( int i = 0; i < length; i++ )
        {
            c[i] = b.ToChar( position );
            position += 1;
        }

        return c;
    }
}

to read and write chars and char arrays my code looks like:

Byte[] _Blob; // set from a db field

public char ubin
{
    get { return _tariffBlob.ToChar( 14 ); }
    set { value.ToByte( 14, _Blob ); }
}

public char[] usercaplas
{
    get { return _tariffBlob.ToCharArray( 2035, 10 ); }
    set { value.ToByteArray( 2035, 10, _Blob ); }
}

So to write to the objects I can do:

ubin = 'C'; // this will update the byte[]
usercaplas = new char[10] { 'A', 'B', etc. }; // this will update the byte[]

usercaplas[3] = 'C'; // this does not update the byte[]

I know the reason is that the setter property is not being called but I want to know is there a way around this using code similar to what I already have?

I know a possible solution is to use a private variable called _usercaplas that I set and update as needed however as the byte array is nearly 10,000 bytes in length the class is already long and I would like a simpler approach as to reduce the overall code length and complexity.

Thank

Solution

Here's my solution should anyone want it. If you have a better way of doing then let me know please.

First I created a new class for the array:

public class CharArrayList : ArrayList
{
    char[] arr;
    private byte[] blob;
    private int length = 0;
    private int position = 0;

    public CharArrayList( byte[] blob, int position, int length )
    {
        this.blob = blob;
        this.length = length;
        this.position = position;

        PopulateInternalArray();
        SetArray();
    }

    private void PopulateInternalArray()
    {
        arr = blob.ToCharArray( position, length );
    }

    private void SetArray()
    {
        foreach ( char c in arr )
        {
            this.Add( c );
        }
    }

    private void UpdateInternalArray()
    {
        this.Clear();

        SetArray();
    }

    public char this[int i]
    {
        get
        {
            return arr[i];
        }
        set
        {
            arr[i] = value;
            UpdateInternalArray();
        }
    }
}

Then I created a couple of extension methods to help with converting to a byte[]

    public static byte[] ToByteArray( this CharArrayList c )
    {
        byte[] b = new byte[c.Count];

        for ( int i = 0; i < c.Count; i++ )
        {
            b[i] = Convert.ToChar( c[i] ).ToByte();
        }

        return b;
    }

    public static byte[] ToByteArray( this CharArrayList c, byte[] blob, int position, int length )
    {
        byte[] b = c.ToByteArray();

        Array.Copy( b, 0, blob, position, length );

        return b;
    }

So to read and write to the object:

    private CharArrayList _usercaplass;
    public CharArrayList usercaplas
    {
        get 
        {
            if ( _usercaplass == null )
                _usercaplass = new CharArrayList( _tariffBlob, 2035, 100 );

            return _usercaplass;
        }
        set 
        {
            _usercaplass = value;
            _usercaplass.ToByteArray( _tariffBlob, 2035, 100 );
        }
    }

As mentioned before its not an ideal solutions as I have to have private variables and extra code in the setter but I couldnt see a way around it.

A: 

try indexer:

Andrey
I don't think you can create a special indexer on an ordinary char-Array. He would need to write his own class.
TToni
he can create indexer for his class and move logic there
Andrey