* Fix collator text

* Fix archiving/unarchiving to provide at least a valid object. However, ICU archiving system doesn't look like it's working well.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37784 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adrien Destugues
2010-07-28 13:16:11 +00:00
parent 110649a1a4
commit 2c6ebfaaea
3 changed files with 45 additions and 29 deletions
+2
View File
@@ -14,6 +14,7 @@
namespace icu_44 { namespace icu_44 {
class Collator; class Collator;
class RuleBasedCollator;
}; };
@@ -65,6 +66,7 @@ class BCollator : public BArchivable {
private: private:
icu_44::Collator* fICUCollator; icu_44::Collator* fICUCollator;
icu_44::RuleBasedCollator* fFallbackICUCollator;
int8 fStrength; int8 fStrength;
bool fIgnorePunctuation; bool fIgnorePunctuation;
}; };
+37 -13
View File
@@ -15,10 +15,12 @@
#include <ctype.h> #include <ctype.h>
#include <unicode/coll.h> #include <unicode/coll.h>
#include <unicode/tblcoll.h>
BCollator::BCollator() BCollator::BCollator()
: :
fFallbackICUCollator(NULL),
fStrength(B_COLLATE_PRIMARY), fStrength(B_COLLATE_PRIMARY),
fIgnorePunctuation(true) fIgnorePunctuation(true)
{ {
@@ -34,6 +36,7 @@ BCollator::BCollator()
BCollator::BCollator(const char *locale, int8 strength, BCollator::BCollator(const char *locale, int8 strength,
bool ignorePunctuation) bool ignorePunctuation)
: :
fFallbackICUCollator(NULL),
fStrength(strength), fStrength(strength),
fIgnorePunctuation(ignorePunctuation) fIgnorePunctuation(ignorePunctuation)
{ {
@@ -45,9 +48,9 @@ BCollator::BCollator(const char *locale, int8 strength,
BCollator::BCollator(BMessage *archive) BCollator::BCollator(BMessage *archive)
: BArchivable(archive), : BArchivable(archive),
fICUCollator(NULL), fICUCollator(NULL),
fFallbackICUCollator(NULL),
fIgnorePunctuation(true) fIgnorePunctuation(true)
{ {
#if HAIKU_TARGET_PLATFORM_HAIKU
int32 data; int32 data;
if (archive->FindInt32("loc:strength", &data) == B_OK) if (archive->FindInt32("loc:strength", &data) == B_OK)
fStrength = (uint8)data; fStrength = (uint8)data;
@@ -57,14 +60,28 @@ BCollator::BCollator(BMessage *archive)
if (archive->FindBool("loc:punctuation", &fIgnorePunctuation) != B_OK) if (archive->FindBool("loc:punctuation", &fIgnorePunctuation) != B_OK)
fIgnorePunctuation = true; fIgnorePunctuation = true;
// TODO : ICU collator ? or just store the locale name ? UErrorCode error = U_ZERO_ERROR;
#endif fFallbackICUCollator = static_cast<RuleBasedCollator*>
(Collator::createInstance(error));
ssize_t size;
const void* buffer = NULL;
if (archive->FindData("loc:collator", B_RAW_TYPE, &buffer, &size) == B_OK) {
fICUCollator = new RuleBasedCollator((const uint8_t*)buffer, (int)size,
fFallbackICUCollator, error);
if (fICUCollator == NULL) {
fICUCollator = fFallbackICUCollator;
// Unarchiving failed, so we revert to the fallback collator
}
}
} }
BCollator::~BCollator() BCollator::~BCollator()
{ {
delete fICUCollator; delete fICUCollator;
fICUCollator = NULL;
delete fFallbackICUCollator;
} }
@@ -169,17 +186,24 @@ BCollator::Archive(BMessage *archive, bool deep) const
if (status == B_OK) if (status == B_OK)
status = archive->AddBool("loc:punctuation", fIgnorePunctuation); status = archive->AddBool("loc:punctuation", fIgnorePunctuation);
/* UErrorCode error = U_ZERO_ERROR;
BMessage collatorArchive; int size = static_cast<RuleBasedCollator*>(fICUCollator)->cloneBinary(NULL,
if (status == B_OK && deep 0, error);
&& typeid(*fCollator) != typeid(BCollatorAddOn) // This WILL fail with U_BUFFER_OVERFLOW_ERROR. But we get the needed
// only archive subclasses from BCollatorAddOn // size.
&& (status = fCollator->Archive(&collatorArchive, true)) == B_OK) error = U_ZERO_ERROR;
status = archive->AddMessage("loc:collator", &collatorArchive); uint8_t* buffer = (uint8_t*)malloc(size);
*/ static_cast<RuleBasedCollator*>(fICUCollator)->cloneBinary(buffer, size,
//TODO : archive fICUCollator error);
return status; if (status == B_OK && error == U_ZERO_ERROR)
status = archive->AddData("loc:collator", B_RAW_TYPE, buffer, size);
delete buffer;
if (error == U_ZERO_ERROR)
return status;
else
return B_ERROR;
} }
+6 -16
View File
@@ -156,20 +156,7 @@ main(int argc, char **argv)
// load the collator add-on if necessary // load the collator add-on if necessary
if (addon != NULL) { if (addon != NULL) {
image_id image = load_add_on(addon); gCollator = new BCollator(addon, strength, true);
if (image < B_OK)
fprintf(stderr, "could not load add-on at \"%s\": %s.\n", addon, strerror(image));
BCollatorAddOn *(*instantiate)(void);
if (get_image_symbol(image, "instantiate_collator",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate) == B_OK) {
BCollatorAddOn *collator = instantiate();
if (collator != NULL)
gCollator = new BCollator(collator, strength, true);
} else if (image >= B_OK) {
fprintf(stderr, "could not find instantiate_collator() function in add-on!\n");
unload_add_on(image);
}
} }
if (gCollator == NULL) { if (gCollator == NULL) {
@@ -177,7 +164,7 @@ main(int argc, char **argv)
gCollator = be_locale->Collator(); gCollator = be_locale->Collator();
} }
// test archiving/unarchiving collator printf("test archiving/unarchiving collator\n");
BMessage archive; BMessage archive;
if (gCollator->Archive(&archive, true) != B_OK) if (gCollator->Archive(&archive, true) != B_OK)
@@ -193,7 +180,10 @@ main(int argc, char **argv)
} }
} }
// test the BCollator::Compare() and GetSortKey() methods printf(" Archived content :");
archive.PrintToStream();
printf("test the BCollator::Compare() and GetSortKey() methods\n");
const char *strengthLabels[] = {"primary: ", "secondary:", "tertiary: "}; const char *strengthLabels[] = {"primary: ", "secondary:", "tertiary: "};
uint32 strengths[] = {B_COLLATE_PRIMARY, B_COLLATE_SECONDARY, B_COLLATE_TERTIARY}; uint32 strengths[] = {B_COLLATE_PRIMARY, B_COLLATE_SECONDARY, B_COLLATE_TERTIARY};