1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-03 17:59:33 +02:00

Encoding converter (in progress)

This commit is contained in:
Nikolay Pultsin 2012-03-17 20:02:26 +00:00
parent 2449325867
commit 0ee1c75698
9 changed files with 106 additions and 7 deletions

View file

@ -29,6 +29,7 @@ const char * const AndroidUtil::Class_java_io_PrintStream = "java/io/PrintStream
const char * const AndroidUtil::Class_ZLibrary = "org/geometerplus/zlibrary/core/library/ZLibrary"; const char * const AndroidUtil::Class_ZLibrary = "org/geometerplus/zlibrary/core/library/ZLibrary";
const char * const AndroidUtil::Class_NativeFormatPlugin = "org/geometerplus/fbreader/formats/NativeFormatPlugin"; const char * const AndroidUtil::Class_NativeFormatPlugin = "org/geometerplus/fbreader/formats/NativeFormatPlugin";
const char * const AndroidUtil::Class_PluginCollection = "org/geometerplus/fbreader/formats/PluginCollection"; const char * const AndroidUtil::Class_PluginCollection = "org/geometerplus/fbreader/formats/PluginCollection";
const char * const AndroidUtil::Class_JavaEncodingCollection = "org/geometerplus/fbreader/formats/JavaEncodingCollection";
const char * const AndroidUtil::Class_Paths = "org/geometerplus/fbreader/Paths"; const char * const AndroidUtil::Class_Paths = "org/geometerplus/fbreader/Paths";
const char * const AndroidUtil::Class_ZLFile = "org/geometerplus/zlibrary/core/filesystem/ZLFile"; const char * const AndroidUtil::Class_ZLFile = "org/geometerplus/zlibrary/core/filesystem/ZLFile";
const char * const AndroidUtil::Class_Book = "org/geometerplus/fbreader/library/Book"; const char * const AndroidUtil::Class_Book = "org/geometerplus/fbreader/library/Book";
@ -57,6 +58,11 @@ jmethodID AndroidUtil::MID_NativeFormatPlugin_supportedFileType;
jmethodID AndroidUtil::SMID_PluginCollection_Instance; jmethodID AndroidUtil::SMID_PluginCollection_Instance;
jmethodID AndroidUtil::SMID_JavaEncodingCollection_Instance;
jmethodID AndroidUtil::MID_JavaEncodingCollection_getEncoding_int;
jmethodID AndroidUtil::MID_JavaEncodingCollection_getEncoding_String;
jmethodID AndroidUtil::MID_JavaEncodingCollection_isEncodingSupported;
jmethodID AndroidUtil::SMID_ZLFile_createFileByPath; jmethodID AndroidUtil::SMID_ZLFile_createFileByPath;
jmethodID AndroidUtil::MID_ZLFile_children; jmethodID AndroidUtil::MID_ZLFile_children;
jmethodID AndroidUtil::MID_ZLFile_exists; jmethodID AndroidUtil::MID_ZLFile_exists;
@ -142,6 +148,13 @@ bool AndroidUtil::init(JavaVM* jvm) {
CHECK_NULL( SMID_PluginCollection_Instance = env->GetStaticMethodID(cls, "Instance", "()Lorg/geometerplus/fbreader/formats/PluginCollection;") ); CHECK_NULL( SMID_PluginCollection_Instance = env->GetStaticMethodID(cls, "Instance", "()Lorg/geometerplus/fbreader/formats/PluginCollection;") );
env->DeleteLocalRef(cls); env->DeleteLocalRef(cls);
CHECK_NULL( cls = env->FindClass(Class_JavaEncodingCollection) );
CHECK_NULL( SMID_JavaEncodingCollection_Instance = env->GetStaticMethodID(cls, "Instance", "()Lorg/geometerplus/fbreader/formats/JavaEncodingCollection;") );
CHECK_NULL( MID_JavaEncodingCollection_getEncoding_String = env->GetMethodID(cls, "getEncoding", "(Ljava/lang/String;)Lorg/geometerplus/fbreader/formats/Encoding;") );
CHECK_NULL( MID_JavaEncodingCollection_getEncoding_int = env->GetMethodID(cls, "getEncoding", "(I)Lorg/geometerplus/fbreader/formats/Encoding;") );
CHECK_NULL( MID_JavaEncodingCollection_isEncodingSupported = env->GetMethodID(cls, "isEncodingSupported", "()Z") );
env->DeleteLocalRef(cls);
CHECK_NULL( cls = env->FindClass(Class_ZLFile) ); CHECK_NULL( cls = env->FindClass(Class_ZLFile) );
CHECK_NULL( SMID_ZLFile_createFileByPath = env->GetStaticMethodID(cls, "createFileByPath", "(Ljava/lang/String;)Lorg/geometerplus/zlibrary/core/filesystem/ZLFile;") ); CHECK_NULL( SMID_ZLFile_createFileByPath = env->GetStaticMethodID(cls, "createFileByPath", "(Ljava/lang/String;)Lorg/geometerplus/zlibrary/core/filesystem/ZLFile;") );
CHECK_NULL( MID_ZLFile_children = env->GetMethodID(cls, "children", "()Ljava/util/List;") ); CHECK_NULL( MID_ZLFile_children = env->GetMethodID(cls, "children", "()Ljava/util/List;") );

View file

@ -40,6 +40,7 @@ public:
static const char * const Class_ZLFile; static const char * const Class_ZLFile;
static const char * const Class_NativeFormatPlugin; static const char * const Class_NativeFormatPlugin;
static const char * const Class_PluginCollection; static const char * const Class_PluginCollection;
static const char * const Class_JavaEncodingCollection;
static const char * const Class_Paths; static const char * const Class_Paths;
static const char * const Class_Book; static const char * const Class_Book;
static const char * const Class_Tag; static const char * const Class_Tag;
@ -75,6 +76,11 @@ public:
static jmethodID SMID_PluginCollection_Instance; static jmethodID SMID_PluginCollection_Instance;
static jmethodID SMID_JavaEncodingCollection_Instance;
static jmethodID MID_JavaEncodingCollection_getEncoding_String;
static jmethodID MID_JavaEncodingCollection_getEncoding_int;
static jmethodID MID_JavaEncodingCollection_isEncodingSupported;
static jmethodID SMID_Paths_cacheDirectory; static jmethodID SMID_Paths_cacheDirectory;
static jfieldID FID_Book_File; static jfieldID FID_Book_File;

View file

@ -17,6 +17,7 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#include <AndroidUtil.h>
#include <ZLUnicodeUtil.h> #include <ZLUnicodeUtil.h>
#include "JavaEncodingConverter.h" #include "JavaEncodingConverter.h"
@ -32,12 +33,20 @@ public:
void reset(); void reset();
bool fillTable(int *map); bool fillTable(int *map);
private:
jobject myJavaConverter;
friend class JavaEncodingConverterProvider; friend class JavaEncodingConverterProvider;
}; };
bool JavaEncodingConverterProvider::providesConverter(const std::string &encoding) { bool JavaEncodingConverterProvider::providesConverter(const std::string &encoding) {
// TODO: implement JNIEnv *env = AndroidUtil::getEnv();
return false; jclass cls = env->FindClass(AndroidUtil::Class_JavaEncodingCollection);
jobject collection = env->CallStaticObjectMethod(cls, AndroidUtil::SMID_JavaEncodingCollection_Instance);
jboolean result = env->CallBooleanMethod(collection, AndroidUtil::MID_JavaEncodingCollection_isEncodingSupported);
env->DeleteLocalRef(collection);
env->DeleteLocalRef(cls);
return result != 0;
} }
shared_ptr<ZLEncodingConverter> JavaEncodingConverterProvider::createConverter(const std::string &encoding) { shared_ptr<ZLEncodingConverter> JavaEncodingConverterProvider::createConverter(const std::string &encoding) {

View file

@ -35,6 +35,14 @@
-keepclassmembers class org.geometerplus.fbreader.formats.FormatPlugin { -keepclassmembers class org.geometerplus.fbreader.formats.FormatPlugin {
public ** supportedFileType(); public ** supportedFileType();
} }
-keep class org.geometerplus.fbreader.formats.Encoding
-keep class org.geometerplus.fbreader.formats.JavaEncodingCollection
-keepclassmembers class org.geometerplus.fbreader.formats.JavaEncodingCollection {
public static ** Instance();
public ** getEncoding(java.lang.String);
public ** getEncoding(int);
public boolean isEncodingSupported(java.lang.String);
}
-keep class org.geometerplus.fbreader.Paths -keep class org.geometerplus.fbreader.Paths
-keepclassmembers class org.geometerplus.fbreader.Paths { -keepclassmembers class org.geometerplus.fbreader.Paths {
public static ** cacheDirectory(); public static ** cacheDirectory();

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2007-2012 Geometer Plus <contact@geometerplus.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.fbreader.formats;
import java.nio.*;
import java.nio.charset.*;
public class EncodingConverter {
private CharsetDecoder myDecoder;
private CharsetEncoder myEncoder;
EncodingConverter(String encoding) {
myDecoder = Charset.forName(encoding).newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
myEncoder = Charset.forName("utf-8").newEncoder();
}
// we assume out is large enough for this conversion
// returns number of filled bytes in out buffer
int convert(byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
final ByteBuffer inBuffer = ByteBuffer.wrap(in, inOffset, inLength);
final ByteBuffer outBuffer = ByteBuffer.wrap(out, outOffset, out.length - outOffset);
try {
final CharBuffer charBuffer = myDecoder.decode(inBuffer);
myEncoder.encode(charBuffer, outBuffer, true);
return charBuffer.length();
} catch (CharacterCodingException e) {
return 0;
}
}
void reset() {
myDecoder.reset();
myEncoder.reset();
}
}

View file

@ -35,7 +35,7 @@ abstract class FilteredEncodingCollection extends EncodingCollection {
); );
} }
protected abstract boolean isEncodingSupported(String name); public abstract boolean isEncodingSupported(String name);
@Override @Override
public List<Encoding> encodings() { public List<Encoding> encodings() {

View file

@ -22,12 +22,21 @@ package org.geometerplus.fbreader.formats;
import java.nio.charset.Charset; import java.nio.charset.Charset;
public final class JavaEncodingCollection extends FilteredEncodingCollection { public final class JavaEncodingCollection extends FilteredEncodingCollection {
public JavaEncodingCollection() { private volatile static JavaEncodingCollection ourInstance;
public static JavaEncodingCollection Instance() {
if (ourInstance == null) {
ourInstance = new JavaEncodingCollection();
}
return ourInstance;
}
private JavaEncodingCollection() {
super(); super();
} }
@Override @Override
protected boolean isEncodingSupported(String name) { public boolean isEncodingSupported(String name) {
try { try {
return Charset.forName(name) != null; return Charset.forName(name) != null;
} catch (Exception e) { } catch (Exception e) {

View file

@ -105,6 +105,6 @@ public class NativeFormatPlugin extends FormatPlugin {
@Override @Override
public EncodingCollection supportedEncodings() { public EncodingCollection supportedEncodings() {
// TODO: implement // TODO: implement
return new JavaEncodingCollection(); return JavaEncodingCollection.Instance();
} }
} }

View file

@ -246,6 +246,6 @@ public class MobipocketPlugin extends JavaFormatPlugin {
@Override @Override
public EncodingCollection supportedEncodings() { public EncodingCollection supportedEncodings() {
return new JavaEncodingCollection(); return JavaEncodingCollection.Instance();
} }
} }