| 1 | --[[ |
|---|
| 2 | module for converting between numbers and binary strings |
|---|
| 3 | usage: |
|---|
| 4 | bs=require('binstr') |
|---|
| 5 | wbdata=bs.unpack(get_prop_str(0x10d,0x1c)) -- return propset 3 white balance as 7 ints |
|---|
| 6 | ]] |
|---|
| 7 | |
|---|
| 8 | local binstr = {} |
|---|
| 9 | --[[ |
|---|
| 10 | convert number or array of numbers into a binary string |
|---|
| 11 | size specifies the number of bytes to use from each number, default 4 |
|---|
| 12 | ]] |
|---|
| 13 | binstr.pack = function(val,size) |
|---|
| 14 | if size == nil then |
|---|
| 15 | size = 4 |
|---|
| 16 | elseif size < 1 or size > 4 then |
|---|
| 17 | error('invalid size') |
|---|
| 18 | end |
|---|
| 19 | if type(val) ~= 'table' then |
|---|
| 20 | val = {tonumber(val)} |
|---|
| 21 | end |
|---|
| 22 | local bytes = {} |
|---|
| 23 | for i,num in ipairs(val) do |
|---|
| 24 | for j = 1, size do |
|---|
| 25 | table.insert(bytes,bitand(num,0xFF)) |
|---|
| 26 | num = bitshru(num,8) |
|---|
| 27 | end |
|---|
| 28 | end |
|---|
| 29 | return string.char(unpack(bytes)) |
|---|
| 30 | end |
|---|
| 31 | |
|---|
| 32 | --[[ |
|---|
| 33 | read a single number of the specified size from str |
|---|
| 34 | defaults to 4 bytes at start |
|---|
| 35 | does not handle negative pos |
|---|
| 36 | does not sign extend < 32 bit size |
|---|
| 37 | ]] |
|---|
| 38 | binstr.getnum = function(str,size,pos) |
|---|
| 39 | if pos == nil then |
|---|
| 40 | pos = 1 |
|---|
| 41 | elseif pos < 1 then |
|---|
| 42 | error('invalid pos') |
|---|
| 43 | end |
|---|
| 44 | if size == nil then |
|---|
| 45 | size = 4 |
|---|
| 46 | elseif size > 4 or size < 1 then |
|---|
| 47 | error('invalid size') |
|---|
| 48 | end |
|---|
| 49 | local e = pos + size - 1 |
|---|
| 50 | if string.len(str) < e then |
|---|
| 51 | return |
|---|
| 52 | end |
|---|
| 53 | local bytes = {string.byte(str,pos,e)} |
|---|
| 54 | local num = 0 |
|---|
| 55 | for i=1,#bytes do |
|---|
| 56 | num = bitor(num,bitshl(bytes[i],8*(i-1))) |
|---|
| 57 | end |
|---|
| 58 | return num |
|---|
| 59 | end |
|---|
| 60 | |
|---|
| 61 | --[[ |
|---|
| 62 | convert a string to an array of numbers |
|---|
| 63 | size specifies the size of the numbers in the packed array, default 4 |
|---|
| 64 | ]] |
|---|
| 65 | binstr.unpack = function(str,size) |
|---|
| 66 | if size == nil then |
|---|
| 67 | size = 4 |
|---|
| 68 | elseif size < 1 or size > 4 then |
|---|
| 69 | error('invalid size') |
|---|
| 70 | end |
|---|
| 71 | if type(str) ~= 'string' then |
|---|
| 72 | error('expected string') |
|---|
| 73 | end |
|---|
| 74 | if (string.len(str)/size)*size ~= string.len(str) then |
|---|
| 75 | error('string lenght not multiple of size') |
|---|
| 76 | end |
|---|
| 77 | local i = 1 |
|---|
| 78 | local r = {} |
|---|
| 79 | while i <= string.len(str) do |
|---|
| 80 | table.insert(r,binstr.getnum(str,size,i)) |
|---|
| 81 | i = i+size |
|---|
| 82 | end |
|---|
| 83 | return r |
|---|
| 84 | end |
|---|
| 85 | |
|---|
| 86 | return binstr |
|---|