scuffed-code/icu4c/source/i18n/tcoldata.cpp
Vladimir Weinstein 9398f17d9d ICU-96 support for collation data
X-SVN-Rev: 2897
2000-11-09 21:58:19 +00:00

324 lines
9.7 KiB
C++

/*
*******************************************************************************
* Copyright (C) 1997-1999, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
//===============================================================================
//
// File tcoldata.cpp
//
// Internal file. Implements TableCollationData, an internal class which is shared
// by TableCollation objects, and which contains all the invariant (and large)
// pieces of data. Once created, TableCollationData objects do not change.
//
// Created by: Alan Liu
//
// Modification History:
//
// Date Name Description
// 2/5/97 aliu Creation.
// 3/5/97 aliu Don't stream rule table in or out.
//===============================================================================
#include "ucmp32.h"
#include "tcoldata.h"
#include "tables.h"
#include "mutex.h"
#include "unicode/tblcoll.h"
//===============================================================================
CollationCache TableCollationData::fgCache;
//===============================================================================
TableCollationData::TableCollationData()
: isFrenchSec(FALSE),
maxSecOrder(0),
maxTerOrder(0),
fBogus(FALSE),
isRuleTableLoaded(FALSE)
{
mapping = 0;
contractTable = 0;
expandTable = 0;
}
TableCollationData::~TableCollationData()
{
ucmp32_close(mapping);
delete contractTable;
delete expandTable;
}
UBool
TableCollationData::isBogus() const
{
return fBogus;
}
void TableCollationData::streamIn(FileStream* is)
{
if (!T_FileStream_error(is))
{
// Stream in large objects
char isNull;
T_FileStream_read(is, &isNull, sizeof(isNull));
if (isNull)
{
ucmp32_close(mapping);
mapping = 0;
}
else
{
// Slight ugliness: We are a friend of TableCollation solely so
// we can access the constant UNMAPPED here. In fact, this code
// path shouldn't really happen, because mapping should always != 0.
// if (mapping == 0) mapping = ucmp32_open(RuleBasedCollator::UNMAPPED);
if (mapping->fBogus ){
fBogus = TRUE;
return;
}
ucmp32_streamIn(mapping, is);
if (mapping->fBogus) {
fBogus = TRUE;
ucmp32_close(mapping);
mapping = 0;
return;
}
}
T_FileStream_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete contractTable;
contractTable = 0;
}
else
{
if (contractTable == 0) contractTable = new VectorOfPToContractTable;
if (contractTable->isBogus()) {
fBogus = TRUE;
return;
}
contractTable->streamIn(is);
if (contractTable->isBogus()) {
fBogus = TRUE;
ucmp32_close(mapping);
mapping = 0;
delete contractTable;
contractTable = 0;
return;
}
}
T_FileStream_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete expandTable;
expandTable = 0;
}
else
{
if (expandTable == 0) expandTable = new VectorOfPToExpandTable;
if (expandTable->isBogus()) {
fBogus = TRUE;
return;
}
expandTable->streamIn(is);
if (expandTable->isBogus()) {
fBogus = TRUE;
ucmp32_close(mapping);
mapping = 0;
delete contractTable;
contractTable = 0;
delete expandTable;
expandTable = 0;
return;
}
}
// We don't stream in or out the rule table, in order to keep
// binary files small. We reconstruct rules on the fly.
ruleTable.remove();
isRuleTableLoaded = FALSE;
// Stream in the small objects
T_FileStream_read(is, &isFrenchSec, sizeof(isFrenchSec));
T_FileStream_read(is, &maxSecOrder, sizeof(maxSecOrder));
T_FileStream_read(is, &maxTerOrder, sizeof(maxTerOrder));
}
}
void TableCollationData::streamOut(FileStream* os) const
{
if (!T_FileStream_error(os))
{
// Stream out the large objects
char isNull;
isNull = (mapping == 0);
T_FileStream_write(os, &isNull, sizeof(isNull));
if (!isNull) ucmp32_streamOut(mapping, os);
isNull = (contractTable == 0);
T_FileStream_write(os, &isNull, sizeof(isNull));
if (!isNull) contractTable->streamOut(os);
isNull = (expandTable == 0);
T_FileStream_write(os, &isNull, sizeof(isNull));
if (!isNull) expandTable->streamOut(os);
// We don't stream out the rule table, in order to keep
// binary files small. We reconstruct rules on the fly.
// Stream out the small objects
T_FileStream_write(os, &isFrenchSec, sizeof(isFrenchSec));
T_FileStream_write(os, &maxSecOrder, sizeof(maxSecOrder));
T_FileStream_write(os, &maxTerOrder, sizeof(maxTerOrder));
}
}
void TableCollationData::streamIn(UMemoryStream* is, UErrorCode &status)
{
if (!uprv_mstrm_error(is) && U_SUCCESS(status))
{
// Stream in large objects
char isNull;
uprv_mstrm_read(is, &isNull, sizeof(isNull));
if (isNull)
{
ucmp32_close(mapping);
mapping = 0;
}
else
{
// Slight ugliness: We are a friend of TableCollation solely so
// we can access the constant UNMAPPED here. In fact, this code
// path shouldn't really happen, because mapping should always != 0.
if (mapping == 0) mapping = ucmp32_openAlias(NULL, NULL, 0);
if (mapping->fBogus ){
fBogus = TRUE;
return;
}
int32_t len = 0;
const uint8_t *map = uprv_mstrm_getCurrentBuffer(is, &len);
ucmp32_initFromData(mapping, &map, &status);
uprv_mstrm_jump(is, map);
// ucmp32_streamMemIn(mapping, is);
if (mapping->fBogus) {
fBogus = TRUE;
ucmp32_close(mapping);
mapping = 0;
status = U_MISSING_RESOURCE_ERROR;
return;
}
}
uprv_mstrm_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete contractTable;
contractTable = 0;
}
else
{
if (contractTable == 0) contractTable = new VectorOfPToContractTable;
if (contractTable->isBogus()) {
fBogus = TRUE;
return;
}
contractTable->streamIn(is);
if (contractTable->isBogus()) {
fBogus = TRUE;
ucmp32_close(mapping);
mapping = 0;
delete contractTable;
contractTable = 0;
return;
}
}
uprv_mstrm_read(is, &isNull, sizeof(isNull));
if (isNull)
{
delete expandTable;
expandTable = 0;
}
else
{
if (expandTable == 0) expandTable = new VectorOfPToExpandTable;
if (expandTable->isBogus()) {
fBogus = TRUE;
return;
}
expandTable->streamIn(is);
if (expandTable->isBogus()) {
fBogus = TRUE;
ucmp32_close(mapping);
mapping = 0;
delete contractTable;
contractTable = 0;
delete expandTable;
expandTable = 0;
return;
}
}
// We don't stream in or out the rule table, in order to keep
// binary files small. We reconstruct rules on the fly.
ruleTable.remove();
isRuleTableLoaded = FALSE;
// Stream in the small objects
uprv_mstrm_read(is, &isFrenchSec, sizeof(isFrenchSec));
uprv_mstrm_read(is, &maxSecOrder, sizeof(maxSecOrder));
uprv_mstrm_read(is, &maxTerOrder, sizeof(maxTerOrder));
}
}
void TableCollationData::streamOut(UMemoryStream* os) const
{
if (!uprv_mstrm_error(os))
{
// Stream out the large objects
char isNull;
isNull = (mapping == 0);
uprv_mstrm_write(os, (uint8_t *)&isNull, sizeof(isNull));
// if (!isNull) ucmp32_streamMemOut(mapping, os);
if (!isNull) ucmp32_flattenMem(mapping, os);
isNull = (contractTable == 0);
uprv_mstrm_write(os, (uint8_t *)&isNull, sizeof(isNull));
if (!isNull) contractTable->streamOut(os);
isNull = (expandTable == 0);
uprv_mstrm_write(os, (uint8_t *)&isNull, sizeof(isNull));
if (!isNull) expandTable->streamOut(os);
// We don't stream out the rule table, in order to keep
// binary files small. We reconstruct rules on the fly.
// Stream out the small objects
uprv_mstrm_write(os, (uint8_t *)&isFrenchSec, sizeof(isFrenchSec));
uprv_mstrm_write(os, (uint8_t *)&maxSecOrder, sizeof(maxSecOrder));
uprv_mstrm_write(os, (uint8_t *)&maxTerOrder, sizeof(maxTerOrder));
}
}
void TableCollationData::addToCache(const UnicodeString& key, TableCollationData* collation)
{
Mutex lock;
fgCache.Add(key, collation);
}
TableCollationData* TableCollationData::findInCache(const UnicodeString& key)
{
Mutex lock;
return fgCache.Find(key);
}
//eof