Load binary hyphen data files
Support for loading the pre-compiled binary format for hyphenation
patterns.
Bug: 21562869
Bug: 21826930
Bug: 24570591
Change-Id: Iaeaa9c9ac9dac236af6b0d7894c2e2396bc8447d
(cherry picked from commit 091dba2de1e5fa7d4db9f8ccbf1f86e5825d0f52)
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
index 10a994a..416dd01 100644
--- a/core/java/android/text/Hyphenator.java
+++ b/core/java/android/text/Hyphenator.java
@@ -16,15 +16,17 @@
package android.text;
-import com.android.internal.annotations.GuardedBy;
-
import android.annotation.Nullable;
import android.util.Log;
-import libcore.io.IoUtils;
+import com.android.internal.annotations.GuardedBy;
import java.io.File;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Locale;
@@ -45,12 +47,18 @@
@GuardedBy("sLock")
final static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>();
- final static Hyphenator sEmptyHyphenator = new Hyphenator(StaticLayout.nLoadHyphenator(""));
+ final static Hyphenator sEmptyHyphenator =
+ new Hyphenator(StaticLayout.nLoadHyphenator(null, 0), null);
final private long mNativePtr;
- private Hyphenator(long nativePtr) {
+ // We retain a reference to the buffer to keep the memory mapping valid
+ @SuppressWarnings("unused")
+ final private ByteBuffer mBuffer;
+
+ private Hyphenator(long nativePtr, ByteBuffer b) {
mNativePtr = nativePtr;
+ mBuffer = b;
}
public static long get(@Nullable Locale locale) {
@@ -90,12 +98,18 @@
}
private static Hyphenator loadHyphenator(String languageTag) {
- String patternFilename = "hyph-"+languageTag.toLowerCase(Locale.US)+".pat.txt";
+ String patternFilename = "hyph-" + languageTag.toLowerCase(Locale.US) + ".hyb";
File patternFile = new File(getSystemHyphenatorLocation(), patternFilename);
try {
- String patternData = IoUtils.readFileAsString(patternFile.getAbsolutePath());
- long nativePtr = StaticLayout.nLoadHyphenator(patternData);
- return new Hyphenator(nativePtr);
+ RandomAccessFile f = new RandomAccessFile(patternFile, "r");
+ try {
+ FileChannel fc = f.getChannel();
+ MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+ long nativePtr = StaticLayout.nLoadHyphenator(buf, 0);
+ return new Hyphenator(nativePtr, buf);
+ } finally {
+ f.close();
+ }
} catch (IOException e) {
Log.e(TAG, "error loading hyphenation " + patternFile, e);
return null;
@@ -148,7 +162,7 @@
sMap.put(null, null);
// TODO: replace this with a discovery-based method that looks into /system/usr/hyphen-data
- String[] availableLanguages = {"en-US", "eu", "hu", "hy", "nb", "nn", "sa", "und-Ethi"};
+ String[] availableLanguages = {"en-US", "eu", "hu", "hy", "nb", "nn", "und-Ethi"};
for (int i = 0; i < availableLanguages.length; i++) {
String languageTag = availableLanguages[i];
Hyphenator h = loadHyphenator(languageTag);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 3b0def2..6303322 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -29,6 +29,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;
@@ -1243,7 +1244,7 @@
private static native void nFreeBuilder(long nativePtr);
private static native void nFinishBuilder(long nativePtr);
- /* package */ static native long nLoadHyphenator(String patternData);
+ /* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset);
private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 90e4bb6..a94ea8b 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -117,9 +117,17 @@
b->finish();
}
-static jlong nLoadHyphenator(JNIEnv* env, jclass, jstring patternData) {
- ScopedStringChars str(env, patternData);
- Hyphenator* hyphenator = Hyphenator::load(str.get(), str.size());
+static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset) {
+ const uint8_t* bytebuf = nullptr;
+ if (buffer != nullptr) {
+ void* rawbuf = env->GetDirectBufferAddress(buffer);
+ if (rawbuf != nullptr) {
+ bytebuf = reinterpret_cast<const uint8_t*>(rawbuf) + offset;
+ } else {
+ ALOGE("failed to get direct buffer address");
+ }
+ }
+ Hyphenator* hyphenator = Hyphenator::loadBinary(bytebuf);
return reinterpret_cast<jlong>(hyphenator);
}
@@ -177,7 +185,7 @@
{"nNewBuilder", "()J", (void*) nNewBuilder},
{"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
{"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
- {"nLoadHyphenator", "(Ljava/lang/String;)J", (void*) nLoadHyphenator},
+ {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;I)J", (void*) nLoadHyphenator},
{"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
{"nSetupParagraph", "(J[CIFIF[IIII)V", (void*) nSetupParagraph},
{"nSetIndents", "(J[I)V", (void*) nSetIndents},