I previously have blogged about the TkbmMWBinaryParser which use special defined definition files for parsing binary data. (Check this blog)
This is a short blog about a new feature, included in kbmMW Enterprise Edition which makes it simple to visualizing the definition file and the data to be parsed.
You will find the demos in kbmMW to have been updated, to include the binary parser visualizer, and showing how to step thru data, while visualizing what fails and what succeeds during the parse.
A picture is worth many words… so here goes. This is a screenshot of the included demo:
The visualizer is in the center. It shows optionally the data being parsed (in magenta) followed by the definition (everything else).
Specific bit definitions are shown in blue, tags and subtags are in green, and constant bitmasks/values are in black.
When parsing non matching data, it is showing failed parts as red. This way its easy to see what match and what doesn’t according to the given definition.
The definition for the above visualization is shown in the end of this blog for the curious.
kbmMW also includes a couple of readers which makes reading files and streams easy. For example TkbmMWBPFileReader.
The simple setup is:
// Keep rd alive while you visualize. rd:TkbmMWBPFileReader; .. // Tell file reader which definition file to use while parsing. rd:=TkbmMWBPFileReader.Create('toledo.yaml'); kbmMWBinaryVisualizer1.Parser:=rd.Parser; .. // Tell file reader which binary file to parse. rd.Step('somebinaryfile.bin'); // Step more on same file. rd.Step; ..
The Options property of the visualizer controls what you want to see:
TkbmMWBPVisalizerOption = (mwbpvoShowData,mwbpvoShowOnlyTouched,mwbpvoShowOnlyTouchedData);
- mwbpvoShowData – Hexdump of the data is visualized.
- mwbpvoShowOnlyTouched – Only show parts of the definition which was “touched”. As the parser is a short circuit parser, it will immediately give up parsing the moment something does not match the definition file. Everything matching until that point is “touched”.
- mwbpvoShowOnlyTouchedData – Only show data which was valid or “touched”.
The definition for the above visualization is typically stored in YAML format, but could just as well be stored in JSON, XML or one of the binary formats supported by kbmMW’s object notation framework. YAML just makes it a cleaner read for humans imo.
# Values: # TARE # GROSS # NET # INCREMENT_SIZE # STATUS = STATUS_OK, STATUS_DATA_ERROR, STATUS_SCALE_ERROR, STATUS_SCALE_OVERLOAD, # STATUS_IN_MOTION, STATUS_TARE_ERROR, STATUS_TRANSMISSION_ERROR, STATUS_INVALID_COMMAND, STATUS_INVALID_PARAMETER # IS_POWER_NOT_ZEROED # IS_SETTLED # IS_OVERLOAD # IS_NEGATIVE # UNIT_WEIGHT = UNIT_GRAM, UNIT_UK_POUND, UNIT_KILOGRAM, UNIT_METRIC_TON, UNIT_OUNCE, UNIT_TROY_OUNCE, UNIT_PENNY_WEIGHT, UNIT_UK_TON, UNIT_CUSTOM # UNIT_TARE (can take same values as UNIT_WEIGHT) # WEIGHT_FACTOR # WEIGHT_EXPANSION # TARE_FACTOR # TARE_CODE = TARE_PRESET, TARE_AUTO, TARE_NONE # TERMINAL_NO # VALUE = current value during parsing TOLEDO: VALUES: # Unit constants # Should update to correct virtual indicator values. C_UNIT_GRAM: 2000 C_UNIT_UK_POUND: 2001 C_UNIT_KILOGRAM: 2002 C_UNIT_METRIC_TON: 2003 C_UNIT_OUNCE: 2004 C_UNIT_TROY_OUNCE: 2005 C_UNIT_PENNY_WEIGHT: 2006 C_UNIT_UK_TON: 2007 C_UNIT_CUSTOM: 2008 # Status constants # Should update to correct virtual indicator values. C_STATUS_OK: 1000 C_STATUS_DATA_ERROR: 1001 C_STATUS_SCALE_ERROR: 1002 C_STATUS_SCALE_OVERLOAD: 1003 C_STATUS_IN_MOTION: 1004 C_STATUS_TARE_ERROR: 1005 C_STATUS_TRANSMISSION_ERROR: 1006 C_STATUS_INVALID_COMMAND: 1007 C_STATUS_INVALID_PARAMETER: 1008 # Tare constants # Should update to correct virtual indicator values. C_TARE_PRESET: 3000 C_TARE_AUTO: 3001 C_TARE_NONE: 3002 # Default values STATUS: @C_STATUS_OK TARE: 0 GROSS: 0 NET: 0 INCREMENT_SIZE: 1 IS_POWER_NOT_ZEROED: false IS_SETTLED: false IS_OVERLOAD: false IS_NEGATIVE: false IS_CHECKSUM_OK: false WEIGHT_FACTOR: 1 TARE_FACTOR: 1 TARE_CODE: @C_TARE_NONE TERMINAL_NO: 0 WEIGHT_UNIT: @C_UNIT_KILOGRAM TARE_UNIT: @C_UNIT_KILOGRAM TELEGRAMS: bytes: - mask: [ 0x2, @SWA, @SWB, @SWC, 6*@W, 6*@T, 0xD, @CHK ] expr: - "WEIGHT_UNIT=IF(IS_UNIT_UK_POUND=1,C_UNIT_POUND,IF(IS_UNIT_KILOGRAM,C_UNIT_KILOGRAM,WEIGHT_UNIT))" - "TARE_UNIT=WEIGHT_UNIT" - "STATUS=IF(IS_CHECKSUM_OK=1,IF(IS_OVERLOAD,C_STATUS_OVERLOAD,C_STATUS_OK),C_STATUS_DATA_ERROR)" - "WEIGHT=WEIGHT*WEIGHT_EXPANSION*IF(WEIGHT_FACTOR<1,WEIGHT_FACTOR,1)" - "TARE=TARE*TARE_EXPANSION*IF(TARE_FACTOR<1,TARE_FACTOR,1)" - "GROSS=IF(IS_NETTO=0,WEIGHT,0)" - "NET=IF(IS_NETTO=1,WEIGHT,0)" TAGS: SWA: bits: # bit offset 0 mask: [ 0, 0, 1, 2*@IS, 3*@DP ] DP: bits: # bit offset 0, 3 bits - mask: [ 0, 0, 0 ] expr: [ WEIGHT_FACTOR=100, TARE_FACTOR=100 ] - mask: [ 0, 0, 1 ] expr: [ WEIGHT_FACTOR=10, TARE_FACTOR=10 ] - mask: [ 0, 1, 0 ] expr: [ WEIGHT_FACTOR=1, TARE_FACTOR=1 ] - mask: [ 0, 1, 1 ] expr: [ WEIGHT_FACTOR=0.1, TARE_FACTOR=0.1 ] - mask: [ 1, 0, 0 ] expr: [ WEIGHT_FACTOR=0.01, TARE_FACTOR=0.01 ] - mask: [ 1, 0, 1 ] expr: [ WEIGHT_FACTOR=0.001, TARE_FACTOR=0.001 ] - mask: [ 1, 1, 0 ] expr: [ WEIGHT_FACTOR=0.0001, TARE_FACTOR=0.0001 ] - mask: [ 1, 1, 1 ] expr: [ WEIGHT_FACTOR=0.00001, TARE_FACTOR=0.00001 ] IS: bits: # bit offset 3, 2 bits - mask: [ 0, 1 ] expr: INCREMENT_SIZE=1 - mask: [ 1, 0 ] expr: INCREMENT_SIZE=2 - mask: [ 1, 1 ] expr: INCREMENT_SIZE=5 CHK: bytes: expr: "IS_CHECKSUM_OK=IF(CHK2COMP7(0,17)=VALUE,1,0)" SWB: bits: mask: [ 0, IS_POWER_NOT_ZEROED, 1, IS_UNIT_UK_POUND/IS_UNIT_KILOGRAM, !IS_SETTLED, IS_OVERLOAD, IS_NEGATIVE, IS_NETTO ] SWC: bits: mask: [ 0, IS_HANDTARE, 1, @EW, IS_PRINTREQUEST, 3*@WF ] WF: bits: - mask: [ 0, 0, 0 ] - mask: [ 0, 0, 1 ] expr: [WEIGHT_UNIT=C_UNIT_GRAM, TARE_UNIT=C_UNIT_GRAM ] - mask: [ 0, 1, 0 ] expr: [WEIGHT_UNIT=C_UNIT_METRIC_TON, TARE_UNIT=C_UNIT_METRIC_TON ] - mask: [ 0, 1, 1 ] expr: [WEIGHT_UNIT=C_UNIT_OUNCE, TARE_UNIT=C_UNIT_OUNCE ] - mask: [ 1, 0, 0 ] expr: [WEIGHT_UNIT=C_UNIT_TROY_OUNCE, TARE_UNIT=C_UNIT_TROY_OUNCE ] - mask: [ 1, 0, 1 ] expr: [WEIGHT_UNIT=C_UNIT_PENNY_WEIGHT, TARE_UNIT=C_UNIT_PENNY_WEIGHT ] - mask: [ 1, 1, 0 ] expr: [WEIGHT_UNIT=C_UNIT_UK_TON, TARE_UNIT=C_UNIT_UK_TON ] - mask: [ 1, 1, 1 ] expr: [WEIGHT_UNIT=C_UNIT_CUSTOM, TARE_UNIT=C_UNIT_CUSTOM ] EW: bits: - mask: 0 expr: [ WEIGHT_EXPANSION=1, TARE_EXPANSION=1 ] - mask: 1 expr: [ WEIGHT_EXPANSION=10, TARE_EXPANSION=10 ] W: string: expr: WEIGHT=VALUE T: string: expr: TARE=VALUE
745 total views, 1 views today