diff --git a/src/kits/locale/HashMapCatalog.cpp b/src/kits/locale/HashMapCatalog.cpp index 6eff488d45..c646fc2328 100644 --- a/src/kits/locale/HashMapCatalog.cpp +++ b/src/kits/locale/HashMapCatalog.cpp @@ -11,6 +11,9 @@ #include +namespace BPrivate { + + /* * This is the standard implementation of a localization catalog, using a hash * map. This class is abstract, you need to inherit it and provide methodes for @@ -86,7 +89,8 @@ CatKey::GetStringParts(BString* str, BString* ctx, BString* cmt) const } -uint32 CatKey::HashFun(const char* s, int startValue) { +uint32 +CatKey::HashFun(const char* s, int startValue) { unsigned long h = startValue; for ( ; *s; ++s) h = 5 * h + *s; @@ -97,7 +101,7 @@ uint32 CatKey::HashFun(const char* s, int startValue) { return size_t(h); } -// (end CatKey) + // BHashMapCatalog @@ -143,15 +147,17 @@ BHashMapCatalog::GetString(const CatKey& key) } -void +static status_t parseQuotedChars(BString& stringToParse) { char* in = stringToParse.LockBuffer(0); + if (in == NULL) + return B_ERROR; char* out = in; int newLength = 0; bool quoted = false; - while (*in != 0 || quoted) { + while (*in != 0) { if (quoted) { if (*in == 'n') *out = '\n'; @@ -160,17 +166,19 @@ parseQuotedChars(BString& stringToParse) else if (*in == '"') *out = '"'; else if (*in == 'x') { + if (in[1] == '\0' || in[2] == '\0') + break; // Parse the 2-digit hex integer that follows char tmp[3]; - tmp[0] = *(in+1); - tmp[1] = *(in+2); + tmp[0] = in[1]; + tmp[1] = in[2]; tmp[2] = '\0'; unsigned int hexchar = strtoul(tmp, NULL, 16); *out = hexchar; // skip the number in += 2; } else { - // dump quote from unknown quoting-sequence: + // drop quote from unknown quoting-sequence: *out = *in ; } quoted = false; @@ -187,7 +195,9 @@ parseQuotedChars(BString& stringToParse) in++; } *out = '\0'; - stringToParse.UnlockBuffer(); + stringToParse.UnlockBuffer(newLength); + + return B_OK; } @@ -197,12 +207,14 @@ BHashMapCatalog::SetString(const char *string, const char *translated, { BString stringCopy(string); BString translatedCopy(translated); - parseQuotedChars(stringCopy); - parseQuotedChars(translatedCopy); + status_t result = parseQuotedChars(stringCopy); + if (result != B_OK) + return result; + if ((result = parseQuotedChars(translatedCopy)) != B_OK) + return result; CatKey key(stringCopy.String(), context, comment); - fCatMap.Put(key, translatedCopy.String()); + return fCatMap.Put(key, translatedCopy.String()); // overwrite existing element - return B_OK; } @@ -210,11 +222,12 @@ status_t BHashMapCatalog::SetString(int32 id, const char *translated) { BString translatedCopy(translated); - parseQuotedChars(translatedCopy); + status_t result = parseQuotedChars(translatedCopy); + if (result != B_OK) + return result; CatKey key(id); - fCatMap.Put(key, translatedCopy.String()); + return fCatMap.Put(key, translatedCopy.String()); // overwrite existing element - return B_OK; } @@ -222,10 +235,11 @@ status_t BHashMapCatalog::SetString(const CatKey& key, const char *translated) { BString translatedCopy(translated); - parseQuotedChars(translatedCopy); - fCatMap.Put(key, translatedCopy.String()); + status_t result = parseQuotedChars(translatedCopy); + if (result != B_OK) + return result; + return fCatMap.Put(key, translatedCopy.String()); // overwrite existing element - return B_OK; } @@ -260,3 +274,6 @@ BHashMapCatalog::UpdateFingerprint() { fFingerprint = ComputeFingerprint(); } + + +} // namespace BPrivate diff --git a/src/tools/locale/HashMapCatalog.cpp b/src/tools/locale/HashMapCatalog.cpp deleted file mode 100644 index b59b40f0fb..0000000000 --- a/src/tools/locale/HashMapCatalog.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2009, Adrien Destugues, pulkomandy@gmail.com. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include - -#include - -#include - - -/* - * This is the standard implementation of a localization catalog, using a hash - * map. This class is abstract, you need to inherit it and provide methodes for - * reading and writing the catalog to a file. Classes doing that are - * HashMapCatalog and PlainTextCatalog. - * If you ever need to create a catalog not built around an hash map, inherit - * BCatalogAddOn instead. Note that in this case you will not be able to use our - * development tools anymore. - */ - - -extern "C" uint32 adler32(uint32 adler, const uint8 *buf, uint32 len); - // definition lives in adler32.c - - -CatKey::CatKey(const char *str, const char *ctx, const char *cmt) - : - fString(str), - fContext(ctx), - fComment(cmt), - fFlags(0) -{ - fHashVal = HashFun(fString.String(),0); - fHashVal = HashFun(fContext.String(),fHashVal); - fHashVal = HashFun(fComment.String(),fHashVal); -} - - -CatKey::CatKey(uint32 id) - : - fHashVal(id), - fFlags(0) -{ -} - - -CatKey::CatKey() - : - fHashVal(0), - fFlags(0) -{ -} - - -bool -CatKey::operator== (const CatKey& right) const -{ - // Two keys are equal if their hashval and key (string,context,comment) - // are equal (testing only the hash would not filter out collisions): - return fHashVal == right.fHashVal - && fString == right.fString - && fContext == right.fContext - && fComment == right.fComment; -} - - -bool -CatKey::operator!= (const CatKey& right) const -{ - // Two keys are equal if their hashval and key (string,context,comment) - // are equal (testing only the hash would not filter out collisions): - return fHashVal != right.fHashVal - || fString != right.fString - || fContext != right.fContext - || fComment != right.fComment; -} - - -status_t -CatKey::GetStringParts(BString* str, BString* ctx, BString* cmt) const -{ - if (str) *str = fString; - if (ctx) *ctx = fContext; - if (cmt) *cmt = fComment; - - return B_OK; -} - - -uint32 CatKey::HashFun(const char* s, int startValue) { - unsigned long h = startValue; - for ( ; *s; ++s) - h = 5 * h + *s; - - // Add 1 to differenciate ("ab","cd","ef") from ("abcd","e","f") - h = 5 * h + 1; - - return size_t(h); -} - -// (end CatKey) -// BHashMapCatalog - - -void -BHashMapCatalog::MakeEmpty() -{ - fCatMap.Clear(); -} - - -int32 -BHashMapCatalog::CountItems() const -{ - return fCatMap.Size(); -} - - -const char * -BHashMapCatalog::GetString(const char *string, const char *context, - const char *comment) -{ - CatKey key(string, context, comment); - return GetString(key); -} - - -const char * -BHashMapCatalog::GetString(uint32 id) -{ - CatKey key(id); - return GetString(key); -} - - -const char * -BHashMapCatalog::GetString(const CatKey& key) -{ - BString value = fCatMap.Get(key); - if (value.Length() == 0) - return NULL; - else - return value.String(); -} - - -void -parseQuotedChars(BString& stringToParse) -{ - char* in = stringToParse.LockBuffer(0); - char* out = in; - int newLength = 0; - bool quoted = false; - - while (*in != 0 || quoted) { - if (quoted) { - if (*in == 'n') - *out = '\n'; - else if (*in == 't') - *out = '\t'; - else if (*in == '"') - *out = '"'; - else if (*in == 'x') { - // Parse the 2-digit hex integer that follows - char tmp[3]; - tmp[0] = *(in+1); - tmp[1] = *(in+2); - tmp[2] = '\0'; - unsigned int hexchar = strtoul(tmp, NULL, 16); - *out = hexchar; - // skip the number - in += 2; - } else { - // dump quote from unknown quoting-sequence: - *out = *in ; - } - quoted = false; - out++; - newLength++; - } else { - quoted = (*in == '\\'); - if (!quoted) { - *out = *in; - out++; - newLength++; - } - } - in++; - } - *out = '\0'; - stringToParse.UnlockBuffer(); -} - - -status_t -BHashMapCatalog::SetString(const char *string, const char *translated, - const char *context, const char *comment) -{ - BString stringCopy(string); - BString translatedCopy(translated); - parseQuotedChars(stringCopy); - parseQuotedChars(translatedCopy); - CatKey key(stringCopy.String(), context, comment); - return fCatMap.Put(key, translatedCopy.String()); - // overwrite existing element -} - - -status_t -BHashMapCatalog::SetString(int32 id, const char *translated) -{ - BString translatedCopy(translated); - parseQuotedChars(translatedCopy); - CatKey key(id); - return fCatMap.Put(key, translatedCopy.String()); - // overwrite existing element -} - - -status_t -BHashMapCatalog::SetString(const CatKey& key, const char *translated) -{ - BString translatedCopy(translated); - parseQuotedChars(translatedCopy); - return fCatMap.Put(key, translatedCopy.String()); - // overwrite existing element -} - - -/* - * computes a checksum (we call it fingerprint) on all the catalog-keys. We do - * not include the values, since we want catalogs for different languages of the - * same app to have the same fingerprint, since we use it to separate different - * catalog-versions. We use a simple sum because there is no well known - * checksum algorithm that gives the same result if the string are sorted in the - * wrong order, and this does happen, as an hash map is an unsorted container. - */ -uint32 -BHashMapCatalog::ComputeFingerprint() const -{ - uint32 checksum = 0; - - int32 hash; - CatMap::Iterator iter = fCatMap.GetIterator(); - CatMap::Entry entry; - while (iter.HasNext()) - { - entry = iter.Next(); - hash = entry.key.fHashVal; - checksum += hash; - } - return checksum; -} - - -void -BHashMapCatalog::UpdateFingerprint() -{ - fFingerprint = ComputeFingerprint(); -} diff --git a/src/tools/locale/Jamfile b/src/tools/locale/Jamfile index d3b6c61f07..37ef8daab7 100644 --- a/src/tools/locale/Jamfile +++ b/src/tools/locale/Jamfile @@ -4,6 +4,7 @@ UsePublicHeaders locale ; UsePrivateHeaders locale ; UsePrivateHeaders shared ; +SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits locale ] ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits tracker ] ; local localetools =