Question

I am a c# beginner and trying to read a symbol inside a binary file. I read this Binary File at sole argument using ReadByte() in c#.By doing so

using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0])))

And after that i do

 while (stream.BaseStream.Position < stream.BaseStream.Length) 
 {
   int symbol = stream.ReadByte(); 
   //And then i do my stuff
 }   

What until here every thing is fine.

But my next step is to make symbol of generic type "<T>". So my algorithm to do so is :

namespace Final 
{
    public Class A <T> where T: IComparable <T> 
    {
        public Class Node
        {
            public T symbol; //This symbol has to be generic type because symbol may be int/long/uint etc. on 32/64 bit archtecture.
            public Node next;
            public int freq;
        }
        public Node Front;

        public A(string[] args) //it's a constructor
        {
            Front = null;
            using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) 
            {                    
                while (stream.BaseStream.Position < stream.BaseStream.Length) 
                {  
                    Func < byte, T > converter = b = > new T(b);
                    byte byteValue = stream.ReadByte();
                    T processingValue = converter(byteValue); //here is the problem
                    Node pt, temp;
                    pt = Front;
                    while (pt != null)
                    {
                        if (pt.symbol == processingValue) //here is the problem
                        {
                            pt.freq++;
                            break;
                        }
                        temp = pt;
                        pt = pt.next;
                    }
                }
            }
            stream.Close();
        }
    }
    public class MyClass
    {
        public static void Main(string[] args)
        {
            A <T> ObjSym = new A <T> (args); //object creation        
        }
    }
}

Please pay attention there are three class Class A,Class Node (containing symbol) and Class MyClass (containing main() function where i create object) and inside class A i have my constructor.

Now what i am trying to achieve since yesterday is, I am trying to make "symbol" as generic data type, i mean the symbol may be int/uint/long etc. on 32/64 bit architecture.Also please note that i am reading the symbols from Binary File at sole argument and the symbol in binary are of the form (11010101 etc.).

I would really appreciate if some one could please correct my algorithm by editing it in achieving my target of making symbol as "generic"() type on which i am stuck since yesterday. Thank you so much.

EDIT: Full code:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;


namespace shekhar_final_version_Csharp
 {
  //  public class Huffman<K> where K :  IComparable<K>
    public class Huffman < T > where T: struct, IComparable < T > , IEquatable < T > 
    {
        public int data_size, length, i, is_there;
         public class Node
        {
            public Node next, left, right;
            public T symbol;
            public int freq;
            public int is_processed;
        }
        public Node front, rear;
        ///////////////////////////////////////////////
      //  public Huffman(string[] args) 
        public Huffman(string[] args, Func < byte[], int, T > converter) 
        {
            front = null;
            rear = null;
            int size = Marshal.SizeOf(typeof (T));
            // Console.WriteLine("Size: {0}  ", size);
            using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) 
            {
                while (stream.BaseStream.Position < stream.BaseStream.Length) 
                {
                   byte[] bytes = stream.ReadBytes(size);   
                    T processingValue = converter(bytes, 0); 
                    {
                        Node pt, temp;
                        bool is_there = false;
                        pt = front;
                        while (pt != null) 
                        { 
                             if (pt.symbol.Equals(processingValue))
                            {
                                pt.freq++;
                                is_there = true;

                                break;
                            }
                            temp = pt;
                            pt = pt.next;
                        }
                        if (is_there == false) 
                        {  
                            temp = new Node();
                            temp.symbol = processingValue;
                            temp.freq = 1;
                            temp.left = null;
                            temp.right = null;
                            temp.next = null;
                            temp.is_processed = 0;
                            if (front == null) 
                            {
                                front = temp;
                            } 
                            else 
                            {
                            //    Console.WriteLine("Symbol : {0}  frequency is : {1}", pt.symbol, pt.freq);
                                temp.next = front;
                                front = temp;
                            }
                        }
                    }
                    Console.WriteLine("check1");
                }
                Console.WriteLine("check2");                
                stream.Close();

                //////////////////////////////
            }
        }
        public void Print_tree( Node treee) 
        {
            Node pt = treee;
            while (pt != null) 
            {
                Console.WriteLine("Symbol : {0}  frequency is : {1}", pt.symbol, pt.freq);
                pt = pt.next;
            }
        }

        /////////////////////////////
        public Node find_two_smallest(ref  Node pmin1, ref  Node pmin2) 
        {
            Node temp = front;
            Node temp6 = front;
            Node address = null;
            Node min1;
            min1 = new Node();
            min1.freq = int.MaxValue;
            Node min2;
            min2 = new Node();
            min2.freq = int.MaxValue;
            while (temp != null)
            {
                if (temp.is_processed == 0) 
                {
                    if (temp.freq < min2.freq) 
                    {
                        min1 = min2;
                        min2 = temp;
                    } 
                    else if (temp.freq < min1.freq && temp.freq != min2.freq) 
                    {
                        min1 = temp;
                    }
                    temp = temp.next;
                } 
                else if (temp.is_processed == 1) 
                {
                    temp = temp.next;
                }
            }
            pmin1 = min1;
            pmin2 = min2;
            //  Below is the code to find the address of first minimum arriving on traversal of List which will be "front" for next execution.
            while (temp6 != null) 
            {
                if (temp6.freq == min1.freq || temp6.freq == min2.freq) 
                {
                    address = temp6;
                    break;
                }
                temp6 = temp6.next;

            }
            return address;
        }
        ///////////////////////////////////////////////////////////////////
        public int count_remaining() 
        {
            int remaining = 0;
            Node pt = front;
            while (pt != null) 
            {
                if (pt.is_processed == 0) 
                {
                    remaining += 1;
                }
                pt = pt.next;
            }
            return remaining;
        }
        ////////////////////////////////////////////////////////////////////////////
        public void huffman_node_processing() 
        {
            Node temp, temp2;
            temp2 = front;
            while (temp2 != null) 
            {
                if (temp2.next == null) 
                {
                    rear = temp2;
                    break;
                }
                temp2 = temp2.next;
            }
            int remaining;
            int counter = 0;
            remaining = count_remaining();

// You can un-comment these console.writeline(..); which are commented below if you want to see how the addition of nodes taking place(which nodes are added), 
//I have commented it inorder to give direct and clear output.
            while (front != rear) 
            {
                if (counter == 0) 
                {
                    temp = new Node();
                    Console.WriteLine("first element1 {0} ", front.freq);
                    Console.WriteLine("second element1 {0} ", front.next.freq);
                    temp.freq = front.freq + front.next.freq;
                    front.is_processed = 1;
                    front.next.is_processed = 1;
                    temp.is_processed = 0;
                    temp.left = front;
                    temp.right = front.next;
                    temp.next = null;
                    rear.next = temp;
                    front = front.next.next;
                    Console.WriteLine("tempcheck1 {0} ", temp.freq);
                    rear = rear.next;
                    remaining = count_remaining();
                    if (remaining == 1) 
                    {
                        break;
                    }
                }
                if (rear.freq == front.freq) 
                {
                    //Console.WriteLine("first element2 {0} ", front.freq);
                    //Console.WriteLine("second element2{0} ", front.next.freq);
                    temp = new Node();
                    temp.freq = front.freq + rear.freq;
                    rear.is_processed = 1;
                    front.is_processed = 1;
                    temp.is_processed = 0;
                    temp.left = front;
                    temp.right = rear;
                    temp.next = null;
                    rear.next = temp;
                    front = front.next;
                    //Console.WriteLine("temp check2 {0} ", front.freq);
                    rear = rear.next;
                    remaining = count_remaining();
                    if (remaining == 1) 
                    {
                        break;
                    }
                }

                if (rear.freq > front.freq) 
                {
                    Node pmin1 = null;
                    Node pmin2 = null;
                    Node address = find_two_smallest(ref pmin1, ref pmin2);
                    temp = new Node();
                    Console.WriteLine("pmin1check3 {0} ", pmin1.freq);
                    Console.WriteLine("pmin2check3 {0} ", pmin2.freq);
                    temp.freq = pmin1.freq + pmin2.freq;
                    pmin1.is_processed = 1;
                    pmin2.is_processed = 1;
                    temp.is_processed = 0;
                    temp.left = pmin2;
                    temp.right = pmin1;
                    temp.next = null;
                    rear.next = temp;
                    front = address;
                    Console.WriteLine("tempcheck3 {0} ", temp.freq);
                    rear = rear.next;
                    remaining = count_remaining();
                    if (remaining == 1) 
                    {
                        break;
                    }
                }

                if (rear.freq < front.freq) 
                {
                    Node pmin1 = null;
                    Node pmin2 = null;
                    Node address = find_two_smallest(ref pmin1, ref pmin2);
                    temp = new Node();
                    //Console.WriteLine("pmin1check4 {0} ", pmin1.freq);
                    //Console.WriteLine("pmin2check4 {0} ", pmin2.freq);
                    temp.freq = pmin1.freq + pmin2.freq;
                    pmin1.is_processed = 1;
                    pmin2.is_processed = 1;
                    temp.is_processed = 0;
                    temp.left = pmin2;
                    temp.right = pmin1;
                    temp.next = null;
                    rear.next = temp;
                    front = address;
                    //Console.WriteLine("tempcheck4 {0} ", temp.freq);
                    rear = rear.next;
                    remaining = count_remaining();
                    if (remaining == 1) 
                    {
                        break;
                    }
                }
                counter++;
            }

        }
        ////////////////////////////////////////////
        public void GenerateCode( Node parentNode, string code) 
        {
            if (parentNode != null) 
            {
                GenerateCode(parentNode.left, code + "0");
                if (parentNode.left == null && parentNode.right == null)
                    Console.WriteLine("Symbol : " + parentNode.symbol + "  frequency is :  " + code);
                GenerateCode(parentNode.right, code + "1");
            }
        }

    }
    public class MyClass 
    {
        public static void Main(string[] args) 
        {
           // Huffman<K>  ObjSym = new Huffman<K>(args); //object creation
            Huffman < long > ObjSym = new Huffman < long > (args, BitConverter.ToInt64);
            Console.WriteLine("\nReading the Binary file......");
            ObjSym.Print_tree(ObjSym.front);
            ObjSym.huffman_node_processing();
            Console.WriteLine("\nThe encoding of symbols are :");
            ObjSym.GenerateCode(ObjSym.rear, "");

        }
    }
}

And the error is : (For debugging i tried to print check1 and check2 in constructor but it just prints "check1" not "check2").Please until the end of output:

hp@ubuntu:~/Desktop/Internship_Xav/templatescplus$ mono test.exe toto.bin 
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1

Unhandled Exception: System.ArgumentException: Destination array is not long enough to copy all the items in the collection. Check array index and length.
  at System.BitConverter.PutBytes (System.Byte* dst, System.Byte[] src, Int32 start_index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.BitConverter.ToInt64 (System.Byte[] value, Int32 startIndex) [0x00000] in <filename unknown>:0 
  at shekhar_final_version_Csharp.Huffman`1[System.Int64]..ctor (System.String[] args, System.Func`3 converter) [0x00000] in <filename unknown>:0 
  at shekhar_final_version_Csharp.MyClass.Main (System.String[] args) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: Destination array is not long enough to copy all the items in the collection. Check array index and length.
  at System.BitConverter.PutBytes (System.Byte* dst, System.Byte[] src, Int32 start_index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.BitConverter.ToInt64 (System.Byte[] value, Int32 startIndex) [0x00000] in <filename unknown>:0 
  at shekhar_final_version_Csharp.Huffman`1[System.Int64]..ctor (System.String[] args, System.Func`3 converter) [0x00000] in <filename unknown>:0 
  at shekhar_final_version_Csharp.MyClass.Main (System.String[] args) [0x00000] in <filename unknown>:0 
hp@ubuntu:~/Desktop/Internship_Xav/templatescplus$
Was it helpful?

Solution

You will have to pass the conversion function and the size of the numeric type into the constructor of A:

public A(string[] args, int size, Func<byte[], int, T> converter) { ... }
 A<long> ObjSym = new A<long>(args, sizeof(long), BitConverter.ToInt64)

instead of passing the size directly, you could use Marshal.SizeOf:

int size = Marshal.SizeOf(typeof(T));

Then you can read the required number of bytes from the reader and do the conversion:

byte[] bytes = stream.ReadBytes(size);
T processingValue = converter(bytes, 0);

You can check for the symbol using Equals:

if (pt.symbol.Equals(processingValue))

You can avoid boxing during the equality check if you further constrain the type parameter to implement IEquatable<T>:

public class A<T> where T : struct, IComparable <T>, IEquatable<T>
{
    public class Node
    {
        public T symbol;
        public Node next;
        public int freq;
    }

    public Node Front;

    public A(string[] args, Func<byte[], int, T> converter)
    {
        int size = Marshal.SizeOf(typeof(T));
        Front = null;
        using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) 
        {                    
            while (stream.BaseStream.Position < stream.BaseStream.Length) 
            {
                byte[] bytes = stream.ReadBytes(size);
                T processingValue = converter(bytes, 0);

                Node pt, temp;
                pt = Front;
                while (pt != null)
                {
                    if (pt.symbol.Equals(processingValue))
                    {
                        pt.freq++;
                        break;
                    }
                    temp = pt;
                    pt = pt.next;
                }
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top