/***************************************************************************
 *
 * messages.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 2000-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC
#include <rw/_defs.h>

#include <new>         // for placement new

#include <string.h>    // for memcpy, size_t

#include <loc/_locale.h>
#include <loc/_messages.h>

#include <rw/_mutex.h>

#include "podarray.h"

#if !defined (_RWSTD_NO_NL_TYPES_H) && !defined (_RWSTD_NO_CATOPEN_CATGETS)
#  include <nl_types.h>
#else   // _RWSTD_NO_NL_TYPES_H || _RWSTD_NO_CATOPEN_CATGETS
#  include "catalog.h"
#endif   // !_RWSTD_NO_NL_TYPES_H && !_RWSTD_NO_CATOPEN_CATGETS


#define _RWSTD_BAD_CATD ((nl_catd)-1)


_RWSTD_NAMESPACE (__rw) { 


// Implementation structure private to this module -- __rw_open_cat_data.
// Keeps track of the association between an open message catalog (as
// identified by the nl_catd handle returned by the C library catopen
// function) and the locale specified by the user for character translation
// in the call to messages<_CharT>::open.
// 
// Also used as a parameter to rw_get_static_mutex to ensure uniqueness
// of the mutex object used in sync'ing the threads using __rw_cat...
// (see RWSTD_MT_STATIC_GUARD below)
struct __rw_open_cat_data
{
    nl_catd catd;
    __rw_aligned_buffer<_STD::locale> loc;
};

struct __rw_open_cat_page
{
    static const size_t _C_size = 8;

    __rw_open_cat_page* _C_next; // next page
    __rw_open_cat_data _C_data [_C_size];
};


// manages a global, per-process repository of open catalogs according
// to the following table:

//        cat   _rw_open_cat_data     algorithm
//        -1         0                invalid
//        -1       non-0              append the struct into the repository and 
//                                    return a pointer to a struct containing
//                                    the new catalog and locale
//      > -1       0                  return the a pointer to a struct
//                                    containing the locale associated with
//                                    this catalog
//      > -1     non-0                find the struct containg  the locale and
//                                    catalog in the repository and invalidate
//                                    it.
//                                    Return a pointer to the struct

static __rw_open_cat_data*
__rw_manage_cat_data (int &cat,  __rw_open_cat_data *pcat_data)
{
    // a per-process array of pointers to catalog data structs
    static __rw_open_cat_data* catalog_buf [__rw_open_cat_page::_C_size];
    static __rw_open_cat_data** catalogs = 0;

    // first page of a per-process list of pages of catalog data structs
    static __rw_open_cat_page  catalog_page;

    static size_t n_catalogs      = 0;
    static size_t catalog_bufsize = sizeof catalog_buf / sizeof *catalog_buf;
    static size_t largest_cat     = 0;

    if (!catalogs) {
        
        for (size_t i = 0; i < catalog_bufsize; ++i) {
            catalog_page._C_data [i].catd = _RWSTD_BAD_CATD;
            catalog_buf [i] = &catalog_page._C_data [i];
        }

        catalogs = catalog_buf;
    }

    if (-1 == cat) {
        _RWSTD_ASSERT (0 != pcat_data);

        // append the locale and return a struct with the associated catalog

        if (pcat_data) {
             if (n_catalogs == catalog_bufsize) {

                // allocate new page of catalog data
                __rw_open_cat_page* const page =
                    new __rw_open_cat_page;

                // insert new page into singly-linked page list
                page->_C_next = catalog_page._C_next;
                catalog_page._C_next = page;

                // initialize new page
                for (size_t i = 0; i < __rw_open_cat_page::_C_size; ++i) {
                    page->_C_data [i].catd = _RWSTD_BAD_CATD;
                }

                // rwallocate buffer of catalog data pointers
                __rw_open_cat_data** const data =
                    new __rw_open_cat_data* [n_catalogs + __rw_open_cat_page::_C_size];

                memcpy (data, catalogs, n_catalogs * sizeof *data);
                 
                if (catalogs != catalog_buf)
                    delete[] catalogs;

                catalogs         = data;
                catalog_bufsize += __rw_open_cat_page::_C_size;

                for (size_t i = 0; i < __rw_open_cat_page::_C_size; ++i) {
                    catalogs [n_catalogs + i] = &page->_C_data [i];
                }

                cat = int (n_catalogs);

                catalogs [cat]->catd = pcat_data->catd;
                memcpy (catalogs [cat]->loc._C_store (), 
                        pcat_data->loc._C_store (),
                        sizeof (_STD::locale));

                if (size_t (cat) > largest_cat)
                    largest_cat = size_t (cat);

                ++n_catalogs;
            }
            else {
                // find the first open slot and use it.
                cat = 0;
                while (catalogs [cat]->catd != _RWSTD_BAD_CATD) {
                    ++cat;
                }

                catalogs [cat]->catd = pcat_data->catd;
                memcpy (catalogs [cat]->loc._C_store (),
                        pcat_data->loc._C_store (),
                        sizeof (_STD::locale));

                if (size_t (cat) > largest_cat)
                    largest_cat = size_t (cat);

                ++n_catalogs;
            }
        }
    }
    else {

        if (0 == pcat_data) {
            // find struct and return it
            if (size_t (cat) < catalog_bufsize)
                return catalogs [cat];

            return 0;
        }

        // initialize the struct to an invalid state
        --n_catalogs;
        catalogs [cat]->catd = _RWSTD_BAD_CATD;

        if (size_t (cat) == largest_cat) {

            // find the next smallest valid slot
            largest_cat = 0;

            for (int i = cat; i >= 0; --i) {
                if (catalogs [i]->catd != _RWSTD_BAD_CATD) {
                    largest_cat = size_t (i);
                    break;
                }
            }

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

            if ((largest_cat < bufsize / 2) && (catalogs != catalog_buf)) {
                // when there are no more open catalogs indexed beyond
                // second half of the static pointer repository, copy
                // the open catalog pointers back into the repository.

                catalog_bufsize = bufsize;

                memcpy (catalog_buf, catalogs,
                        catalog_bufsize * sizeof (*catalogs));

                delete[] catalogs;

                catalogs = catalog_buf;

                // remove all pages, they're not in use
                while (catalog_page._C_next)
                {
                    // remove next page from page list
                    __rw_open_cat_page* page = catalog_page._C_next;
                    catalog_page._C_next = page->_C_next;

                    // deallocate that page
                    delete page;
                }
            }
        }
    }

    return pcat_data;
}



// Open a message catalog and assign and return a handle for it.

int __rw_cat_open (const _STD::string &cat_name, const _STD::locale &loc)
{
    _RWSTD_MT_CLASS_GUARD (__rw_open_cat_data);

    const nl_catd catd = catopen (cat_name.c_str (), NL_CAT_LOCALE);
    if (_RWSTD_BAD_CATD == catd)
        return -1;

    __rw_open_cat_data cat_data;

    cat_data.catd = catd;
    new (cat_data.loc._C_store ()) _STD::locale (loc);

    int cat = -1;
    __rw_manage_cat_data (cat, &cat_data);

    _RWSTD_ASSERT (0 <= cat);

    return cat;
}


// Get message text from catalog.
const char* __rw_get_message (int cat, int set_num, int msg_num)
{
    if (cat < 0)
        return 0;

    _RWSTD_MT_CLASS_GUARD (__rw_open_cat_data);

    __rw_open_cat_data *const pcat_data = __rw_manage_cat_data (cat, 0);

    if (pcat_data && _RWSTD_BAD_CATD != pcat_data->catd) {
        // 22.2.7.1.2, p3: `catalog' must be valid

        const char dflt[] = "";

        const nl_catd catd = pcat_data->catd;

        const char* const text = catgets (catd, set_num, msg_num, dflt);

        if (text != dflt)
            return text;
    }

    return 0;
}


// Get locale to be used for character translation for this message catalog.
const _STD::locale& __rw_get_locale (int cat)
{
    _RWSTD_MT_CLASS_GUARD (__rw_open_cat_data);

    _RWSTD_ASSERT (0 <= cat);
    __rw_open_cat_data* const pcat_data = __rw_manage_cat_data (cat, 0);

    _RWSTD_ASSERT (0 != pcat_data);

    return *pcat_data->loc._C_data ();
}


// Close a catalog and release its handle.
void __rw_cat_close (int cat)
{
    bool cat_closed = false;

    {
        // guard is local to this scope to avoid reacquiring the mutex
        // if have to generate an exception message string below.
        _RWSTD_MT_CLASS_GUARD (__rw_open_cat_data);
    
        __rw_open_cat_data* const pcat_data =
            cat < 0 ? 0 : __rw_manage_cat_data (cat, 0);

        // 22.2.7.1.2, p5: `catalog' must be valid
        if (pcat_data && pcat_data->catd != _RWSTD_BAD_CATD) {

            catclose (pcat_data->catd);

            _STD::locale* const ploc = pcat_data->loc._C_data ();

            ploc->~locale ();

            __rw_manage_cat_data (cat, pcat_data);

            cat_closed = true;
        }
        else {
            cat_closed = false;
        }
    }

    _RWSTD_REQUIRES (cat_closed, (_RWSTD_ERROR_INVALID_ARGUMENT,
                                  _RWSTD_FUNC ("__rw_cat_close (int cat)")));
}


}   // namespace __rw
