From: thadh Date: Tue, 10 Feb 2009 05:33:33 +0000 (-0800) Subject: go X-Git-Url: http://gitweb.fperrin.net/?a=commitdiff_plain;h=b88f0117c6a4792902d8eebe82b3c5fda386e6eb;p=Dictionary.git go --- b88f0117c6a4792902d8eebe82b3c5fda386e6eb diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100755 index 0000000..640d31d --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/icon.png b/res/drawable/icon.png new file mode 100755 index 0000000..7502484 Binary files /dev/null and b/res/drawable/icon.png differ diff --git a/res/layout/main.xml b/res/layout/main.xml new file mode 100755 index 0000000..4c08a55 --- /dev/null +++ b/res/layout/main.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml new file mode 100755 index 0000000..61f6cd4 --- /dev/null +++ b/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Hello World, Dictionary + Dictionary + diff --git a/src/com/hughes/android/dictionary/Dictionary.java b/src/com/hughes/android/dictionary/Dictionary.java new file mode 100755 index 0000000..52b46b4 --- /dev/null +++ b/src/com/hughes/android/dictionary/Dictionary.java @@ -0,0 +1,130 @@ +package com.hughes.android.dictionary; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; + +import android.app.Activity; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.TextView; + +public class Dictionary extends Activity { + + private String searchText = ""; + + private List entries = new ArrayList(100); + + public static final String INDEX_FORMAT = "%s_index_%d"; + private final File dictionaryFile = new File("/sdcard/dict-de-en.txt"); + private final Index[] indexes = new Index[2]; + private final byte lang = Entry.LANG1; + + private DictionaryListAdapter dictionaryListAdapter = new DictionaryListAdapter(); + + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + Log.d("THAD", "onCreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + EditText searchText = (EditText) findViewById(R.id.SearchText); + searchText.addTextChangedListener(new DictionaryTextWatcher()); + + ListView searchResults = (ListView) findViewById(R.id.SearchResults); + searchResults.setAdapter(dictionaryListAdapter); + + try { + loadIndex(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private void loadIndex() throws IOException, ClassNotFoundException { + Log.d("THAD", "enter loadIndex"); + indexes[0] = new Index(String.format(INDEX_FORMAT, dictionaryFile.getAbsolutePath(), Entry.LANG1)); + Log.d("THAD", "exit loadIndex"); + } + + void onSearchTextChange(final String searchText) { + this.searchText = searchText; + final Index.Node node = indexes[lang].lookup(searchText); + + try { + final long length = dictionaryFile.length(); + Log.d("THAD", "Dictionary file length=" + length); + + final RandomAccessFile raf = new RandomAccessFile(dictionaryFile, "r"); + raf.seek(length / 2); +// final InputStreamReader dictionaryReader = new InputStreamReader(new BufferedInputStream(new FileInputStream("/sdcard/dict-de-en.txt"))); +// skip(dictionaryReader, length / 2); + + for (int i = 0; i < entries.length; ++i) { + entries[i] = raf.readLine(); + raf.skipBytes((int) (length / 100000)); + } + + raf.close(); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + dictionaryListAdapter.notifyDataSetChanged(); + } + + private class DictionaryListAdapter extends BaseAdapter { + + public int getCount() { + return 1000000; + + } + + public Object getItem(int position) { + return searchText + position + entries[position % entries.length]; + } + + public long getItemId(int position) { + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + TextView result = null; + if (convertView instanceof TextView) { + result = (TextView) convertView; + } else { + result = new TextView(parent.getContext()); + } + result.setText((String) getItem(position)); + return result; + } + + } + + private class DictionaryTextWatcher implements TextWatcher { + public void afterTextChanged(Editable searchText) { + onSearchTextChange(searchText.toString()); + } + + public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, + int arg3) { + } + + public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { + } + } + +} \ No newline at end of file diff --git a/src/com/hughes/android/dictionary/Entry.java b/src/com/hughes/android/dictionary/Entry.java new file mode 100755 index 0000000..3bb7b67 --- /dev/null +++ b/src/com/hughes/android/dictionary/Entry.java @@ -0,0 +1,47 @@ +package com.hughes.android.dictionary; + +import java.util.regex.Pattern; + +public final class Entry { + + static final byte LANG1 = 0; + static final byte LANG2 = 1; + + static final Pattern lineSplitPattern = Pattern.compile("\\s+::\\s+"); + + String lang1 = ""; + String lang2 = ""; + + boolean parseFromLine(final String line) { + final String[] parts = lineSplitPattern.split(line); + if (parts.length != 2) { + System.err.println("Entry:" + "Invalid line: " + line); + return false; + } + lang1 = parts[0]; + lang2 = parts[1]; + return true; + } + + String getAllText(final byte lang) { + if (lang == LANG1) { + return lang1; + } + assert lang == LANG2; + return lang2; + } + + String getIndexableText(final byte lang) { + String text = getAllText(lang); + text = text.replaceAll("[\"\\.!?,]", ""); + text = text.replaceAll("\\{[^}]+\\}", ""); + return text; + } + + public String normalizeToken(final String token, final byte lang) { + return token.toLowerCase().replaceAll("ß", "ss").replaceAll("ä", "ae") + .replaceAll("ö", "oe").replaceAll("ü", "ue") + .replaceAll("[^A-Za-z]", ""); + } + +} diff --git a/src/com/hughes/android/dictionary/Index.java b/src/com/hughes/android/dictionary/Index.java new file mode 100755 index 0000000..89024ff --- /dev/null +++ b/src/com/hughes/android/dictionary/Index.java @@ -0,0 +1,81 @@ +package com.hughes.android.dictionary; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Map; +import java.util.TreeMap; + +import com.hughes.util.LRUCacheMap; + + +public final class Index { + + final String filename; + final RandomAccessFile file; + + final Node root; + final Map locationToNode = new LRUCacheMap(5000); + + + public Index(final String filename) throws IOException { + this.filename = filename; + file = new RandomAccessFile(filename, "r"); + root = getNode("", 0); + } + + public Node lookup(final String text) throws IOException { + return lookup(text, 0, root); + } + + private Node lookup(final String text, final int pos, final Node n) throws IOException { + if (pos == text.length()) { + return n; + } + for (int i = pos + 1; i <= text.length(); ++i) { + final Integer child = n.children.get(text.substring(pos, i)); + if (child != null) { + return lookup(text, i, getNode(text.substring(0, i), child)); + } + } + return n; + } + + private Node getNode(final String text, final int location) throws IOException { + Node node = locationToNode.get(location); + if (node == null) { + node = new Node(text, location); + locationToNode.put(location, node); + } + return node; + } + + final class Node { + final String text; + final int location; + final TreeMap children; + final int[] offsets; + + Node(final String text, final int location) throws IOException { + this.text = text; + this.location = location; + + file.seek(location); + final int numChildren = file.readInt(); + children = new TreeMap(); + for (int i = 0; i < numChildren; ++i) { + final String chunk = file.readUTF().intern(); + if (chunk.length() == 0) { + throw new IOException("Empty string chunk."); + } + children.put(chunk, file.readInt()); + } + + final int numOffsets = file.readInt(); + offsets = new int[numOffsets]; + for (int i = 0; i < offsets.length; ++i) { + offsets[i] = file.readInt(); + } + } + } + +} diff --git a/src/com/hughes/android/dictionary/R.java b/src/com/hughes/android/dictionary/R.java new file mode 100755 index 0000000..88153f5 --- /dev/null +++ b/src/com/hughes/android/dictionary/R.java @@ -0,0 +1,27 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.hughes.android.dictionary; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int icon=0x7f020000; + } + public static final class id { + public static final int SearchResults=0x7f050001; + public static final int SearchText=0x7f050000; + } + public static final class layout { + public static final int main=0x7f030000; + } + public static final class string { + public static final int app_name=0x7f040001; + public static final int hello=0x7f040000; + } +}