I tried creating a utility to parse gettext po file and generate binary mo file. The parser is simple (my co. not use fuzzy, plural, etc. things, just msgid/msgstr), but the generator is not work.
Here is the description of the mo file, here is the original generator source (it's C), and found a php script (https://github.com/josscrowcroft/php.mo/blob/master/php-mo.php) also.
My code:
public void writeFile(String filename, Map<String, String> polines) throws FileNotFoundException, IOException {
DataOutputStream os = new DataOutputStream(new FileOutputStream(filename));
HashMap<String, String> bvc = new HashMap<String, String>();
TreeMap<String, String> hash = new TreeMap(bvc);
hash.putAll(polines);
StringBuilder ids = new StringBuilder();
StringBuilder strings = new StringBuilder();
ArrayList<ArrayList> offsets = new ArrayList<ArrayList>();
ArrayList<Integer> key_offsets = new ArrayList<Integer>();
ArrayList<Integer> value_offsets = new ArrayList<Integer>();
ArrayList<Integer> temp_offsets = new ArrayList<Integer>();
for (Map.Entry<String, String> entry : hash.entrySet()) {
String id = entry.getKey();
String str = entry.getValue();
ArrayList<Integer> offsetsItems = new ArrayList<Integer>();
offsetsItems.add(ids.length());
offsetsItems.add(id.length());
offsetsItems.add(strings.length());
offsetsItems.add(str.length());
offsets.add((ArrayList) offsetsItems.clone());
ids.append(id).append('\0');
strings.append(str).append('\0');
}
Integer key_start = 7 * 4 + hash.size() * 4 * 4;
Integer value_start = key_start + ids.length();
Iterator e = offsets.iterator();
while (e.hasNext()) {
ArrayList<Integer> offEl = (ArrayList<Integer>) e.next();
key_offsets.add(offEl.get(1));
key_offsets.add(offEl.get(0) + key_start);
value_offsets.add(offEl.get(3));
value_offsets.add(offEl.get(2) + value_start);
}
temp_offsets.addAll(key_offsets);
temp_offsets.addAll(value_offsets);
os.writeByte(0xde);
os.writeByte(0x12);
os.writeByte(0x04);
os.writeByte(0x95);
os.writeByte(0x00);
os.writeInt(hash.size() & 0xff);
os.writeInt((7 * 4) & 0xff);
os.writeInt((7 * 4 + hash.size() * 8) & 0xff);
os.writeInt(0x00000000);
os.writeInt(key_start & 0xff);
Iterator offi = temp_offsets.iterator();
while (offi.hasNext()) {
Integer off = (Integer) offi.next();
os.writeInt(off & 0xff);
}
os.writeUTF(ids.toString());
os.writeUTF(strings.toString());
os.close();
}
The line os.writeInt(key_start);
seems like ok, the differences from the original tool generated mo file starting after theese bytes.
What's wrong? (aside from my scary english..)