def test_array_of_conditionals(): test_struct = [ ("cond", b.uint8), ("foos", b.array(3, (b.CONDITIONAL, "cond", { 1: [("foo", b.nibble), b.padding(4)], 2: [("bar", b.bit), b.padding(7)], 4: [("baz", b.semi_nibble), b.padding(6)] }))) ] test_data = bytearray([1, 0b10000101, 0b01010110, 0b11010101]) test_parsed = b.parse(test_data, test_struct) assert_equal(test_parsed.cond, 1) assert_equal(test_parsed.foos[0].foo, 0b1000) assert_equal(test_parsed.foos[1].foo, 0b0101) assert_equal(test_parsed.foos[2].foo, 0b1101) test_parsed.cond = 4 assert_equal(test_parsed.cond, 4) assert_equal(test_parsed.foos[0].baz, 0b10) assert_equal(test_parsed.foos[1].baz, 0b01) assert_equal(test_parsed.foos[2].baz, 0b11)
def test_minimal_pylsdj_song(): pulse_instrument = [ ("envelope", b.byte), ] instrument = [ ("instrument_type", b.enum(8, { 0: 'pulse' })), (b.CONDITIONAL, "instrument_type", { "pulse": pulse_instrument }) ] song = [ ("instruments", b.array(1, instrument)) ] DEFAULT_INSTRUMENT = bytearray([0, 0xa8]) data_bytes = DEFAULT_INSTRUMENT parsed_song = b.parse(data_bytes, song) assert_equal(parsed_song.instruments[0].envelope, 0xa8)
def test_field_properties_in_array(): array_endian_test = [ ("little_arr", b.array(3, b.uint16), {"endianness": b.LITTLE_ENDIAN}), ("big_arr", b.array(3, b.uint16), {"endianness": b.BIG_ENDIAN}) ] data = bytearray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]) test = b.parse(data, array_endian_test) assert_equal(len(test.little_arr), 3) assert_equal(test.little_arr[0], 0x0201) assert_equal(test.little_arr[1], 0x0403) assert_equal(test.little_arr[2], 0x0605) assert_equal(len(test.big_arr), 3) assert_equal(test.big_arr[0], 0x0102) assert_equal(test.big_arr[1], 0x0304) assert_equal(test.big_arr[2], 0x0506)
def test_array_eq(): first_test_struct = [("nums", b.array(3, b.uint8))] first_test_data = bytearray([2, 4, 6]) second_test_struct = [("nums", b.array(4, b.uint8))] second_test_data = bytearray([2, 4, 6, 8]) first_test_parsed = b.parse(first_test_data, first_test_struct) second_test_parsed = b.parse(second_test_data, second_test_struct) assert first_test_parsed == first_test_parsed assert first_test_parsed != second_test_parsed first_test_parsed_copy = b.parse(first_test_data, first_test_struct) assert first_test_parsed.nums == first_test_parsed_copy.nums first_test_parsed_copy.nums[2] = 100 assert first_test_parsed != first_test_parsed_copy assert first_test_parsed.nums != first_test_parsed_copy.nums
def test_field_properties_in_array(): array_endian_test = [ ("little_arr", b.array(3, b.uint16), {"endianness": b.LITTLE_ENDIAN}), ("big_arr", b.array(3, b.uint16), {"endianness": b.BIG_ENDIAN}) ] data = bytearray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]) test = b.parse(data, array_endian_test) assert len(test.little_arr) == 3 assert test.little_arr[0] == 0x0201 assert test.little_arr[1] == 0x0403 assert test.little_arr[2] == 0x0605 assert len(test.big_arr) == 3 assert test.big_arr[0] == 0x0102 assert test.big_arr[1] == 0x0304 assert test.big_arr[2] == 0x0506
def test_array_eq(): first_test_struct = [("nums", b.array(3, b.uint8))] first_test_data = bytearray([2, 4, 6]) second_test_struct = [("nums", b.array(4, b.uint8))] second_test_data = bytearray([2, 4, 6, 8]) first_test_parsed = b.parse(first_test_data, first_test_struct) second_test_parsed = b.parse(second_test_data, second_test_struct) assert_equal(first_test_parsed, first_test_parsed) assert_not_equal(first_test_parsed, second_test_parsed) first_test_parsed_copy = b.parse(first_test_data, first_test_struct) assert_equal(first_test_parsed.nums, first_test_parsed_copy.nums) first_test_parsed_copy.nums[2] = 100 assert_not_equal(first_test_parsed, first_test_parsed_copy) assert_not_equal(first_test_parsed.nums, first_test_parsed_copy.nums)
def test_field_properties_in_array(): array_endian_test = [("little_arr", b.array(3, b.uint16), { "endianness": b.LITTLE_ENDIAN }), ("big_arr", b.array(3, b.uint16), { "endianness": b.BIG_ENDIAN })] data = bytearray([ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 ]) test = b.parse(data, array_endian_test) assert_equal(len(test.little_arr), 3) assert_equal(test.little_arr[0], 0x0201) assert_equal(test.little_arr[1], 0x0403) assert_equal(test.little_arr[2], 0x0605) assert_equal(len(test.big_arr), 3) assert_equal(test.big_arr[0], 0x0102) assert_equal(test.big_arr[1], 0x0304) assert_equal(test.big_arr[2], 0x0506)
def test_get_slice(): data = bytearray([0x61, 0x62, 0x63, 0x64, 0x65, 0x66]) slice_test_format = [('arr', b.array(6, b.string(1)))] slice_test = b.parse(data, slice_test_format) assert_equal([b'a', b'b', b'c', b'd', b'e', b'f'], list(slice_test.arr)) assert_equal([b'c', b'd', b'e', b'f'], slice_test.arr[2:]) assert_equal([b'a', b'b'], slice_test.arr[:2]) assert_equal([b'f', b'e', b'd', b'c', b'b', b'a'], slice_test.arr[::-1]) assert_equal([b'c', b'd', b'e'], slice_test.arr[2:5]) assert_equal([b'f', b'e', b'd'], slice_test.arr[5:2:-1]) assert_equal([b'f', b'e', b'd'], slice_test.arr[:2:-1])
def test_minimal_pylsdj_song(): pulse_instrument = [ ("envelope", b.byte), ] instrument = [("instrument_type", b.enum(8, {0: 'pulse'})), (b.CONDITIONAL, "instrument_type", { "pulse": pulse_instrument })] song = [("instruments", b.array(1, instrument))] DEFAULT_INSTRUMENT = bytearray([0, 0xa8]) data_bytes = DEFAULT_INSTRUMENT parsed_song = b.parse(data_bytes, song) assert_equal(parsed_song.instruments[0].envelope, 0xa8)
def test_array(): data = bytearray([0b11111111, 0b10010101, 0b00010001]) test_array_struct = [ {"endianness" : b.BIG_ENDIAN}, ("first", b.uint8), ("flags", b.array(8, b.boolean)), ("last", b.uint8)] array_test = b.parse(data, test_array_struct) assert array_test.__offsets__.first == 0 assert array_test.__offsets__.flags == 8 assert array_test.__offsets__.last == 16 assert len(array_test) == 24 assert (array_test.flags == [True, False, False, True, False, True, False, True]) assert b.write(array_test, test_array_struct) == data
import bread as b import bitstring # Shared structs for bread struct test test_struct = [{ "endianness": b.BIG_ENDIAN }, ("flag_one", b.boolean), ("flag_two", b.boolean), ("flag_three", b.boolean), ("flag_four", b.boolean), ("first", b.uint8), (b.padding(2), ), b.padding(2), ("blah", b.uint16), ("second", b.int64), ("third", b.uint64), ("fourth", b.int8)] test_array_struct = [{ "endianness": b.BIG_ENDIAN }, ("first", b.uint8), ("flags", b.array(8, b.boolean)), ("last", b.uint8)] nested_array_struct = [{ "endianness": b.BIG_ENDIAN }, ("first", b.uint8), ("matrix", b.array(3, b.array(3, b.uint8))), ("last", b.uint8)] simple_struct = [("length", b.uint8), ("ok", b.boolean)] offset_struct = [("length", b.uint8, {"offset": 1})] deeply_nested_struct = [{ "endianness": b.BIG_ENDIAN }, ("ubermatrix", b.array(3, nested_array_struct)), ("dummy", simple_struct)] conditional_test = [("qux", b.boolean),
("flag_four", b.boolean), ("first", b.uint8), (b.padding(2),), b.padding(2), ("blah", b.uint16), ("second", b.int64), ("third", b.uint64), ("fourth", b.int8) ] test_array_struct = [ { "endianness": b.BIG_ENDIAN }, ("first", b.uint8), ("flags", b.array(8, b.boolean)), ("last", b.uint8)] nested_array_struct = [ { "endianness": b.BIG_ENDIAN }, ("first", b.uint8), ("matrix", b.array(3, b.array(3, b.uint8))), ("last", b.uint8) ] simple_struct = [ ("length", b.uint8), ("ok", b.boolean) ]
import bread as b import sys enum_data_type = [ ("type", b.enum(8, { 0x50 : "raw", 0x51 : "enc" })) ] hex_data = [ ("data", b.array(5, b.byte), {"str_format": hex}) ] str_data = [ ("type", b.enum(8, { 0x50 : "raw", 0x51 : "enc" })), ("data", b.array(5, b.byte), {"str_format": hex}) ] data = bytearray([0x51, 0x01, 0x02, 0x03, 0x04, 0x05]) parsed_data = b.parse(data, str_data) print parsed_data simple_spec_hex = [('addr', b.uint8, {"str_format": hex})] parsed_data = b.parse(bytearray([42]), simple_spec_hex) print parsed_data
else: os.makedirs(d) def logF(path, x): if ARGS.log: ensuredir(os.path.dirname(path)) with open(path, 'w') as f: f.write(x) def hex_array(x): return str(map(hex, x)) nsf_head_spec = \ [ ('magic_number', b.array(5, b.byte), {"str_format": hex_array}) , ('version', b.byte) , ('total_songs', b.byte) , ('starting_song', b.byte) , ('load_addr', b.uint16, {"str_format": hex}) , ('init_addr', b.uint16, {"str_format": hex}) , ('play_addr', b.uint16, {"str_format": hex}) , ('title', b.string(32)) , ('artist', b.string(32)) , ('copyright', b.string(32)) , ('ntsc_speed', b.uint16) , ('bankswitch_init', b.array(8, b.byte), {"str_format": hex_array}) , ('pal_speed', b.uint16) , ('tv_std', b.boolean, {"str_format": lambda x: "PAL" if x else "NTSC"}) , ('ntsc_and_pal', b.boolean) , (b.padding(6))
import bread as b from .vendor.six.moves import range def padded_hex(pad_count): return lambda x: ("0x%%0%dx" % (pad_count)) % (x) EMPTY_BLOCK = 0xff # File management structure (starts at 0x8000) compressed_sav_file = [ # Up to 32 files (songs) can be saved to one cartridge ("filenames", b.array(32, b.string(8))), # Each file has a monotonically increasing version number ("file_versions", b.array(32, b.byte)), b.padding(30 * 8), ("sram_init_check", b.string(2)), # set to 'jk' on init # The file that is currently active ("active_file", b.byte), # Table mapping blocks to files. ("block_alloc_table", b.array(191, b.byte)) ] # Should be 0x4000 bytes long sample_kit = [ ("magic_number", b.string(2)), # should be 0x60, 0x40 # The address of the first byte after each sample, or 0 if the sample is # unused ("sample_end_addresses", b.array(15, b.string(2))), b.padding(2 * 8), # For samples with names less than three characters long, sample names are
import bread as b import sys def hex_array(x): return str(map(hex, x)) nsf_header = [('magic_number', b.array(5, b.byte), { "str_format": hex_array }), ('version', b.byte), ('total_songs', b.byte), ('starting_song', b.byte), ('load_addr', b.uint16, { "str_format": hex }), ('init_addr', b.uint16, { "str_format": hex }), ('play_addr', b.uint16, { "str_format": hex }), ('title', b.string(32)), ('artist', b.string(32)), ('copyright', b.string(32)), ('ntsc_speed', b.uint16), ('bankswitch_init', b.array(8, b.byte), { "str_format": hex_array }), ('pal_speed', b.uint16), ('ntsc', b.boolean), ('pal', b.boolean), ('ntsc_and_pal', b.boolean), (b.padding(6)), ('vrc6', b.boolean), ('vrc7', b.boolean), ('fds', b.boolean), ('mmc5', b.boolean), ('namco_106', b.boolean), ('fme07', b.boolean), (b.padding(2)), (b.padding(32))] with open(sys.argv[1], 'r') as fp: header = b.parse(fp, nsf_header) print header
'saw down', 2: 'saw up', 3: 'square', 4: 'sine', # Some sysex parsers (like the one in Dexed) seem to accept 6 and 7 as a # valid value for S&H, even though the spec's value is 5 (5, 6, 7): 'sample and hold' } } raw_operator = [ ('eg_rates', b.array(4, b.uint8)), ('eg_levels', b.array(4, b.uint8)), ('keyboard_level_scaling_break_point', b.uint8), # C3 = 0x27 ('keyboard_level_scaling_left_depth', b.uint8), ('keyboard_level_scaling_right_depth', b.uint8), ('keyboard_level_scaling_left_curve', b.enum(8, enums['curves'])), ('keyboard_level_scaling_right_curve', b.enum(8, enums['curves'])), ('keyboard_rate_scaling', b.uint8), ('amp_mod_sensitivity', b.uint8), ('key_velocity_sensitivity', b.uint8), ('output_level', b.uint8), ('osc_mode', b.enum(8, enums['osc_mode'])), ('osc_frequency_coarse', b.uint8), ('osc_frequency_fine', b.uint8), ('osc_detune', b.uint8, { 'offset': -7
import bread as b import sys def hex_array(x): return str(map(hex, x)) nsf_header = [ ('magic_number', b.array(5, b.byte), {"str_format": hex_array}), ('version', b.byte), ('total_songs', b.byte), ('starting_song', b.byte), ('load_addr', b.uint16, {"str_format": hex}), ('init_addr', b.uint16, {"str_format": hex}), ('play_addr', b.uint16, {"str_format": hex}), ('title', b.string(32)), ('artist', b.string(32)), ('copyright', b.string(32)), ('ntsc_speed', b.uint16), ('bankswitch_init', b.array(8, b.byte), {"str_format": hex_array}), ('pal_speed', b.uint16), ('ntsc', b.boolean), ('pal', b.boolean), ('ntsc_and_pal', b.boolean), (b.padding(6)), ('vrc6', b.boolean), ('vrc7', b.boolean), ('fds', b.boolean), ('mmc5', b.boolean), ('namco_106', b.boolean), ('fme07', b.boolean),
("flag_two", b.boolean), ("flag_three", b.boolean), ("flag_four", b.boolean), ("first", b.uint8), (b.padding(2),), b.padding(2), ("blah", b.uint16), ("second", b.int64), ("third", b.uint64), ("fourth", b.int8) ] nested_array_struct = [ {"endianness" : b.BIG_ENDIAN}, ("first", b.uint8), ("matrix", b.array(3, b.array(3, b.uint8))), ("last", b.uint8) ] simple_struct = [ ("length", b.uint8), ("ok", b.boolean) ] offset_struct = [ ("length", b.uint8, {"offset": 1}) ] deeply_nested_struct = [ {"endianness" : b.BIG_ENDIAN}, ("ubermatrix", b.array(3, nested_array_struct)),
import bread as b from .vendor.six.moves import range def padded_hex(pad_count): return lambda x: ("0x%%0%dx" % (pad_count)) % (x) EMPTY_BLOCK = 0xff # File management structure (starts at 0x8000) compressed_sav_file = [ # Up to 32 files (songs) can be saved to one cartridge ("filenames", b.array(32, b.string(8))), # Each file has a monotonically increasing version number ("file_versions", b.array(32, b.byte)), b.padding(30 * 8), ("sram_init_check", b.string(2)), # set to 'jk' on init # The file that is currently active ("active_file", b.byte), # Table mapping blocks to files. ("block_alloc_table", b.array(191, b.byte)) ] # Should be 0x4000 bytes long sample_kit = [ ("magic_number", b.string(2)), # should be 0x60, 0x40 # The address of the first byte after each sample, or 0 if the sample is # unused ("sample_end_addresses", b.array(15, b.string(2))),