/***************************************************************************
 *
 * locale_combine.cpp - definition of std::locale::combine() and related
 *                      member functions
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  License); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 1994-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC

#include <rw/_defs.h>

#include <locale.h>
#include <stdio.h>
#include <string.h>   // for memxxx() and strxxx() functions

#include <loc/_locale.h>

#include "access.h"
#include "locale_body.h"
#include "setlocale.h"


_RWSTD_NAMESPACE (__rw) {


// constructs a new locale name from two locale names, combining
// all but the category given by `cat' from `name_1' and the rest
// from `name_2'
static void
__rw_combine_names (__rw_chararray &locname,
                    const char *name_1, const char *name_2, int cat)
{
    _RWSTD_ASSERT (0 != name_1);
    _RWSTD_ASSERT (0 != name_2);

    // `cat' must be a locale::category (and not a LC_XXX value)
    _RWSTD_ASSERT (__rw_locale::_C_check_category (cat));

    for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) {
        const char *nxt1 = strchr (name_1, *_RWSTD_CAT_SEP);
        const char *nxt2 = strchr (name_2, *_RWSTD_CAT_SEP);

        if (!nxt1 || !*nxt1)
            nxt1 = name_1 + strlen (name_1);

        if (!nxt2 || !*nxt2)
            nxt2 = name_2 + strlen (name_2);

        // convert a LC_XXX constant to a locale::category value
        const int c = __rw_locale::_C_LC2category (__rw_cats [i].cat);

        const char    *from;   // copy from where
        _RWSTD_SIZE_T  len;    // this many chars

        if (cat & c) {   // category comes from `other'
            from = name_2;
            len  = nxt2 - name_2;
        }
        else {   // category comes from `one'
            from = name_1;
            len  = nxt1 - name_1;
        }

        if (locname.size ())
            locname.append (_RWSTD_CAT_SEP, 1);

        locname.append (from, len);

        // advance to the next category name in each name
        if (*nxt1)
            name_1 = nxt1 + 1;

        if (*nxt2)
            name_2 = nxt2 + 1;
    }
}


void __rw_locale::
_C_construct (const __rw_locale &rhs, const __rw_facet *pfacet)
{
    // called from ctor only, members are not initialized
    _C_ref = 1;

    // copy standard facets from other locale
#if defined (__i386__) || !defined (__GNUG__) || __GNUG__ < 3

    memcpy (_C_std_facets, rhs._C_std_facets,
            _C_n_std_facets * sizeof *_C_std_facets);

#else   // !i86  || !gcc 3.x

    // Working around a bug (most probably) identical to the one described 
    // and fixed in __rw_locale::__rw_locale, but related to the use of
    // memcpy.

    for(_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; i++)
        _C_std_facets [i] = rhs._C_std_facets [i];

#endif   // i86/gcc 3.x

    _RWSTD_ASSERT (!pfacet || pfacet->_C_pid);

    // get facet's index into one of the facet arrays
    _RWSTD_SIZE_T inx = pfacet
        ? rhs._C_get_facet_inx (*pfacet->_C_pid) : (_RWSTD_SIZE_T)(-1);

    // extend size if facet isn't installed in `rhs'
    _C_n_usr_facets =   rhs._C_n_usr_facets
                      + (inx > rhs._C_n_usr_facets + _C_n_std_facets);

    // allocate a buffer for user facets if necesary
    _C_usr_facets = _C_n_usr_facets ? new __rw_facet* [_C_n_usr_facets] : 0;

    // copy facets from other locale
    memcpy (_C_usr_facets, rhs._C_usr_facets,
            rhs._C_n_usr_facets * sizeof *_C_usr_facets);

    _RWSTD_ASSERT (rhs._C_name);

    _C_name = 0;

    // copy facet bits from `rhs' and adjust below as necessary
    _C_std_facet_bits    = rhs._C_std_facet_bits;
    _C_byname_facet_bits = rhs._C_byname_facet_bits;

    if (pfacet) {
        __rw_facet* const pf = _RWSTD_CONST_CAST (__rw_facet*, pfacet);
        // overwrite an existing pointer or add a new one
        if (inx < _C_n_std_facets) {
            _C_std_facets [inx] = pf;

            const _RWSTD_SIZE_T facet_bit = 1UL << inx;

            // set or clear a corresponding bit based on whether
            // the facet is one of the standard facets or not
            // (user-defined objects even if they are of standard
            // facet types, are not considered standard facets)
            if (pf->_C_type > 0)
                _C_std_facet_bits |= facet_bit;
            else
                _C_std_facet_bits &= ~facet_bit;

            // ditto for named facet bitmap
            if (pf->_C_type & 1)   // even types are _byname
                _C_byname_facet_bits &= ~facet_bit;
            else
                _C_byname_facet_bits |= facet_bit;

            // construct a new name
            // _C_name =
            //     _C_make_name (_C_namebuf, sizeof _C_namebuf, rhs, *pfacet);
        }
        else if ((_RWSTD_SIZE_T)(-1) == inx)
            _C_usr_facets [_C_n_usr_facets - 1] = pf;
        else
            _C_usr_facets [inx - _C_n_std_facets] = pf;
    }

    if (!_C_name) {
        // simply copy name from `rhs'
        const _RWSTD_SIZE_T size = strlen (rhs._C_name) + 1;
        char* const name = size <= sizeof _C_namebuf
            ? _C_namebuf : new char [size];

        memcpy (name, rhs._C_name, size);
        _C_name = name;
    }

    // increment reference counts for facets (including the newly added one)
    for (inx = 0; inx != _C_n_std_facets; ++inx) {
        if (_C_std_facets [inx])
            _RWSTD_ATOMIC_PREINCREMENT (_C_std_facets [inx]->_C_ref,
                                        _C_std_facets [inx]->_C_mutex);
    }
    
    for (inx = 0; inx != _C_n_usr_facets; ++inx) {
        _RWSTD_ATOMIC_PREINCREMENT (_C_usr_facets [inx]->_C_ref,
                                    _C_usr_facets [inx]->_C_mutex);
    }
}


void __rw_locale::
_C_construct (const __rw_locale &one, const __rw_locale &other, int cat)
{
    // category must be valid at this point (checked by caller)
    _RWSTD_ASSERT (_C_check_category (cat));

    // called from ctor only, members are not initialized
    _C_ref = 1;

    // size is the same as that of `one'
    _C_n_usr_facets = one._C_n_usr_facets;

    // allocate only if internal buffer is insufficient
    _C_usr_facets = _C_n_usr_facets ?  new __rw_facet* [_C_n_usr_facets] : 0;

    // copy standard facets to `one' from `other'
    memcpy (_C_std_facets, one._C_std_facets,
            _C_n_std_facets * sizeof *_C_std_facets);

    // copy user-defined facets (if any)
    memcpy (_C_usr_facets, one._C_usr_facets,
            _C_n_usr_facets * sizeof *_C_usr_facets);

    // compute and assign facet bitmaps
    const int bits = _C_LC2facet_bits (cat);

    _C_std_facet_bits    =   one._C_std_facet_bits & ~bits
                           | other._C_std_facet_bits & bits;

    _C_byname_facet_bits =   one._C_byname_facet_bits & ~bits
                           | other._C_byname_facet_bits & bits;

    for (_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; ++i) {

        // each facet is stored at an index equal to its (id - 1)
        // convert an LC_XXX constant to a locale::category value
        const int c = _C_LC2category (__rw_get_cat (int (i) + 1));

        if (cat & c) {
            // assign/overwrite corresponding facets
            _C_std_facets [i] = other._C_std_facets [i];
        }

        if (_C_std_facets [i]) {
            // bump up the facet's reference count of *this' facet
            _RWSTD_ATOMIC_PREINCREMENT (_C_std_facets [i]->_C_ref,
                                        _C_std_facets [i]->_C_mutex);
        }
    }

    // increment the ref count of user-defined facets (if any)
    for (_RWSTD_SIZE_T j = 0; j != _C_n_usr_facets; ++j) {

        _RWSTD_ASSERT (_C_usr_facets [j]);

        _RWSTD_ATOMIC_PREINCREMENT (_C_usr_facets [j]->_C_ref,
                                    _C_usr_facets [j]->_C_mutex);
    }

    __rw_chararray locname;

    __rw_combine_names (locname, one._C_name, other._C_name, cat);

    if (locname.size () >= one._C_namebuf_size)
        _C_name = locname.release ();
    else {
        _C_name = _C_namebuf;
        memcpy (_C_namebuf, locname.data (), locname.size () + 1);
    }
}


_RW::__rw_locale* __rw_locale::
_C_combine (const __rw_facet *pfacet) const
{
    _RWSTD_ASSERT (pfacet);

    // template ctor: locale::locale (const locale&, Facet*)
    // with `facet' being installed (e.g., adding or replacing
    // an existing one)

    // verify that Facet::id has been initialized
    _RWSTD_ASSERT (pfacet->_C_pid);
    _RWSTD_ASSERT (*pfacet->_C_pid);

    // get the locale name ("C" if it's NUL)
    const char* const one_locname = _C_name ? _C_name : "C";

    // get the name of the locale `*pfacet' belongs to
    const char* const facet_locname =
        pfacet->_C_name ? pfacet->_C_name : "C";

    // get the locale::category that `*pfacet' belongs to
    const int facet_cat =
        _C_LC2category (__rw_get_cat (int (*pfacet->_C_pid)));

    bool managed = false;

    if (pfacet->_C_type && !_C_n_usr_facets) {

        // facet is one of the (perhaps byname) standard facets

        // compute the number of the bit in _C_std_facet_bits or
        //_C_byname_facet_bits corresponding to the facet being
        // used (i.e., `*pfacet')
        const _RWSTD_SIZE_T facet_bit =
            (_RWSTD_SIZE_T)1U << (*pfacet->_C_pid - 1U);

        // a locale object is globally managed if all its facets are objects
        // of standard facet types (ordinary or byname) that were constructed
        // by the library and within each locale category all facets belong
        // to the same facet
        // managed locales have names that completely describe their facets
        // and from which they can be unambiguously and fully constructed
        //
        // note that in the code snippet below, x0 is not a managed locale
        // (its name is "*"), but y0 is a managed locale (on SunOS, its name
        // is "/de_DE/de_DE/de_DE/de_DE/de_DE/en_US"); x1 is the same as x0
        // and y1 is the same as de:
        //
        //   locale de ("de_DE");
        //   locale en ("en_US");
        //   locale x0 = de.combine<messages<char> >(en);
        //   locale y0 = x0.combine<messages<wchar_t> >(en);
        //   locale x1 = y0.combine<messages<wchar_t> >(de);
        //   locale y1 = x1.combine<messages<char> >(de);
        //   assert (de == y1);
        //   assert (x0 == x1);

        if (__rw_locale::_C_all == (_C_std_facet_bits | facet_bit)) {

            // compute the bitmask corresponding to all the facets in
            // the same category as the one to which `*pfacet' belongs
            const int cat_bits = _C_LC2facet_bits (facet_cat);

            // get the index into the _C_std_facets array for `pfacet'
            const _RWSTD_SIZE_T facet_inx =
                _C_get_facet_inx (*pfacet->_C_pid);

            managed = true;

            // iterate over all facets that belong the same category
            // as `*pfacet' and compare the name of each with the name
            // of `*pfacet' to determine if they all have the same name
            // _byname facets that are not installed yet (i.e., whose
            // pointers are 0 come from a locale whose name is given
            // by the name of the whole locale
            for (_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; ++i) {

                // skip facets from other categories
                if (!((1 << i) & cat_bits))
                    continue;

                // skip the facet being replaced
                if (facet_inx == i)
                    continue;

                const char* const ones_facet_locname =
                      _C_std_facets [i] ? _C_std_facets [i]->_C_name
                    ? _C_std_facets [i]->_C_name : "C" : one_locname;

                if (strcmp (facet_locname, ones_facet_locname)) {
                    managed = false;
                    break;
                }
            }
        }
    }

    __rw_locale *plocale;

    if (managed) {

        __rw_chararray locname;
        __rw_combine_names (locname, one_locname, facet_locname, facet_cat);

        plocale = __rw_locale::_C_manage (0, locname.data ());

        _RWSTD_ASSERT (0 != plocale);
        _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none));
    }
    else {
        plocale = new __rw_locale (*this, pfacet);
        
        _RWSTD_ASSERT (0 != plocale);
        _RWSTD_ASSERT (!plocale->_C_is_managed (_STD::locale::none));
    }

    return plocale;
}


__rw_locale* __rw_locale::
_C_combine (const __rw_locale &other, int cat)
{
    // convert a possible LC_XXX constant to a locale::category value
    cat = _C_LC2category (cat);

    // verify that the category argument is valid
    if (!_C_check_category (cat))
        return 0;


    // combining ctor: locale (const locale&, const locale&, cat)

    if (this == &other || _STD::locale::none == cat) {
        // same as copy ctor (copying all facets from `*this')
        // body may or may not be globally managed
        _RWSTD_ATOMIC_PREINCREMENT (_C_ref, false);

        return this;
    }

#if 0   // disabled

    // 22.1.1.2, p14: only facets that implement categories in `cat' are
    // to be copied from `other', i.e., not necessarily user-defined facets

    if (_RWSTD_LC_ALL == cat || _STD::locale::all == cat) {
        // same as copy ctor (copying all facets from `other')
        // body may or may not be globally managed
        _RWSTD_ATOMIC_PREINCREMENT (other._C_ref, false);
        return &other;
    }

#endif   // 0/1

    if (   _C_is_managed (_STD::locale::all & ~cat)
        && other._C_is_managed (cat)) {
        
        // determine new locale name from `*this' and `other's, taking all of
        // this's category names except for those given by `cat', which come
        // from `other'

        const char *name_1 = _C_name;
        const char *name_2 = other._C_name;

        if (0 == strcmp (name_1, name_2)) {
            // if locale names are the same, return a globally managed body
            __rw_locale* const plocale = __rw_locale::_C_manage (0, name_1);

            _RWSTD_ASSERT (0 != plocale);
            _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none));

            return plocale;
        }

        __rw_chararray locname;

        // compose the new name
        __rw_combine_names (locname, name_1, name_2, cat);

        // return a globally managed body
        __rw_locale* const plocale =
            __rw_locale::_C_manage (0, locname.data ());

        _RWSTD_ASSERT (0 != plocale);
        _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none));

        return plocale;
    }

    // one or both locales are not globally managed (one or more of
    // their facets are of use-defined types, possibly derived from
    // the standard facets), and thus the combined locale cannot be
    // globally managed either
    __rw_locale *plocale = new __rw_locale (*this, other, cat);

    _RWSTD_ASSERT (!plocale->_C_is_managed (_STD::locale::none));

    return plocale;
}


/* static */ __rw_locale* __rw_locale::
_C_get_body (__rw_locale      *one,
             __rw_locale      *other,
             const char       *locname,
             int               cat,
             const __rw_facet *pfacet)
{
    __rw_chararray realname;

    // see if `locname' contains embedded "LC_XXX=..." sequences
    if (locname && !strncmp (locname, "LC_", 3)) {

        // convert a combined locale name (consisting of a sequence
        // of `sep'-separated LC_XXX=<name> substrings) to a normalized
        // form in the expected (internal) format and order

        const char *pcatnames [__rw_n_cats] = { 0 };

        // try the libc "native" separator first, semicolon next
        const char *sep = strchr (locname, *_RWSTD_CAT_SEP);
        if (!sep)
            sep = ";";

        for (const char *s = locname; *s; ) {

            const char *next = strchr (s, *sep);
            if (!next)
                next = s + strlen (s);

            const char* const endcat = strchr (s, '=');
            if (!endcat)
                return 0;   // error: missing `=' after LC_XXX

            // go through the LC_XXX category names, trying to find
            // a match; if found, remember its position (duplicates
            // are not allowed)

            for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) {
                if (!strncmp (__rw_cats [i].name, s, endcat - s)) {
                    if (pcatnames [i])
                        return 0;    // error: duplicate LC_XXX

                    pcatnames [i] = endcat + 1;
                    break;
                }
            }

            s = *next ? next + 1 : next;
        }

        // compose a normalized locale name out of category names
        _RWSTD_SIZE_T size = 0;
        for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) {

            if (!pcatnames [i]) {
                // use "C" for missing LC_XXX values
                pcatnames [i] = "C";
            }

            const char *endcat = strchr (pcatnames [i], *sep);

            if (!endcat)
                endcat = pcatnames [i] + strlen (pcatnames [i]);

            const _RWSTD_SIZE_T catsize = endcat - pcatnames [i];

            // append name followed by the libc "native" separator
            realname.append (pcatnames [i], endcat - pcatnames [i]);
            realname.append (_RWSTD_CAT_SEP, 1);

            size += catsize;
        }

        locname = realname.data ();
    }
    else if (locname && *locname == *_RWSTD_CAT_SEP) {
        // advance past the leading category separator if present
        ++locname;
    }

    if (!one && !other && !locname && _STD::locale::none == cat && !pfacet) {
        // implements default ctor: locale::locale () throw ()
        __rw_locale* const global = __rw_locale::_C_manage (0, 0);

        _RWSTD_ASSERT (0 != global);

        return global;
    }

    if (one && !other && !locname && _STD::locale::none == cat && !pfacet) {
        // copy ctor: locale::locale (const locale&)
        // or combining ctor: locale::locale (const locale&, Facet*)
        // (in the second case with Facet* being 0)
        // body may or may not be globally managed
        // or locale::operator=(const locale&)
        _RWSTD_ATOMIC_PREINCREMENT (one->_C_ref, false);
        return one;
    }

    if (!one && !other && locname && _STD::locale::none == cat && !pfacet) {
        // ctor: locale::locale (const char*)
        // if successful, body is globally managed
         __rw_locale* const plocale = __rw_locale::_C_manage (0, locname);

         _RWSTD_ASSERT (!plocale || plocale->_C_is_managed (_STD::locale::none));

        return plocale;
    }

    if (one && !other && !locname && _STD::locale::none == cat && pfacet) {
        // template ctor: locale::locale (const locale&, Facet*)
        // with `pfacet' being installed (e.g., adding or replacing
        // an existing one)
        // template <class Facet> locale::combine(const locale&) is
        // trivially implemented inline in terms of the template ctor
        __rw_locale* const plocale = one->_C_combine (pfacet);

        _RWSTD_ASSERT (0 != plocale);

        return plocale;
    }

    if (one && !other && locname && !pfacet) {
        // combining ctor: locale (const locale&, const char*, category)

        // construct a temporary locale from locale name `locname'
        const _STD::locale tmp (locname);

        // construct a locale combined from `one' and the temporary
        __rw_locale* const plocale = one->_C_combine (*tmp._C_body, cat);

        return plocale;
    }

    if (one && other && !locname && !pfacet) {
        // combining ctor: locale (const locale&, const locale&, category)
        return one->_C_combine (*other, cat);
    }

    _RWSTD_ASSERT (!"logic error: bad combination of arguments");

    return 0;
}

}   // namespace __rw


_RWSTD_NAMESPACE (std) {


// outlined to hide implementation details
locale::
locale (const char *locname)
{
    // verify 22.1.1.2, p7: `locname' must not be null
    _RWSTD_REQUIRES (locname,
                     (_RWSTD_ERROR_LOCALE_BAD_NAME,
                      _RWSTD_FUNC ("locale::locale (const char*)"), "(null)"));

    _C_body = _RW::__rw_locale::_C_get_body (0, 0, locname, none, 0);

    // verify 22.1.1.2, p7: `locname' must be valid
    _RWSTD_REQUIRES (_C_body,
                     (_RWSTD_ERROR_LOCALE_BAD_NAME,
                      _RWSTD_FUNC ("locale::locale (const char*)"), locname));
}


// outlined to hide implementation details
locale::
locale (const locale &rhs, const char *locname, category cat)
{
    // verify 22.1.1.2, p10: `locname' must not ne null
    _RWSTD_REQUIRES (locname,
                     (_RWSTD_ERROR_LOCALE_BAD_NAME,
                      _RWSTD_FUNC ("locale::locale (const locale&, "
                                   "const char*, category)"), "(null"));

    _C_body = _RW::__rw_locale::_C_get_body (rhs._C_body, 0, locname, cat, 0);

    // verify 22.1.1.2, p10: `locname' must be valid
    _RWSTD_REQUIRES (_C_body,
                     (_RWSTD_ERROR_LOCALE_BAD_NAME,
                      _RWSTD_FUNC ("locale::locale (const locale&, "
                                   "const char*, category)"), locname));
}


// outlined to hide implementation details
locale::
locale (const locale &one, const locale &other, category cat)
    : _C_body (_RW::__rw_locale::_C_get_body (one._C_body, other._C_body,
                                              0, cat, 0))
{
    // verify 22.1.1.2, p14 (missing requirement): category must be valid
    _RWSTD_REQUIRES (_C_body,
                     (_RWSTD_ERROR_LOCALE_BAD_CAT,
                      _RWSTD_FUNC ("locale::locale (const locale&, "
                                   "const locale&, category)"), cat));
}


// outlined to hide implementation details
/* private */ locale::
locale (_RW::__rw_locale &rhs, const facet *pfacet)
    : _C_body (_RW::__rw_locale::_C_get_body (&rhs, 0, 0, none, pfacet))
{
    // empty
}


const locale::facet* locale::
_C_get_facet (const id &fid) const
{
    // initialize id if not yet initialized
    if (!fid._C_id)
        fid._C_init ();

    // properly initialized facet id's are non-zero
    _RWSTD_ASSERT (0 != fid._C_id);

    _RWSTD_ASSERT (0 != _C_body);

    // find the index at which the facet is stored in one of the facet arrays
    const _RWSTD_SIZE_T inx = _C_body->_C_get_facet_inx (fid._C_id);
    if ((_RWSTD_SIZE_T)(-1) == inx)
        return 0;

    const locale::facet* const pfacet = inx < _RW::__rw_locale::_C_n_std_facets
        ? _C_body->_C_std_facets [inx]
        : _C_body->_C_usr_facets [inx - _RW::__rw_locale::_C_n_std_facets];

    if (pfacet) {
        // facet id must have been initialized to point
        // to the numeric member of the static Facet::id
        _RWSTD_ASSERT (pfacet->_C_pid);

        // make sure the static Facet::id matches its (non-static) id member
        _RWSTD_ASSERT (*pfacet->_C_pid == fid._C_id);
    }

    return pfacet;
}


}   // namespace std
