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

synchronization with native branch

This commit is contained in:
Nikolay Pultsin 2012-03-01 00:49:15 +00:00
parent 27595d6429
commit 072a506dc0
6 changed files with 415 additions and 1 deletions

View file

@ -51,10 +51,15 @@ LOCAL_SRC_FILES := \
NativeFormats/zlibrary/core/src/language/ZLStatisticsXMLReader.cpp \
NativeFormats/zlibrary/core/src/library/ZLibrary.cpp \
NativeFormats/zlibrary/core/src/logger/ZLLogger.cpp \
NativeFormats/zlibrary/core/src/util/ZLStringUtil.cpp \
NativeFormats/zlibrary/core/src/util/ZLUnicodeUtil.cpp \
NativeFormats/zlibrary/core/src/xml/ZLXMLReader.cpp \
NativeFormats/fbreader/src/formats/FormatPlugin.cpp \
NativeFormats/fbreader/src/formats/PluginCollection.cpp \
NativeFormats/fbreader/src/library/Book.cpp
NativeFormats/fbreader/src/library/Author.cpp \
NativeFormats/fbreader/src/library/Book.cpp \
NativeFormats/fbreader/src/library/Comparators.cpp \
NativeFormats/fbreader/src/library/Tag.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/NativeFormats/util \

View file

@ -0,0 +1,68 @@
/*
* Copyright (C) 2009-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.
*/
#include <ZLStringUtil.h>
#include <ZLUnicodeUtil.h>
#include "Author.h"
std::set<shared_ptr<Author>,AuthorComparator> Author::ourAuthorSet;
shared_ptr<Author> Author::getAuthor(const std::string &name, const std::string &sortKey) {
std::string strippedName = name;
ZLStringUtil::stripWhiteSpaces(strippedName);
if (strippedName.empty()) {
return 0;
}
std::string strippedKey = sortKey;
ZLStringUtil::stripWhiteSpaces(strippedKey);
if (strippedKey.empty()) {
const size_t index = strippedName.find(',');
if (index != std::string::npos) {
strippedKey = strippedName.substr(0, index);
ZLStringUtil::stripWhiteSpaces(strippedKey);
}
}
if (strippedKey.empty()) {
size_t index = strippedName.rfind(' ');
if (index == std::string::npos) {
strippedKey = strippedName;
} else {
strippedKey = strippedName.substr(index + 1);
const size_t size = strippedName.size();
while (index < size && strippedName[index] == ' ') {
--index;
}
strippedName = strippedName.substr(0, index + 1) + ' ' + strippedKey;
}
}
shared_ptr<Author> author =
new Author(strippedName, ZLUnicodeUtil::toLower(strippedKey));
std::set<shared_ptr<Author>,AuthorComparator>::const_iterator it =
ourAuthorSet.find(author);
if (it != ourAuthorSet.end()) {
return *it;
} else {
ourAuthorSet.insert(author);
return author;
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (C) 2009-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.
*/
#include "Book.h"
#include "Author.h"
#include "Tag.h"
bool BookComparator::operator() (
const shared_ptr<Book> book0,
const shared_ptr<Book> book1
) const {
const std::string &seriesTitle0 = book0->seriesTitle();
const std::string &seriesTitle1 = book1->seriesTitle();
int comp = seriesTitle0.compare(seriesTitle1);
if (comp == 0) {
if (!seriesTitle0.empty()) {
comp = book0->indexInSeries() - book1->indexInSeries();
if (comp != 0) {
return comp < 0;
}
}
return book0->title() < book1->title();
}
if (seriesTitle0.empty()) {
return book0->title() < seriesTitle1;
}
if (seriesTitle1.empty()) {
return seriesTitle0 <= book1->title();
}
return comp < 0;
}
bool BookByFileNameComparator::operator() (
const shared_ptr<Book> book0,
const shared_ptr<Book> book1
) const {
return book0->file() < book1->file();
}
bool AuthorComparator::operator() (
const shared_ptr<Author> author0,
const shared_ptr<Author> author1
) const {
if (author0.isNull()) {
return !author1.isNull();
}
if (author1.isNull()) {
return false;
}
const int comp = author0->sortKey().compare(author1->sortKey());
return comp != 0 ? comp < 0 : author0->name() < author1->name();
}
bool TagComparator::operator() (
shared_ptr<Tag> tag0,
shared_ptr<Tag> tag1
) const {
if (tag0.isNull()) {
return !tag1.isNull();
}
if (tag1.isNull()) {
return false;
}
size_t level0 = tag0->level();
size_t level1 = tag1->level();
if (level0 > level1) {
for (; level0 > level1; --level0) {
tag0 = tag0->parent();
}
if (tag0 == tag1) {
return false;
}
} else if (level0 < level1) {
for (; level0 < level1; --level1) {
tag1 = tag1->parent();
}
if (tag0 == tag1) {
return true;
}
}
while (tag0->parent() != tag1->parent()) {
tag0 = tag0->parent();
tag1 = tag1->parent();
}
return tag0->name() < tag1->name();
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (C) 2009-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.
*/
#include <set>
#include <algorithm>
#include <AndroidUtil.h>
#include <ZLStringUtil.h>
#include "Tag.h"
TagList Tag::ourRootTags;
std::map <int,shared_ptr<Tag> > Tag::ourTagsById;
const std::string Tag::DELIMITER = "/";
shared_ptr<Tag> Tag::getTag(const std::string &name, shared_ptr<Tag> parent, int tagId) {
if (name.empty()) {
return 0;
}
TagList &tags = parent.isNull() ? ourRootTags : parent->myChildren;
for (TagList::const_iterator it = tags.begin(); it != tags.end(); ++it) {
if ((*it)->name() == name) {
return *it;
}
}
shared_ptr<Tag> t = new Tag(name, parent, tagId);
tags.push_back(t);
if (tagId > 0) {
ourTagsById[tagId] = t;
}
return t;
}
shared_ptr<Tag> Tag::getTagByFullName(const std::string &fullName) {
std::string tag = fullName;
ZLStringUtil::stripWhiteSpaces(tag);
size_t index = tag.rfind(DELIMITER);
if (index == std::string::npos) {
return getTag(tag);
} else {
std::string lastName = tag.substr(index + 1);
ZLStringUtil::stripWhiteSpaces(lastName);
return getTag(lastName, getTagByFullName(tag.substr(0, index)));
}
}
shared_ptr<Tag> Tag::getTagById(int tagId) {
std::map<int,shared_ptr<Tag> >::const_iterator it = ourTagsById.find(tagId);
return it != ourTagsById.end() ? it->second : 0;
}
shared_ptr<Tag> Tag::cloneSubTag(shared_ptr<Tag> tag, shared_ptr<Tag> oldparent, shared_ptr<Tag> newparent) {
std::vector<std::string> levels;
while (tag != oldparent) {
levels.push_back(tag->name());
tag = tag->parent();
if (tag.isNull()) {
return 0;
}
}
if (levels.empty()) {
return 0;
}
shared_ptr<Tag> res = newparent;
while (!levels.empty()) {
res = getTag(levels.back(), res);
levels.pop_back();
}
return res;
}
void Tag::collectAncestors(shared_ptr<Tag> tag, TagList &parents) {
for (; !tag.isNull(); tag = tag->parent()) {
parents.push_back(tag);
}
std::reverse(parents.begin(), parents.end());
}
void Tag::collectTagNames(std::vector<std::string> &tags) {
std::set<std::string> tagsSet;
TagList stack(ourRootTags);
while (!stack.empty()) {
shared_ptr<Tag> tag = stack.back();
stack.pop_back();
tagsSet.insert(tag->fullName());
stack.insert(stack.end(), tag->myChildren.begin(), tag->myChildren.end());
}
tags.insert(tags.end(), tagsSet.begin(), tagsSet.end());
}
Tag::Tag(const std::string &name, shared_ptr<Tag> parent, int tagId) : myName(name), myParent(parent), myLevel(parent.isNull() ? 0 : parent->level() + 1), myTagId(tagId), myJavaTag(0) {
}
Tag::~Tag() {
JNIEnv *env = AndroidUtil::getEnv();
env->DeleteGlobalRef(myJavaTag);
}
const std::string &Tag::fullName() const {
if (myParent.isNull()) {
return myName;
}
if (myFullName.empty()) {
myFullName = myParent->fullName() + DELIMITER + myName;
}
return myFullName;
}
jobject Tag::javaTag(JNIEnv *env) const {
if (myJavaTag != 0) {
return myJavaTag;
}
jobject parentTag = 0;
if (!myParent.isNull()) {
parentTag = myParent->javaTag(env);
}
jobject javaName = env->NewStringUTF(myName.c_str());
jclass cls = env->FindClass(AndroidUtil::Class_Tag);
jobject tag = env->CallStaticObjectMethod(cls, AndroidUtil::SMID_Tag_getTag, parentTag, javaName);
myJavaTag = env->NewGlobalRef(tag);
env->DeleteLocalRef(tag);
env->DeleteLocalRef(cls);
env->DeleteLocalRef(javaName);
return myJavaTag;
}
bool Tag::isAncestorOf(shared_ptr<Tag> tag) const {
if (tag->level() <= level()) {
return false;
}
while (tag->level() > level()) {
tag = tag->parent();
}
return &*tag == this;
}
void Tag::setTagId(shared_ptr<Tag> tag, int tagId) {
if (tag.isNull() || tag->myTagId != 0) {
return;
}
tag->myTagId = tagId;
ourTagsById[tagId] = tag;
}

View file

@ -23,11 +23,64 @@ JavaVM *AndroidUtil::ourJavaVM = 0;
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_ZLFile = "org/geometerplus/zlibrary/core/filesystem/ZLFile";
const char * const AndroidUtil::Class_Book = "org/geometerplus/fbreader/library/Book";
const char * const AndroidUtil::Class_Tag = "org/geometerplus/fbreader/library/Tag";
jmethodID AndroidUtil::SMID_PluginCollection_Instance;
jmethodID AndroidUtil::MID_ZLFile_getPath;
jfieldID AndroidUtil::FID_Book_File;
jfieldID AndroidUtil::FID_Book_Title;
jfieldID AndroidUtil::FID_Book_Language;
jfieldID AndroidUtil::FID_Book_Encoding;
jmethodID AndroidUtil::SMID_Tag_getTag;
JNIEnv *AndroidUtil::getEnv() {
JNIEnv *env;
ourJavaVM->GetEnv((void **)&env, JNI_VERSION_1_2);
return env;
}
#define CHECK_NULL(value) if ((value) == 0) { return false; }
bool AndroidUtil::init(JavaVM* jvm) {
ourJavaVM = jvm;
JNIEnv *env = getEnv();
jclass cls;
CHECK_NULL( cls = env->FindClass(Class_ZLFile) );
CHECK_NULL( MID_ZLFile_getPath = env->GetMethodID(cls, "getPath", "()Ljava/lang/String;") );
env->DeleteLocalRef(cls);
CHECK_NULL( cls = env->FindClass(Class_Book) );
CHECK_NULL( FID_Book_File = env->GetFieldID(cls, "File", "Lorg/geometerplus/zlibrary/core/filesystem/ZLFile;") );
CHECK_NULL( FID_Book_Title = env->GetFieldID(cls, "myTitle", "Ljava/lang/String;") );
CHECK_NULL( FID_Book_Language = env->GetFieldID(cls, "myLanguage", "Ljava/lang/String;") );
CHECK_NULL( FID_Book_Encoding = env->GetFieldID(cls, "myEncoding", "Ljava/lang/String;") );
env->DeleteLocalRef(cls);
CHECK_NULL( cls = env->FindClass(Class_Tag) );
CHECK_NULL( SMID_Tag_getTag = env->GetStaticMethodID(cls, "getTag", "(Lorg/geometerplus/fbreader/library/Tag;Ljava/lang/String;)Lorg/geometerplus/fbreader/library/Tag;") );
env->DeleteLocalRef(cls);
}
bool AndroidUtil::extractJavaString(JNIEnv *env, jstring from, std::string &to) {
if (from == 0) {
return false;
}
const char *data = env->GetStringUTFChars(from, 0);
to.assign(data);
env->ReleaseStringUTFChars(from, data);
return true;
}
jstring AndroidUtil::createJavaString(JNIEnv* env, const std::string &str) {
if (str.empty()) {
return 0;
}
return env->NewStringUTF(str.c_str());
}

View file

@ -22,19 +22,37 @@
#include <jni.h>
#include <string>
class AndroidUtil {
private:
static JavaVM *ourJavaVM;
public:
static const char * const Class_ZLFile;
static const char * const Class_NativeFormatPlugin;
static const char * const Class_PluginCollection;
static const char * const Class_Book;
static const char * const Class_Tag;
static jmethodID MID_ZLFile_getPath;
static jmethodID SMID_PluginCollection_Instance;
static jfieldID FID_Book_File;
static jfieldID FID_Book_Title;
static jfieldID FID_Book_Language;
static jfieldID FID_Book_Encoding;
static jmethodID SMID_Tag_getTag;
public:
static bool init(JavaVM* jvm);
static JNIEnv *getEnv();
static bool extractJavaString(JNIEnv *env, jstring from, std::string &to);
static jstring createJavaString(JNIEnv* env, const std::string &str);
};
#endif /* __ANDROIDUTIL_H__ */