Created
October 24, 2020 00:05
-
-
Save OopsieWoopsie/9f39907c2925ae7b7e8d61a11c6208b1 to your computer and use it in GitHub Desktop.
Parser for OLPC Manufacturing Data. http://wiki.laptop.org/go/Manufacturing_Data_Specification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.sheidy.mfgparse; | |
import java.nio.file.Files; | |
import java.nio.file.Paths; | |
import java.util.LinkedHashMap; | |
import java.util.Map; | |
public class ParseMfgData { | |
public static Map<String, byte[]> parseMfgData(byte[] data) { | |
Map<String, byte[]> values = new LinkedHashMap<>(); | |
for (int i = data.length - 1; i > 0; i--) { | |
if (data[i] == (byte) 0xFF) break; | |
char t2 = (char) data[i--]; | |
char t1 = (char) data[i--]; | |
String tag = new StringBuilder() | |
.append(t1) | |
.append(t2) | |
.toString(); | |
int len = data[i--]; | |
if (len >= 0 && len <= 127) { // 4-byte tag | |
int check = data[i--]; | |
if (check == ~len) { | |
byte[] value = new byte[len]; | |
for (int j = value.length-1; j >= 0; j--) { | |
value[j] = data[i--]; | |
} | |
i++; | |
values.put(tag, value); | |
continue; | |
} | |
} else { // 5-byte tag | |
int low_length = data[i--]; | |
int high_length = data[i--]; | |
byte check_byte = (byte) len; | |
len = (high_length << 7) + low_length; | |
byte calc_check = (byte) (low_length ^ high_length ^ 0xff); | |
if (check_byte == calc_check) { | |
byte[] value = new byte[len]; | |
for (int j = value.length-1; j >= 0; j--) { | |
value[j] = data[i--]; | |
} | |
i++; | |
values.put(tag, value); | |
continue; | |
} | |
} | |
System.err.println("error parsing tag: " + tag + " b: " + (byte)len); | |
break; | |
} | |
return values; | |
} | |
/*******************************************************/ | |
public static void main(String[] args) throws Exception { | |
if (args.length == 0) { | |
System.out.println("No file specified"); | |
return; | |
} | |
byte[] data = Files.readAllBytes(Paths.get(args[0])); | |
Map<String, byte[]> tags = parseMfgData(data); | |
for (Map.Entry<String, byte[]> e : tags.entrySet()) { | |
String tag = e.getKey(); | |
byte[] val = e.getValue(); | |
if (val.length == 0) { // boolean? | |
System.out.println(tag + ":"); | |
} else if (val[val.length - 1] == 0) { // string | |
System.out.println(tag + ": " + new String(val)); | |
} else { // binary | |
System.out.println(tag + ": " + hex(val)); | |
} | |
} | |
} | |
private static String hex(byte[] a) { | |
StringBuilder sb = new StringBuilder(); | |
for (byte b : a) sb.append(String.format("%02x ", b)); | |
return sb.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment