0

I have a handful of different type of C-structs that are all compressed into a binary file.

struct-id serialized-struct struct-id serialized-struct ...

If it were the same struct over and over, it would make sense to use the struct package, but I want to switch between previously defined structs all the time.

STRUCT1_ID = '\xAA'
STRUCT2_ID = '\xBB'
STRUCT_IDS = frozenset([STRUCT1_ID, STRUCT2_ID])

struct1s = []
struct2s = []

def create_test_file(filepath):
    with open(filepath, 'wb') as f:
        # Write an example struct1 id followed by struct
        f.write(STRUCT1_ID)
        f.write(b'\x01\x02\x03\x04\x05\x06')
        # Write an example struct2 id followed by struct
        f.write(STRUCT2_ID)
        f.write(b'\x07\x08\x09\x0A')

def parse_test_file(filepath):
    with open(filepath, 'rb') as f:
        msg_type = f.read(1)
        while msg_type:
            print(byte)
            if byte in STRUCT_IDS:
                # Parse the next however many bytes needed by struct
                # logic breaks down here
                struct1s.append(turnIntoStruct(f.read(?)))
                msg_type = f.read(1)
            else:
              print('Corrupted file.  Unrecognized id')

In C, the structs would be:

typedef struct struct1_s {
  uint16_t a;
  uint16_t b;
  uint16_t c;
} struct1_t;

typedef struct struct2_s {
  uint16_t d;
  uint16_t e;
} struct2_t;

// Declare and initialize the structs
struct1_t s1 = {
  .a = 0x0201,
  .b = 0x0403,
  .c = 0x0605
};

struct2_t s2 = {
  .d = 0x0807,
  .e = 0x0A09
};

I'm less python than I am C right now. I seem unable to bring construct to python 3.4.3?

3
  • Can we see both structures declared in C? Commented Oct 4, 2015 at 3:23
  • How do you calculate the size of the struct? C structures are allowed to have padding bytes in them. Also when you're reading byte by byte, be mindful of endianness. Commented Oct 4, 2015 at 3:36
  • Fine, you have the size of each struct, so why you can't proceed? Commented Oct 4, 2015 at 3:39

1 Answer 1

1

Map the ID to the struct pattern, and use the appropriate one.

structmap = {
  b'\xaa': ('3H', struct1s),
  b'\xbb': ('2H', struct2s)
}

 ...

structmap[msg_type][1].append(struct.unpack(structmap[msg_type][0],
  f.read(struct.calcsize(structmap[msg_type][0]))))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.