package org.madore.android.unicodeMap; import java.util.Iterator; import java.util.NoSuchElementException; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.sql.SQLException; import android.content.Context; import android.content.res.AssetManager; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; import android.database.sqlite.SQLiteOpenHelper; public class UnicodeDatabase { protected static final String DATABASE_NAME = "unicode.db"; protected static final int DATABASE_VERSION = 1; protected static final String UNICODE_TABLE_NAME = "unicode"; protected static class DatabaseInit extends SQLiteOpenHelper { final Context context; DatabaseInit(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; } protected void parseUnicodeData(SQLiteDatabase db) { AssetManager amgr = context.getAssets(); try { BufferedReader rd = new BufferedReader(new InputStreamReader(amgr.open("UnicodeData.txt"), "US-ASCII")); SQLiteStatement cmd = db.compileStatement("INSERT INTO "+UNICODE_TABLE_NAME +" VALUES ( ? , ? , ? )"); String line; while ( ( line = rd.readLine() ) != null ) { String[] fields = line.split(";"); int codePoint = Integer.parseInt(fields[0], 16); String name = fields[1]; String category = fields[2]; if ( name.charAt(0) == '<' ) continue; cmd.bindLong(1, codePoint); cmd.bindString(2, name); cmd.bindString(3, category); cmd.execute(); } } catch (UnsupportedEncodingException e) { throw new AssertionError("US-ASCII encoding unsupported"); } catch (IOException e) { throw new RuntimeException(e); } } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE "+UNICODE_TABLE_NAME+" ( " +"id INTEGER PRIMARY KEY , " +"name TEXT , " +"category TEXT )"); parseUnicodeData(db); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS "+UNICODE_TABLE_NAME); onCreate(db); } } SQLiteDatabase db; public UnicodeDatabase(Context context) { DatabaseInit dbinit = new DatabaseInit(context); if ( true ) db = dbinit.getReadableDatabase(); else { db = dbinit.getWritableDatabase(); db.execSQL("DELETE FROM "+UNICODE_TABLE_NAME); dbinit.parseUnicodeData(db); } } protected final static String[] queryColumns = { "id", "name", "category" }; public UnicodeCharacter getSingle(int codePoint) { final Cursor c = db.query(UNICODE_TABLE_NAME, queryColumns, "id=?", new String[] { Integer.toString(codePoint) }, null, null, null, null); UnicodeCharacter ch; if ( c.getCount() > 0 ) { c.moveToFirst(); ch = new UnicodeCharacter(c.getInt(0), c.getString(1), UnicodeCharacter.Category.fromCode(c.getString(2))); } else ch = null; c.close(); return ch; } protected final static String[] countColumns = { "count(*)" }; public int countRange(int from, int to) { final Cursor c = db.query(UNICODE_TABLE_NAME, countColumns, "id >= ? AND id < ?", new String[] { Integer.toString(from), Integer.toString(to) }, null, null, null, null); if ( c.getCount() != 1 ) throw new AssertionError("\"SELECT count(*)\" returned no result"); c.moveToFirst(); int cnt = c.getInt(0); c.close(); return cnt; } private static class CursorIterable implements Iterable { protected final Cursor c; public CursorIterable(Cursor c) { this.c = c; } public Iterator iterator() { final boolean hasData = c.getCount() > 0; if ( hasData ) c.moveToFirst(); else c.close(); return (new Iterator() { boolean hasNext = hasData; public boolean hasNext() { return hasNext; } public UnicodeCharacter next() { if ( hasNext ) { UnicodeCharacter ch = new UnicodeCharacter(c.getInt(0), c.getString(1), UnicodeCharacter.Category.fromCode(c.getString(2))); if ( c.isLast() ) { hasNext = false; c.close(); } else c.moveToNext(); return ch; } else throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } }); } } public Iterable getRange(int from, int to) { final Cursor c = db.query(UNICODE_TABLE_NAME, queryColumns, "id >= ? AND id < ?", new String[] { Integer.toString(from), Integer.toString(to) }, null, null, null, null); return new CursorIterable(c); } }