Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

code that uses the struct module for reading bytes in file headers is not converted #8

Open
AraHaan opened this issue Dec 29, 2017 · 7 comments

Comments

@AraHaan
Copy link

AraHaan commented Dec 29, 2017

It seems like python code that uses the struct module is not converted to compileable standalone C#. (it would probably get syntax errors).

Code like this for example:

    offset = 0
    # version = struct.unpack_from(b'<26s26x', file_data, offset)[0]
    offset += 52
    entry_count = struct.unpack_from(b'<I4x', file_data, offset)[0]
    print(entry_count)
    offset += 12
    # file_timer = struct.unpack_from(b'<I', file_data, offset)[0]
    offset += 4
    xml_size_file = struct.unpack_from(b'<I', file_data, offset)[0]
    print(xml_size_file)
    offset += 4
    theunpack_offset = offset + xml_size_file

Is not converted properly, it still looks almost exactly alike in the output C# code.

Also, if I try to manually convert it to look like this:

        private enum KOM_DATA {
            KOM_HEADER_SIZE = 27,
            KOM_ENTRY_COUNT_SIZE = 8,
            KOM_FILE_TIMER_SIZE = 4,
            KOM_XML_SIZE_FILE_SIZE = 4
        };

            System.IO.FileStream reader = new System.IO.FileStream(System.Windows.Forms.Application.StartupPath + "\\koms\\" + komfile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            byte[] headerbuffer = new byte[System.Convert.ToInt32(KOM_DATA.KOM_HEADER_SIZE)];
            byte[] entry_count_buffer = new byte[System.Convert.ToInt32(KOM_DATA.KOM_ENTRY_COUNT_SIZE)];
            byte[] file_timer_buffer = new byte[System.Convert.ToInt32(KOM_DATA.KOM_FILE_TIMER_SIZE)];
            byte[] xml_size_file_buffer = new byte[System.Convert.ToInt32(KOM_DATA.KOM_XML_SIZE_FILE_SIZE)];
            int offset = 0;
            reader.Read(headerbuffer, offset, System.Convert.ToInt32(KOM_DATA.KOM_HEADER_SIZE));
            string headerstring = System.Text.Encoding.UTF8.GetString(headerbuffer);
            offset += 52;
            reader.Read(entry_count_buffer, offset, System.Convert.ToInt32(KOM_DATA.KOM_ENTRY_COUNT_SIZE));
            offset += 12;
            reader.Read(file_timer_buffer, offset, System.Convert.ToInt32(KOM_DATA.KOM_FILE_TIMER_SIZE));
            offset += 4;
            reader.Read(xml_size_file_buffer, offset, System.Convert.ToInt32(KOM_DATA.KOM_XML_SIZE_FILE_SIZE));
            MessageManager.ShowInfo(System.Convert.ToInt32(entry_count_buffer).ToString(), "Debug!");
            MessageManager.ShowInfo(System.Convert.ToInt32(file_timer_buffer).ToString(), "Debug!");
            MessageManager.ShowInfo(System.Convert.ToInt32(xml_size_file_buffer).ToString(), "Debug!");

The program would crash at the second read into the file to get the data it needs to extract.

@uxmal
Copy link
Owner

uxmal commented Dec 30, 2017

Correct. Pytocs needs to be made aware of the struct module and provide some form of runtime support to make it work. I will attend to this after the new year.

@AraHaan
Copy link
Author

AraHaan commented Dec 30, 2017

now that I think of it it could be extended to know about all parts of the python standard library that has an implementation already in the .NET framework.

@uxmal
Copy link
Owner

uxmal commented Dec 30, 2017

Indeed. It just a question of time to write mappings from python APIs to equivalents in the .NET framework

@uxmal
Copy link
Owner

uxmal commented Jan 2, 2018

By the way, @AraHaan, is your expectation that when translating

tuple_of_integers = struct.unpack("<ii", buffer)

the result should be:

var tuple_of_integers = @struct.unpack<Tuple<int,int>>("<ii", buffer);

or are you expecting that, since the unpacking format string is constant, it should be broken down into something like the following code?

int _tmp0 = 0;
var _tmp1 = PyToCs.Runtime.ReadLeInt32(buffer, ref _tmp0);
var _tmp2 = PyToCs.Runtime.ReadLeInt32(buffer, ref _tmp0);
var tuple_of_integers = Tuple.Create(_tmp1, _tmp2);

My gut tells me the first choice is better as it follows the original Python source more closely. In particular avoiding the introduction of all those variables helps the readability of the code.

@AraHaan
Copy link
Author

AraHaan commented Jan 2, 2018

Now that I realized it, the struct module is not really needed, just take the size of the struct module input string and put it into the 1st param in BinaryReader.ReadBytes. That was why I was crashing.

Also it needs BitConverter as well on my code, that was another reason why my manual translation crashed as well.

However now my manual translation only gets the first elelment in the XML data and makes only that entry when it should get multiple ones, my guess is an typo somewhere.

@uxmal
Copy link
Owner

uxmal commented Jan 3, 2018

Sadly, the BitConverter is little-endian only, so work still has to be done to provide a service like this if you wanted to read big-endian words from a buffer. I shall continue with my first suggestion above; this should make things work right out of the box.

@AraHaan
Copy link
Author

AraHaan commented Jan 3, 2018

ah, I see.

Also the zlib stuff from python could be converted to zlib.net usage (however it is sadly unmaintined to provide implementation of the very latest zlib into it though).

uxmal added a commit that referenced this issue Feb 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants