package yuku.alkitabconverter.yes1; import yuku.alkitabconverter.yes1.Yes1File.PericopeData.Entry; import yuku.bintex.BintexWriter; import java.io.FileInputStream; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; @Deprecated public class Yes1File { private static final byte FILE_VERSI = 0x01; private static final String TAG = Yes1File.class.getSimpleName(); byte[] FILE_HEADER = {(byte) 0x98, 0x58, 0x0d, 0x0a, 0x00, 0x5d, (byte) 0xe0, FILE_VERSI}; public Seksi[] xseksi; public interface Seksi { byte[] nama(); IsiSeksi isi(); } public abstract class SeksiBernama implements Seksi { private byte[] nama; public SeksiBernama(String nama) { try { this.nama = nama.getBytes("ascii"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } @Override final public byte[] nama() { return nama; } } public interface IsiSeksi { void toBytes(BintexWriter writer) throws Exception; } public static abstract class InfoEdisi implements IsiSeksi { public int versi; // 1; 2 tambah encoding dan keterangan public String nama; public String shortName; public String longName; public String keterangan; public String locale; public int nkitab; public int perikopAda; // 0=ga ada, selain 0: nomer versi perikopIndex dan perikopBlok_ public int encoding; // 1 = ascii; 2 = utf-8 @Override public void toBytes(BintexWriter writer) throws Exception { writer.writeShortString("versi"); writer.writeInt(versi); if (nama != null) { writer.writeShortString("nama"); writer.writeShortString(nama); } writer.writeShortString("judul"); writer.writeShortString(longName); if (shortName != null) { writer.writeShortString("shortName"); writer.writeShortString(shortName); } writer.writeShortString("keterangan"); writer.writeLongString(keterangan); writer.writeShortString("nkitab"); writer.writeInt(nkitab); writer.writeShortString("perikopAda"); writer.writeInt(perikopAda); writer.writeShortString("encoding"); // mulai versi 2 ada. writer.writeInt(encoding); if (locale != null) { writer.writeShortString("locale"); writer.writeShortString(locale); } writer.writeShortString("end"); } } public static class Kitab { public int versi; // 1; 2 mulai ada pdbBookNumber public int pos; public int pdbBookNumber; public String nama; public String judul; public int npasal; public int[] nayat; public int ayatLoncat; public int[] pasal_offset; public int encoding; public int offset; public void toBytes(BintexWriter writer) throws Exception { writer.writeShortString("versi"); writer.writeInt(versi); writer.writeShortString("pos"); writer.writeInt(pos); writer.writeShortString("nama"); writer.writeShortString(nama); writer.writeShortString("judul"); writer.writeShortString(judul); writer.writeShortString("npasal"); writer.writeInt(npasal); writer.writeShortString("nayat"); for (int a: nayat) { writer.writeUint8(a); } writer.writeShortString("ayatLoncat"); writer.writeInt(ayatLoncat); writer.writeShortString("pasal_offset"); for (int a: pasal_offset) { writer.writeInt(a); } if (encoding != 0) { writer.writeShortString("encoding"); writer.writeInt(encoding); } writer.writeShortString("offset"); writer.writeInt(offset); if (pdbBookNumber != 0) { writer.writeShortString("pdbBookNumber"); writer.writeInt(pdbBookNumber); } writer.writeShortString("end"); } public static void nullToBytes(BintexWriter writer) throws Exception { writer.writeShortString("end"); } } public static class InfoKitab implements IsiSeksi { public Kitab[] xkitab; @Override public void toBytes(BintexWriter writer) throws Exception { for (Kitab kitab: xkitab) { if (kitab != null) { kitab.toBytes(writer); } else { Kitab.nullToBytes(writer); } } } } public static class Teks implements IsiSeksi { private final String encoding; public Teks(String encoding) { this.encoding = encoding; } int ayatLoncat = 0; public String[] xisi; @Override public void toBytes(BintexWriter writer) throws Exception { if (ayatLoncat != 0) { throw new RuntimeException("ayatLoncat ga 0"); } for (String isi: xisi) { writer.writeRaw(isi.getBytes(encoding)); writer.writeUint8('\n'); } } } public static class NemplokSeksi implements IsiSeksi { private String nf; public NemplokSeksi(String nf) { this.nf = nf; } @Override public void toBytes(BintexWriter writer) throws Exception { FileInputStream in = new FileInputStream(nf); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r <= 0) break; writer.writeRaw(b, 0, r); } in.close(); } } public static class PerikopBlok implements IsiSeksi { private final PericopeData data; public PerikopBlok(PericopeData data) { this.data = data; } @Override public void toBytes(BintexWriter writer) throws Exception { int offsetAwalSeksi = writer.getPos(); for (Entry entry: data.entries) { int offsetAwalEntri = writer.getPos(); /* * Blok { * uint8 versi = 2 * lstring judul * uint8 nparalel * sstring[nparalel] xparalel * } * * // OR * * Blok { * uint8 versi = 3 * autostring judul * uint8 nparalel * autostring[nparalel] xparalel * } */ writer.writeUint8(entry.block.version); // versi if (entry.block.version == 2) { writer.writeLongString(entry.block.title); // judul writer.writeUint8(entry.block.parallels == null? 0: entry.block.parallels.size()); // nparalel if (entry.block.parallels != null) { // xparalel for (String paralel: entry.block.parallels) { writer.writeShortString(paralel); } } } else if (entry.block.version == 3) { writer.writeAutoString(entry.block.title); // judul writer.writeUint8(entry.block.parallels == null? 0: entry.block.parallels.size()); // nparalel if (entry.block.parallels != null) { // xparalel for (String paralel: entry.block.parallels) { writer.writeAutoString(paralel); } } } else { throw new RuntimeException("pericope entry.block.version " + entry.block.version + " not supported yet"); } entry.block._offset = offsetAwalEntri - offsetAwalSeksi; } } } public static class PerikopIndex implements IsiSeksi { private final PericopeData data; public PerikopIndex(PericopeData data) { this.data = data; } @Override public void toBytes(BintexWriter writer) throws Exception { writer.writeInt(data.entries.size()); // nentri for (Entry entry: data.entries) { if (entry.block._offset == -1) { throw new RuntimeException("offset entri perikop belum dihitung"); // $NON-NLS-1$ } writer.writeInt(entry.ari); writer.writeInt(entry.block._offset); } } } public static class PericopeData { public static class Entry { public int ari; public Block block; } public static class Block { public int version; public String title; public List<String> parallels; int _offset = -1; public void addParallel(String parallel) { if (parallels == null) parallels = new ArrayList<>(); parallels.add(parallel); } } public List<Entry> entries; public void addEntry(Entry e) { if (entries == null) entries = new ArrayList<>(); entries.add(e); } } public void output(RandomAccessFile file) throws Exception { RandomOutputStream ros = new RandomOutputStream(file); BintexWriter os2 = new BintexWriter(ros); os2.writeRaw(FILE_HEADER); long pos = file.getFilePointer(); for (Seksi seksi: xseksi) { pos = file.getFilePointer(); { byte[] nama = seksi.nama(); if (bisaLog()) Log.d(TAG, "[pos=" + pos + "] tulis nama seksi: " + new String(nama)); os2.writeRaw(nama); } pos = file.getFilePointer(); { byte[] palsu = {-1, -1, -1, -1}; if (bisaLog()) Log.d(TAG, "[pos=" + pos + "] tulis placeholder ukuran"); os2.writeRaw(palsu); } int posSebelumIsi = os2.getPos(); if (bisaLog()) Log.d(TAG, "[pos=" + file.getFilePointer() + "] tulis isi seksi"); seksi.isi().toBytes(os2); int posSesudahIsi = os2.getPos(); int ukuranIsi = posSesudahIsi - posSebelumIsi; if (bisaLog()) Log.d(TAG, "[pos=" + file.getFilePointer() + "] isi seksi selesai ditulis, sebesar " + ukuranIsi); long posUntukMelanjutkan = file.getFilePointer(); { file.seek(pos); if (bisaLog()) Log.d(TAG, "[pos=" + pos + "] tulis ukuran: " + ukuranIsi); os2.writeInt(ukuranIsi); } file.seek(posUntukMelanjutkan); } pos = file.getFilePointer(); if (bisaLog()) Log.d(TAG, "[pos=" + pos + "] tulis penanda tidak ada seksi lagi (____________)"); os2.writeRaw("____________".getBytes("ascii")); os2.close(); pos = file.getFilePointer(); if (bisaLog()) Log.d(TAG, "[pos=" + pos + "] selesai"); } static Boolean bisaLog = null; private static boolean bisaLog() { if (bisaLog == null) { try { Class.forName("android.util.Log"); bisaLog = true; } catch (Exception e) { bisaLog = false; } } return bisaLog; } // dummy static class Log { public static void d(final String tag, final String msg) { System.out.println(tag + "\t" + msg); } } }