/***************************************************************************
 *
 * facet.cpp
 *
 * $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 2001-2006 Rogue Wave Software, Inc.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC

#include <rw/_defs.h>

#include <locale.h>   // for LC_XXX costants
#include <stdlib.h>   // for bsearch(), getenv(), qsort()
#include <string.h>   // for memcpy(), strlen()

#include <iosfwd>         // for mbstate_t

#include "access.h"
#include "mman.h"

#include <loc/_facet.h>
#include <loc/_locale.h>
#include <loc/_localedef.h>

#include <rw/_mutex.h>

#include "locale_body.h"
#include "podarray.h"    // for __rw_chararry


_RWSTD_NAMESPACE (__rw) { 

// computes LC_XXX category from a numeric facet id, returns the
// LC_XXX category for standard facets, LC_ALL for all others
int __rw_get_cat (int) _THROWS (());

// retrieves the literal name for a given category value
static inline 
const char* __rw_get_cat_name (int category) _THROWS (())
{
    // FIXME: merge this struct and lookup with __rw_cats in rw_locale.cpp
    // maps LC_XXX category values to their names
    static const struct {
        int         cat;           // LC_XXX category
        const char *name;          // string corresponding to LC_XXX
    } cats [] = {
        { _RWSTD_LC_COLLATE,  "LC_COLLATE"},
        { _RWSTD_LC_CTYPE,    "LC_CTYPE"},
        { _RWSTD_LC_MONETARY, "LC_MONETARY"},
        { _RWSTD_LC_NUMERIC,  "LC_NUMERIC"},
        { _RWSTD_LC_TIME,     "LC_TIME"}

#ifdef _RWSTD_LC_MESSAGES
        , { _RWSTD_LC_MESSAGES, "LC_MESSAGES" }
#endif   // _RWSTD_LC_MESSAGES
    };

    // find facet's category name
    for (size_t i = 0; i != sizeof cats / sizeof *cats; ++i) {
        if (category == cats [i].cat)
            return cats [i].name;
    }

    return 0;
}


int __rw_facet::_C_opts = 0

#ifndef _RWSTD_NO_INITIAL_CAT_SEP
    | __rw_facet::_C_prepend_cat_sep
#endif   // _RWSTD_NO_INITIAL_CAT_SEP

#ifndef _RWSTD_NO_CAT_NAMES
    | __rw_facet::_C_use_cat_names
#endif   // _RWSTD_NO_CAT_NAMES

#ifndef _RWSTD_NO_CONDENSED_NAME
    | __rw_facet::_C_condensed_name
#endif   // _RWSTD_NO_CONDENSED_NAME

    | 0;


__rw_facet::__rw_facet (size_t __ref /* = 0 */) _THROWS (())
    : _C_name (0), _C_buf (0), _C_impdata (0), _C_impsize (0),
    _C_type (_C_unknown), _C_ref (__ref), _C_pid (0 /* invalid */)
{
}


__rw_facet::~__rw_facet () // nothrow
{
    _RWSTD_ASSERT ((!_C_name && !_C_buf) || (_C_name && _C_buf));

    static const char destroyed[] = "*** destroyed facet ***";

    // (try to) detect double deletion
    _RWSTD_ASSERT (destroyed != _C_name);
    _RWSTD_ASSERT (_C_invalid != _C_type);

    // mark invalid
    _C_type = _C_invalid;

    if (_C_name != _C_buf)
        //  MSVC requires that we cast away const before calling delete.
        delete[] _RWSTD_CONST_CAST (char*, _C_name);

    // mark destroyed
    _C_name = destroyed;

    // unmap only if both `impadata' and `impsize' are valid
    // (derived facets may want to set `impdata' to their own,
    // not necessarily memory mapped, data w/o setting `impsize'
    // to something meaningful
    if (size_t (-1) == _C_impsize)
        ::operator delete (_RWSTD_CONST_CAST (void*, _C_impdata));
    else if (_C_impdata && _C_impsize) 
        __rw_release_facet_data (_C_impdata, _C_impsize);
}


void __rw_facet::_C_set_name (const char *name, char *buf, size_t size)
{
    _RWSTD_ASSERT (0 != name);
    _RWSTD_ASSERT (0 != buf || 0 == size);

    // expected to be called only from the ctor
    _RWSTD_ASSERT (0 == _C_name);
    _RWSTD_ASSERT (0 == _C_buf);

    size_t len = strlen (name) + 1;

    char *tmp = len <= size ? buf : new char [len];

    ::memcpy (tmp, name, len);
    _C_name = tmp;
    _C_buf  = buf;
}


const void* __rw_facet::_C_get_data ()
{
    // check initialization
    if (_C_impsize)
        return _C_impdata;

    // `pid' may be 0 if the facet has not been obtained
    // by a call to use_facet (but instead constructed
    // and used directly without having been installed
    // in a locale object); in that case, locale database
    // mapping for the facet is not available
    if (!_C_pid)
        return _C_impdata;

    // lock the object
    _RWSTD_MT_GUARD (&_C_mutex);

    // check again for initialization
    if (_C_impsize)
        return _C_impdata;

    __rw_chararray locname (_C_name && _C_name [0] ? _C_name : "C");

    // implementation database mapping data
    const void* pdata = 0;
    size_t sz = 0;

    _RWSTD_ASSERT (0 != _C_pid);
    const int cat = __rw_get_cat (int (*_C_pid));

    // use facet's id and name to determine whether the type of the facet is
    // codecvt_byname<wchar_t, char, mbstate_t> (_C_type is not sufficiently
    // reliable since it is set to _C_unknown for all facet objects contructed
    // outside of the library)
    const bool is_wcodecvt_byname =
        _C_wcodecvt_byname == __rw_locale::_C_get_facet_type (*this);

    // map the database; first try with the full name (including
    // any modifiers) since such a database may actually exist
    pdata = __rw_get_facet_data (cat, sz, locname.data ());
    if (!pdata) {

        // the mapping failure can be attributed to the use of a
        // special name, eg <locale>.<codeset>@UCS-4 which calls
        // for the stripping of the special suffix
        _RW::__rw_chararray strip_name;

        const char*  pstr = strstr (locname.data (), "@UCS");
        const size_t plen = size_t (pstr - locname.data ());

        if (pstr && !pstr [4]) {

            // @UCS suffix is recognized irrespective of the size of wchar_t,
            strip_name.append (locname.data (), plen);
            pdata = __rw_get_facet_data (cat, sz, strip_name.data ());
        }
        else if (   pstr && pstr [4] == '-' && !pstr [6]
                 && (   ('4' == pstr [5] && sizeof (wchar_t) == 4)
                     || ('2' == pstr [5] && sizeof (wchar_t) == 2))) {

            // @UCS-4 is only recognized where sizeof (wchar_t) == 4
            // @UCS-2 is only recognized where sizeof (wchar_t) == 2
            // no other modifier is recognized
            strip_name.append (locname.data (), plen);
            pdata = __rw_get_facet_data (cat, sz, strip_name.data ());
        }

        // if the type of the facet is codecvt_byname<wchar_t,char,mbstate_t>
        // then the name is possibly in the format codeset | codeset@modifier
        if (!pdata && is_wcodecvt_byname) {

            pstr = pstr ? strip_name.data () : locname.data ();
            pdata = __rw_get_facet_data (cat, sz, 0, pstr /* codeset */);
        }
        else
            pstr = 0;

        // this is the definitive result for facets other than 
        // codecvt_byname<wchar_t, char, mbstate_t>
        if (!pdata) {
            _RWSTD_ASSERT (0 == _C_impdata);

            // set `impsize' to non-zero value to avoid subsequent
            // attempts at reinitialization
            _C_impsize = size_t (-1);
            return 0;
        }

        if (!is_wcodecvt_byname || (pstr && pdata)) {
            _C_impdata = pdata; 
            _C_impsize = sz;
            return _C_impdata;
        }
    }
    else if (!is_wcodecvt_byname) {
        _C_impdata = pdata;
        _C_impsize = sz;
        return _C_impdata;
    }

    // for codecvt_byname facet map the database indicated by 
    // codeset_name offset in LC_CTYPE database
    const _RW::__rw_ctype_t* pctype  = 
        _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*, pdata);
 
    _RWSTD_ASSERT (0 != pctype);

    // the facet name may be an ordinary filename or a (relative
    // or absolute) pathname; unless it's the former, prepend
    // the name of the directory containing the facet to the
    // name of the codeset before trying to map it
    __rw_chararray codeset_fname;
    const char* codeset = pctype->codeset_name ();

    const char* const slash = strrchr (locname.data (), _RWSTD_PATH_SEP);
    if (slash) {
        const size_t dirlen = size_t (slash - locname.data ()) + 1;

        codeset_fname.assign (locname.data (), dirlen);
        codeset_fname.append (codeset);
        codeset = codeset_fname.data ();
    }

    // map the codecvt database
    _C_impdata = __rw_get_facet_data (cat, _C_impsize, 0, codeset);
    
    // unmap the LC_CTYPE database
    __rw_munmap (pdata, sz);

    return _C_impdata;
}


extern "C" {

// compares two facets, returns 0 if equal, -1 if less, +1 otherwise
static int cmpfacets (const void *pv1, const void *pv2) _THROWS (())
{
    _RWSTD_ASSERT (0 != pv1);
    _RWSTD_ASSERT (0 != pv2);

    const __rw_facet* const pf1 =
        *_RWSTD_STATIC_CAST (const __rw_facet* const*, pv1);
    const __rw_facet* const pf2 =
        *_RWSTD_STATIC_CAST (const __rw_facet* const*, pv2);

    if (__rw_access::_C_get_type(*pf1) == __rw_access::_C_get_type(*pf2)) {
        return ::strcmp (__rw_access::_C_get_name(*pf1) ? 
                         __rw_access::_C_get_name(*pf1) : "C",
                         __rw_access::_C_get_name(*pf2) ? 
                         __rw_access::_C_get_name(*pf2) : "C");
    }

    return __rw_access::_C_get_type(*pf2) - __rw_access::_C_get_type(*pf1);
}


struct __rw_facet_info
{
    const char                *_C_name;
    __rw_facet::_C_facet_type  _C_type;
};

// compares a key to a facet, returns 0 if equal, -1 if less, +1 otherwise
static int cmpfacet (const void *pv1, const void *pv2) _THROWS (())
{
    _RWSTD_ASSERT (0 != pv1);
    _RWSTD_ASSERT (0 != pv2);

    const __rw_facet_info* const pinfo =
        _RWSTD_STATIC_CAST (const __rw_facet_info*, pv1);

    const __rw_facet* const pfacet =
        *_RWSTD_STATIC_CAST (const __rw_facet* const*, pv2);

    if (pinfo->_C_type == __rw_access::_C_get_type(*pfacet)) {
        return ::strcmp (pinfo->_C_name  ? pinfo->_C_name   : "C",
                         __rw_access::_C_get_name(*pfacet) ? 
                         __rw_access::_C_get_name(*pfacet) : "C");
    }

    return __rw_access::_C_get_type(*pfacet) - pinfo->_C_type;
}

}   // extern "C"


/* static */ __rw_facet*
__rw_facet::_C_manage (__rw_facet            *pfacet,
                       _C_facet_type          type,
                       const char            *name,
                       __rw_facet::_C_ctor_t *ctor)
{
    // a per-process array of facet pointers sufficiently large
    // to hold (pointers to) all standard facets for 8 locales
    static __rw_facet*  std_facet_buf [__rw_facet::_C_last_type * 8];
    static __rw_facet** std_facets = std_facet_buf;
    static size_t n_std_facets = 0;
    static size_t std_facet_bufsize =
        sizeof std_facet_buf / sizeof *std_facet_buf;

    // acquire lock
    _RWSTD_MT_STATIC_GUARD (_RW::__rw_facet);

    if (pfacet) {
        // remove facet from the facet repository (if it is found) and
        // destroy it (ordinary unnamed standard facets are never destroyed)

        if (!name) {
            // find facet by its name
            name = __rw_locale::_C_get_cat_name (*pfacet);
        }

        _RWSTD_ASSERT (0 != n_std_facets);

        const void *pf =
            ::bsearch (&pfacet, std_facets, n_std_facets,
                       sizeof pfacet, &cmpfacets);
        if (pf) {

            const size_t inx =
                  _RWSTD_STATIC_CAST (const __rw_facet* const*, pf)
                - _RWSTD_CONST_CAST (const __rw_facet* const*, std_facets);

            pfacet = std_facets [inx];

            if (0 == __rw_locale::_C_remove_ref (*pfacet)) {

                static const size_t bufsize =
                    sizeof std_facet_buf / sizeof *std_facet_buf;

                --n_std_facets;

                if (n_std_facets < bufsize / 2 && std_facets != std_facet_buf) {

                    _RWSTD_ASSERT (inx < bufsize);

                    // when the number of facets in the dynamically allocated
                    // repository drops below half the capacity of the
                    // statically allocated buffer, copy facets from the
                    // former into the latter and deallocate the former
                    ::memcpy (std_facet_buf, std_facets,
                              inx * sizeof (*std_facets));

                    ::memcpy (std_facet_buf + inx,
                              std_facets + inx + 1,
                              (n_std_facets - inx)
                              * sizeof (*std_facets));

                    delete[] std_facets;
                    std_facets = std_facet_buf;
                }
                else {

                    // move facet pointers back
                    ::memmove (std_facets + inx,
                               std_facets + inx + 1,
                               (n_std_facets - inx)
                               * sizeof (*std_facets));
                }

                // delete facet unless it's one of the ordinary (unnamed)
                // standard factes which are statically allocated
                if (pfacet->_C_name)
                    delete pfacet;
            }
        }
        else {

            // facet is an ordinary (unnamed) standard facet
            const size_t ref = __rw_locale::_C_remove_ref (*pfacet);
            _RWSTD_ASSERT (ref + 1U != 0);
            _RWSTD_UNUSED (ref);
        }

        pfacet = 0;
    }
    else {

        // find facet in the repository or construct it if not found

        const __rw_facet_info info = { name, type };

        const void *pcf = ::bsearch (&info, std_facets, n_std_facets,
                                     sizeof pfacet, &cmpfacet);

        if (pcf) {
            // facet already exists in the repository, bump up its ref count

            void *pf = _RWSTD_CONST_CAST (void*, pcf);
            pfacet = *_RWSTD_STATIC_CAST (__rw_facet**, pf);

            _RWSTD_ASSERT (0 != pfacet);

            __rw_locale::_C_add_ref (*pfacet);
        }
        else {

            if (n_std_facets == std_facet_bufsize) {

                // reallocate buffer of facet pointers
                __rw_facet **tmp = new __rw_facet* [n_std_facets * 2];

                ::memcpy (tmp, std_facets, n_std_facets * sizeof *tmp);

                if (std_facets != std_facet_buf)
                    delete[] std_facets;

                std_facets         = tmp;
                std_facet_bufsize *= 2;
            }

            // construct a facet with the initial reference count of 1
            // if no such facet exists yet or bump up the facet's ref
            // count by 1 if it does

            _RWSTD_ASSERT (0 != ctor);

            pfacet = ctor (1, type & 1 ? 0 : name);

            _RWSTD_ASSERT (0 != pfacet);

            // set the facet's numeric id
            *__rw_access::_C_get_pid (*pfacet) =
                _RWSTD_STATIC_CAST (size_t, (type + 1) / 2);

            if (__rw_access::_C_get_type (*pfacet) != type) {
                // set the type of the facet if not already set
                __rw_access::_C_get_type (*pfacet) = type;
            }

            if (__rw_access::_C_get_ref (*pfacet) != 1) {
                // set the refcount of the facet if 0

                // the refcount is set during construction which occurs
                // at most once in a program, but may decrease to 0 if
                // all locales containing that facet are destroyed

                _RWSTD_ASSERT (0 == __rw_access::_C_get_ref (*pfacet));

                __rw_access::_C_get_ref (*pfacet) = 1;
            }

            // add facet pointer to the end of the repository
            std_facets [n_std_facets++] = pfacet;

            // sort facet pointers for fast access
            ::qsort (std_facets, n_std_facets, sizeof pfacet, &cmpfacets);
            
        }
    }

    return pfacet;
}


const void* __rw_get_facet_data (int cat, size_t &impsize, 
                                 const char* name, const char* encoding) 
{
    if (__rw_facet::_C_use_libc == (__rw_facet::_C_opts & 
                                    (__rw_facet::_C_use_libc | 
                                     __rw_facet::_C_use_libstd))) {
        // fail but allow further calls to this function
        return 0;
    }

    __rw_chararray  pathname;
    const char     *path;

    // null name means C locale
    const char *locname = name ? name : "C";

    if ('/' == *locname) {
        // facet name is an absolute pathname to a locale/category database
        path = locname;
    }
    else {

#ifndef _RWSTD_LOCALE_ROOT_ENVVAR
#  define _RWSTD_LOCALE_ROOT_ENVVAR "RWSTD_LOCALE_ROOT"
#endif

        // look up the value of the environment variable
        const char *root = getenv (_RWSTD_LOCALE_ROOT_ENVVAR);

        // use the cwd if none given
        if (!root || !*root)
            root = "./";

        // compose the pathname of the locale/category database
        pathname.append (root);
        if (pathname.data () [pathname.size () - 1] != '/')
            pathname.append ("/", 1);

        // the database name for the facet will hold either the
        // name of the category (ie LC_CTYPE, etc.) or the name
        // of the encoding (codecvt database)
        const char* db;

        if (encoding)
            db = encoding;
        else {
            // only append the locname if we are not going to be 
            // appending an encoding
            pathname.append (locname).append ("/", 1);
            db = __rw_get_cat_name (cat);
        }
        if (!db)
            return 0;

        // append database name to the end of the pathname
        // to form a complete name of the locale/category database
        pathname.append (db);
        path = pathname.data ();
    }

    // map the database
    return __rw_mmap (path, &impsize);
}

// Its counterpart - does the database unmapping
void __rw_release_facet_data (const void* pv, size_t sz) _THROWS (())
{
    __rw_munmap (pv, sz);
}


// standard facet id's (i.e., those instantiated and installed
// by the library are in the range [1, __rw_facet::_C_last_type]
// all others (i.e., id's of all user-defined facet types or
// specializations of standard facets on user-defined types)
// are in the range (__rw_facet::_C_last_type, ...)
static size_t __rw_id_gen = __rw_facet::_C_last_type + 1;


size_t __rw_facet_id::_C_init () const _THROWS (())
{
    // return immediately if already initialized
    if (_C_id)
        return _C_id;

    // atomically increment id generator
    // the above initialization is already guarded and the initialization
    // of standard facets has a chance of completing at the step above

    // generate a unique id
    const size_t new_id = _RWSTD_ATOMIC_PREINCREMENT (__rw_id_gen, false);

#ifndef _RWSTD_NO_MUTABLE

    _C_id = new_id;

#else   // if defined (_RWSTD_NO_MUTABLE)

    _RWSTD_CONST_CAST (__rw_facet_id*, this)->_C_id = new_id;

#endif   // _RWSTD_NO_MUTABLE

    return _C_id;
}

}   // namespace __rw
