/*
*******************************************************************************
* 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


