Second (and last) part of fixing #7226:
* fix most obvious problems in parseQuotedChars() * drop separate HashMapCatalog in tools-folder, which isn't much different from the original one (we now just use that one instead) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40527 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8a990d5228
commit
efccf04aaf
@ -11,6 +11,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the standard implementation of a localization catalog, using a hash
|
* 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
|
* 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;
|
unsigned long h = startValue;
|
||||||
for ( ; *s; ++s)
|
for ( ; *s; ++s)
|
||||||
h = 5 * h + *s;
|
h = 5 * h + *s;
|
||||||
@ -97,7 +101,7 @@ uint32 CatKey::HashFun(const char* s, int startValue) {
|
|||||||
return size_t(h);
|
return size_t(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (end CatKey)
|
|
||||||
// BHashMapCatalog
|
// BHashMapCatalog
|
||||||
|
|
||||||
|
|
||||||
@ -143,15 +147,17 @@ BHashMapCatalog::GetString(const CatKey& key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static status_t
|
||||||
parseQuotedChars(BString& stringToParse)
|
parseQuotedChars(BString& stringToParse)
|
||||||
{
|
{
|
||||||
char* in = stringToParse.LockBuffer(0);
|
char* in = stringToParse.LockBuffer(0);
|
||||||
|
if (in == NULL)
|
||||||
|
return B_ERROR;
|
||||||
char* out = in;
|
char* out = in;
|
||||||
int newLength = 0;
|
int newLength = 0;
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
|
|
||||||
while (*in != 0 || quoted) {
|
while (*in != 0) {
|
||||||
if (quoted) {
|
if (quoted) {
|
||||||
if (*in == 'n')
|
if (*in == 'n')
|
||||||
*out = '\n';
|
*out = '\n';
|
||||||
@ -160,17 +166,19 @@ parseQuotedChars(BString& stringToParse)
|
|||||||
else if (*in == '"')
|
else if (*in == '"')
|
||||||
*out = '"';
|
*out = '"';
|
||||||
else if (*in == 'x') {
|
else if (*in == 'x') {
|
||||||
|
if (in[1] == '\0' || in[2] == '\0')
|
||||||
|
break;
|
||||||
// Parse the 2-digit hex integer that follows
|
// Parse the 2-digit hex integer that follows
|
||||||
char tmp[3];
|
char tmp[3];
|
||||||
tmp[0] = *(in+1);
|
tmp[0] = in[1];
|
||||||
tmp[1] = *(in+2);
|
tmp[1] = in[2];
|
||||||
tmp[2] = '\0';
|
tmp[2] = '\0';
|
||||||
unsigned int hexchar = strtoul(tmp, NULL, 16);
|
unsigned int hexchar = strtoul(tmp, NULL, 16);
|
||||||
*out = hexchar;
|
*out = hexchar;
|
||||||
// skip the number
|
// skip the number
|
||||||
in += 2;
|
in += 2;
|
||||||
} else {
|
} else {
|
||||||
// dump quote from unknown quoting-sequence:
|
// drop quote from unknown quoting-sequence:
|
||||||
*out = *in ;
|
*out = *in ;
|
||||||
}
|
}
|
||||||
quoted = false;
|
quoted = false;
|
||||||
@ -187,7 +195,9 @@ parseQuotedChars(BString& stringToParse)
|
|||||||
in++;
|
in++;
|
||||||
}
|
}
|
||||||
*out = '\0';
|
*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 stringCopy(string);
|
||||||
BString translatedCopy(translated);
|
BString translatedCopy(translated);
|
||||||
parseQuotedChars(stringCopy);
|
status_t result = parseQuotedChars(stringCopy);
|
||||||
parseQuotedChars(translatedCopy);
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
if ((result = parseQuotedChars(translatedCopy)) != B_OK)
|
||||||
|
return result;
|
||||||
CatKey key(stringCopy.String(), context, comment);
|
CatKey key(stringCopy.String(), context, comment);
|
||||||
fCatMap.Put(key, translatedCopy.String());
|
return fCatMap.Put(key, translatedCopy.String());
|
||||||
// overwrite existing element
|
// overwrite existing element
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -210,11 +222,12 @@ status_t
|
|||||||
BHashMapCatalog::SetString(int32 id, const char *translated)
|
BHashMapCatalog::SetString(int32 id, const char *translated)
|
||||||
{
|
{
|
||||||
BString translatedCopy(translated);
|
BString translatedCopy(translated);
|
||||||
parseQuotedChars(translatedCopy);
|
status_t result = parseQuotedChars(translatedCopy);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
CatKey key(id);
|
CatKey key(id);
|
||||||
fCatMap.Put(key, translatedCopy.String());
|
return fCatMap.Put(key, translatedCopy.String());
|
||||||
// overwrite existing element
|
// overwrite existing element
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,10 +235,11 @@ status_t
|
|||||||
BHashMapCatalog::SetString(const CatKey& key, const char *translated)
|
BHashMapCatalog::SetString(const CatKey& key, const char *translated)
|
||||||
{
|
{
|
||||||
BString translatedCopy(translated);
|
BString translatedCopy(translated);
|
||||||
parseQuotedChars(translatedCopy);
|
status_t result = parseQuotedChars(translatedCopy);
|
||||||
fCatMap.Put(key, translatedCopy.String());
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
return fCatMap.Put(key, translatedCopy.String());
|
||||||
// overwrite existing element
|
// overwrite existing element
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -260,3 +274,6 @@ BHashMapCatalog::UpdateFingerprint()
|
|||||||
{
|
{
|
||||||
fFingerprint = ComputeFingerprint();
|
fFingerprint = ComputeFingerprint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
@ -1,263 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009, Adrien Destugues, pulkomandy@gmail.com. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <HashMapCatalog.h>
|
|
||||||
|
|
||||||
#include <ByteOrder.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
@ -4,6 +4,7 @@ UsePublicHeaders locale ;
|
|||||||
UsePrivateHeaders locale ;
|
UsePrivateHeaders locale ;
|
||||||
UsePrivateHeaders shared ;
|
UsePrivateHeaders shared ;
|
||||||
|
|
||||||
|
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits locale ] ;
|
||||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
||||||
|
|
||||||
local localetools =
|
local localetools =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user