add upstream source (adch++ 2.12.1 from sourceforge)
This commit is contained in:
10
src/boost/libs/date_time/src/SConscript
Normal file
10
src/boost/libs/date_time/src/SConscript
Normal file
@@ -0,0 +1,10 @@
|
||||
Import('dev source_path')
|
||||
|
||||
env, target, sources = dev.prepare_build(source_path, 'aboost_date_time', '*/*.cpp')
|
||||
|
||||
if '-fvisibility=hidden' in env['CCFLAGS']:
|
||||
env['CCFLAGS'].remove('-fvisibility=hidden')
|
||||
|
||||
ret = env.SharedLibrary(target, sources)
|
||||
|
||||
Return('ret')
|
||||
38
src/boost/libs/date_time/src/gregorian/date_generators.cpp
Normal file
38
src/boost/libs/date_time/src/gregorian/date_generators.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
|
||||
* Use, modification and distribution is subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
* Author: Jeff Garland, Bart Garst
|
||||
* $Date: 2012-09-24 11:08:16 -0700 (Mon, 24 Sep 2012) $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef BOOST_DATE_TIME_SOURCE
|
||||
#define BOOST_DATE_TIME_SOURCE
|
||||
#endif
|
||||
#include "boost/date_time/date_generators.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace date_time {
|
||||
|
||||
const char* const _nth_as_str[] = {"out of range", "first", "second",
|
||||
"third", "fourth", "fifth"};
|
||||
|
||||
//! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
|
||||
BOOST_DATE_TIME_DECL const char* nth_as_str(int ele)
|
||||
{
|
||||
if(ele >= 1 && ele <= 5) {
|
||||
return _nth_as_str[ele];
|
||||
}
|
||||
else {
|
||||
return _nth_as_str[0];
|
||||
}
|
||||
}
|
||||
|
||||
} } //namespace date_time
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
173
src/boost/libs/date_time/src/gregorian/greg_month.cpp
Normal file
173
src/boost/libs/date_time/src/gregorian/greg_month.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
|
||||
* Use, modification and distribution is subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
* Author: Jeff Garland, Bart Garst
|
||||
* $Date: 2012-09-30 16:25:22 -0700 (Sun, 30 Sep 2012) $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef BOOST_DATE_TIME_SOURCE
|
||||
#define BOOST_DATE_TIME_SOURCE
|
||||
#endif
|
||||
#include "boost/date_time/gregorian/greg_month.hpp"
|
||||
#include "boost/date_time/gregorian/greg_facet.hpp"
|
||||
#include "boost/date_time/date_format_simple.hpp"
|
||||
#include "boost/date_time/compiler_config.hpp"
|
||||
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
|
||||
#include "boost/date_time/gregorian/formatters_limited.hpp"
|
||||
#else
|
||||
#include "boost/date_time/gregorian/formatters.hpp"
|
||||
#endif
|
||||
#include "boost/date_time/date_parsing.hpp"
|
||||
#include "boost/date_time/gregorian/parsers.hpp"
|
||||
|
||||
#include "greg_names.hpp"
|
||||
namespace boost {
|
||||
namespace gregorian {
|
||||
|
||||
/*! Returns a shared pointer to a map of Month strings & numbers.
|
||||
* Strings are both full names and abbreviations.
|
||||
* Ex. ("jan",1), ("february",2), etc...
|
||||
* Note: All characters are lowercase - for case insensitivity
|
||||
*/
|
||||
greg_month::month_map_ptr_type greg_month::get_month_map_ptr()
|
||||
{
|
||||
static month_map_ptr_type month_map_ptr(new greg_month::month_map_type());
|
||||
|
||||
if(month_map_ptr->empty()) {
|
||||
std::string s("");
|
||||
for(unsigned short i = 1; i <= 12; ++i) {
|
||||
greg_month m(static_cast<month_enum>(i));
|
||||
s = m.as_long_string();
|
||||
s = date_time::convert_to_lower(s);
|
||||
month_map_ptr->insert(std::make_pair(s, i));
|
||||
s = m.as_short_string();
|
||||
s = date_time::convert_to_lower(s);
|
||||
month_map_ptr->insert(std::make_pair(s, i));
|
||||
}
|
||||
}
|
||||
return month_map_ptr;
|
||||
}
|
||||
|
||||
|
||||
//! Returns 3 char english string for the month ex: Jan, Feb, Mar, Apr
|
||||
const char*
|
||||
greg_month::as_short_string() const
|
||||
{
|
||||
return short_month_names[value_-1];
|
||||
}
|
||||
|
||||
//! Returns full name of month as string in english ex: January, February
|
||||
const char*
|
||||
greg_month::as_long_string() const
|
||||
{
|
||||
return long_month_names[value_-1];
|
||||
}
|
||||
|
||||
//! Return special_value from string argument
|
||||
/*! Return special_value from string argument. If argument is
|
||||
* not one of the special value names (defined in names.hpp),
|
||||
* return 'not_special' */
|
||||
special_values special_value_from_string(const std::string& s) {
|
||||
short i = date_time::find_match(special_value_names,
|
||||
special_value_names,
|
||||
date_time::NumSpecialValues,
|
||||
s);
|
||||
if(i >= date_time::NumSpecialValues) { // match not found
|
||||
return not_special;
|
||||
}
|
||||
else {
|
||||
return static_cast<special_values>(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
//! Returns 3 wchar_t english string for the month ex: Jan, Feb, Mar, Apr
|
||||
const wchar_t*
|
||||
greg_month::as_short_wstring() const
|
||||
{
|
||||
return w_short_month_names[value_-1];
|
||||
}
|
||||
|
||||
//! Returns full name of month as wchar_t string in english ex: January, February
|
||||
const wchar_t*
|
||||
greg_month::as_long_wstring() const
|
||||
{
|
||||
return w_long_month_names[value_-1];
|
||||
}
|
||||
#endif // BOOST_NO_STD_WSTRING
|
||||
|
||||
#ifndef BOOST_DATE_TIME_NO_LOCALE
|
||||
/*! creates an all_date_names_put object with the correct set of names.
|
||||
* This function is only called in the event of an exception where
|
||||
* the imbued locale containing the needed facet is for some reason
|
||||
* unreachable.
|
||||
*/
|
||||
BOOST_DATE_TIME_DECL
|
||||
boost::date_time::all_date_names_put<greg_facet_config, char>*
|
||||
create_facet_def(char /*type*/)
|
||||
{
|
||||
typedef
|
||||
boost::date_time::all_date_names_put<greg_facet_config, char> facet_def;
|
||||
|
||||
return new facet_def(short_month_names,
|
||||
long_month_names,
|
||||
special_value_names,
|
||||
short_weekday_names,
|
||||
long_weekday_names);
|
||||
}
|
||||
|
||||
//! generates a locale with the set of gregorian name-strings of type char*
|
||||
BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char /*type*/){
|
||||
typedef boost::date_time::all_date_names_put<greg_facet_config, char> facet_def;
|
||||
return std::locale(loc, new facet_def(short_month_names,
|
||||
long_month_names,
|
||||
special_value_names,
|
||||
short_weekday_names,
|
||||
long_weekday_names)
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
/*! creates an all_date_names_put object with the correct set of names.
|
||||
* This function is only called in the event of an exception where
|
||||
* the imbued locale containing the needed facet is for some reason
|
||||
* unreachable.
|
||||
*/
|
||||
BOOST_DATE_TIME_DECL
|
||||
boost::date_time::all_date_names_put<greg_facet_config, wchar_t>*
|
||||
create_facet_def(wchar_t /*type*/)
|
||||
{
|
||||
typedef
|
||||
boost::date_time::all_date_names_put<greg_facet_config,wchar_t> facet_def;
|
||||
|
||||
return new facet_def(w_short_month_names,
|
||||
w_long_month_names,
|
||||
w_special_value_names,
|
||||
w_short_weekday_names,
|
||||
w_long_weekday_names);
|
||||
}
|
||||
|
||||
//! generates a locale with the set of gregorian name-strings of type wchar_t*
|
||||
BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t /*type*/){
|
||||
typedef boost::date_time::all_date_names_put<greg_facet_config, wchar_t> facet_def;
|
||||
return std::locale(loc, new facet_def(w_short_month_names,
|
||||
w_long_month_names,
|
||||
w_special_value_names,
|
||||
w_short_weekday_names,
|
||||
w_long_weekday_names)
|
||||
);
|
||||
}
|
||||
#endif // BOOST_NO_STD_WSTRING
|
||||
#endif // BOOST_DATE_TIME_NO_LOCALE
|
||||
|
||||
} } //namespace gregorian
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
43
src/boost/libs/date_time/src/gregorian/greg_names.hpp
Normal file
43
src/boost/libs/date_time/src/gregorian/greg_names.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
|
||||
* Use, modification and distribution is subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
* Author: Jeff Garland, Bart Garst
|
||||
* $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef DATE_TIME_SRC_GREG_NAMES_HPP___
|
||||
#define DATE_TIME_SRC_GREG_NAMES_HPP___
|
||||
|
||||
#include "boost/date_time/gregorian/greg_month.hpp"
|
||||
#include "boost/date_time/special_defs.hpp"
|
||||
namespace boost {
|
||||
namespace gregorian {
|
||||
|
||||
|
||||
const char* const short_month_names[NumMonths]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", "NAM"};
|
||||
const char* const long_month_names[NumMonths]={"January","February","March","April","May","June","July","August","September","October","November","December","NotAMonth"};
|
||||
const char* const special_value_names[date_time::NumSpecialValues]={"not-a-date-time","-infinity","+infinity","min_date_time","max_date_time","not_special"};
|
||||
|
||||
|
||||
const char* const short_weekday_names[]={"Sun", "Mon", "Tue",
|
||||
"Wed", "Thu", "Fri", "Sat"};
|
||||
const char* const long_weekday_names[]= {"Sunday","Monday","Tuesday",
|
||||
"Wednesday", "Thursday",
|
||||
"Friday", "Saturday"};
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
const wchar_t* const w_short_month_names[NumMonths]={L"Jan",L"Feb",L"Mar",L"Apr",L"May",L"Jun",L"Jul",L"Aug",L"Sep",L"Oct",L"Nov",L"Dec",L"NAM"};
|
||||
const wchar_t* const w_long_month_names[NumMonths]={L"January",L"February",L"March",L"April",L"May",L"June",L"July",L"August",L"September",L"October",L"November",L"December",L"NotAMonth"};
|
||||
const wchar_t* const w_special_value_names[date_time::NumSpecialValues]={L"not-a-date-time",L"-infinity",L"+infinity",L"min_date_time",L"max_date_time",L"not_special"};
|
||||
|
||||
const wchar_t* const w_short_weekday_names[]={L"Sun", L"Mon", L"Tue",
|
||||
L"Wed", L"Thu", L"Fri", L"Sat"};
|
||||
const wchar_t* const w_long_weekday_names[]= {L"Sunday",L"Monday",L"Tuesday",
|
||||
L"Wednesday", L"Thursday",
|
||||
L"Friday", L"Saturday"};
|
||||
#endif // BOOST_NO_STD_WSTRING
|
||||
} } // boost::gregorian
|
||||
#endif // DATE_TIME_SRC_GREG_NAMES_HPP___
|
||||
50
src/boost/libs/date_time/src/gregorian/greg_weekday.cpp
Normal file
50
src/boost/libs/date_time/src/gregorian/greg_weekday.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
|
||||
* Use, modification and distribution is subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
* Author: Jeff Garland, Bart Garst
|
||||
* $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef BOOST_DATE_TIME_SOURCE
|
||||
#define BOOST_DATE_TIME_SOURCE
|
||||
#endif
|
||||
#include "boost/date_time/gregorian/greg_weekday.hpp"
|
||||
|
||||
#include "greg_names.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace gregorian {
|
||||
|
||||
//! Return a 3 digit english string of the day of week (eg: Sun)
|
||||
const char*
|
||||
greg_weekday::as_short_string() const
|
||||
{
|
||||
return short_weekday_names[value_];
|
||||
}
|
||||
//! Return a point to a long english string representing day of week
|
||||
const char*
|
||||
greg_weekday::as_long_string() const
|
||||
{
|
||||
return long_weekday_names[value_];
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
//! Return a 3 digit english wchar_t string of the day of week (eg: Sun)
|
||||
const wchar_t*
|
||||
greg_weekday::as_short_wstring() const
|
||||
{
|
||||
return w_short_weekday_names[value_];
|
||||
}
|
||||
//! Return a point to a long english wchar_t string representing day of week
|
||||
const wchar_t*
|
||||
greg_weekday::as_long_wstring() const
|
||||
{
|
||||
return w_long_weekday_names[value_];
|
||||
}
|
||||
#endif // BOOST_NO_STD_WSTRING
|
||||
|
||||
} } //namespace gregorian
|
||||
|
||||
62
src/boost/libs/date_time/src/gregorian/gregorian_types.cpp
Normal file
62
src/boost/libs/date_time/src/gregorian/gregorian_types.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
|
||||
* Use, modification and distribution is subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
* Author: Jeff Garland
|
||||
* $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup date_basics Date Basics
|
||||
This page summarizes some of the key user types and functions needed
|
||||
to write programs using the gregorian date system. This is not a
|
||||
comprehensive list, but rather some key types to start exploring.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
/** @defgroup date_alg Date Algorithms / Generators
|
||||
Date algorithms or generators are tools for generating other dates or
|
||||
schedules of dates. A generator function starts with some part of a
|
||||
date such as a month and day and is supplied another part to then
|
||||
generate a final date.
|
||||
|
||||
**/
|
||||
|
||||
/** @defgroup date_format Date Formatting
|
||||
The functions on these page are some of the key formatting functions
|
||||
for dates.
|
||||
**/
|
||||
|
||||
|
||||
//File doesn't have a current purpose except to generate docs
|
||||
//and keep it changeable without recompiles
|
||||
/*! @example days_alive.cpp
|
||||
Calculate the number of days you have been living using durations and dates.
|
||||
*/
|
||||
/*! @example days_till_new_year.cpp
|
||||
Calculate the number of days till new years
|
||||
*/
|
||||
/*! @example print_month.cpp
|
||||
Simple utility to print out days of the month with the days of a month. Demontstrates date iteration (date_time::date_itr).
|
||||
*/
|
||||
/*! @example localization.cpp
|
||||
An example showing localized stream-based I/O.
|
||||
*/
|
||||
/*! @example dates_as_strings.cpp
|
||||
Various parsing and output of strings (mostly supported for
|
||||
compilers that do not support localized streams).
|
||||
*/
|
||||
/*! @example period_calc.cpp
|
||||
Calculates if a date is in an 'irregular' collection of periods using
|
||||
period calculation functions.
|
||||
*/
|
||||
/*! @example print_holidays.cpp
|
||||
This is an example of using functors to define a holiday schedule
|
||||
*/
|
||||
/*! @example localization.cpp
|
||||
Demonstrates the use of facets to localize date output for Gregorian dates.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
35
src/boost/libs/date_time/src/posix_time/posix_time_types.cpp
Normal file
35
src/boost/libs/date_time/src/posix_time/posix_time_types.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
|
||||
* Use, modification and distribution is subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
* Author: Jeff Garland
|
||||
* $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $
|
||||
*/
|
||||
|
||||
|
||||
//File doesn't have a current purpose except to generate docs
|
||||
//and keep it changeable without recompiles
|
||||
|
||||
/** @defgroup time_basics Time Basics
|
||||
|
||||
**/
|
||||
|
||||
/** @defgroup time_format Time Formatting
|
||||
|
||||
**/
|
||||
|
||||
|
||||
|
||||
/*! @example local_utc_conversion.cpp
|
||||
Demonstrate utc to local and local to utc calculations including dst.
|
||||
*/
|
||||
/*! @example time_periods.cpp Demonstrate some simple uses of time periods.
|
||||
*/
|
||||
/*! @example print_hours.cpp Demonstrate time iteration, clock retrieval, and simple calculation.
|
||||
*/
|
||||
/*! @example time_math.cpp Various types of calculations with times and time durations.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
22
src/boost/libs/locale/src/SConscript
Normal file
22
src/boost/libs/locale/src/SConscript
Normal file
@@ -0,0 +1,22 @@
|
||||
Import('dev source_path')
|
||||
|
||||
env, target, sources = dev.prepare_build(source_path, 'aboost_locale', '*/*.cpp')
|
||||
|
||||
if dev.is_win32(): to_remove = 'posix'
|
||||
else: to_remove = 'win32'
|
||||
sources = [source for source in sources if to_remove + '/' not in source and to_remove + '\\' not in source]
|
||||
|
||||
if dev.is_win32():
|
||||
env.Append(CPPDEFINES = ['BOOST_LOCALE_NO_POSIX_BACKEND'])
|
||||
else:
|
||||
env.Append(CPPDEFINES = ['BOOST_LOCALE_NO_WINAPI_BACKEND', 'BOOST_LOCALE_WITH_ICONV'])
|
||||
|
||||
env.Append(LIBS = ['aboost_system'])
|
||||
env.Depends(target, dev.boost_system)
|
||||
|
||||
if '-fvisibility=hidden' in env['CCFLAGS']:
|
||||
env['CCFLAGS'].remove('-fvisibility=hidden')
|
||||
|
||||
ret = env.SharedLibrary(target, sources)
|
||||
|
||||
Return('ret')
|
||||
200
src/boost/libs/locale/src/encoding/codepage.cpp
Normal file
200
src/boost/libs/locale/src/encoding/codepage.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#define BOOST_LOCALE_WITH_WCONV
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LOCALE_WITH_ICONV
|
||||
#include "iconv_codepage.ipp"
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_ICU
|
||||
#include "uconv_codepage.ipp"
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_WCONV
|
||||
#include "wconv_codepage.ipp"
|
||||
#endif
|
||||
|
||||
#include <boost/locale/encoding.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace conv {
|
||||
namespace impl {
|
||||
|
||||
std::string convert_between(char const *begin,
|
||||
char const *end,
|
||||
char const *to_charset,
|
||||
char const *from_charset,
|
||||
method_type how)
|
||||
{
|
||||
std::auto_ptr<converter_between> cvt;
|
||||
#ifdef BOOST_LOCALE_WITH_ICONV
|
||||
cvt.reset(new iconv_between());
|
||||
if(cvt->open(to_charset,from_charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_ICU
|
||||
cvt.reset(new uconv_between());
|
||||
if(cvt->open(to_charset,from_charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_WCONV
|
||||
cvt.reset(new wconv_between());
|
||||
if(cvt->open(to_charset,from_charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> convert_to(
|
||||
char const *begin,
|
||||
char const *end,
|
||||
char const *charset,
|
||||
method_type how)
|
||||
{
|
||||
std::auto_ptr<converter_to_utf<CharType> > cvt;
|
||||
#ifdef BOOST_LOCALE_WITH_ICONV
|
||||
cvt.reset(new iconv_to_utf<CharType>());
|
||||
if(cvt->open(charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_ICU
|
||||
cvt.reset(new uconv_to_utf<CharType>());
|
||||
if(cvt->open(charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_WCONV
|
||||
cvt.reset(new wconv_to_utf<CharType>());
|
||||
if(cvt->open(charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
throw invalid_charset_error(charset);
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
std::string convert_from(
|
||||
CharType const *begin,
|
||||
CharType const *end,
|
||||
char const *charset,
|
||||
method_type how)
|
||||
{
|
||||
std::auto_ptr<converter_from_utf<CharType> > cvt;
|
||||
#ifdef BOOST_LOCALE_WITH_ICONV
|
||||
cvt.reset(new iconv_from_utf<CharType>());
|
||||
if(cvt->open(charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_ICU
|
||||
cvt.reset(new uconv_from_utf<CharType>());
|
||||
if(cvt->open(charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
#ifdef BOOST_LOCALE_WITH_WCONV
|
||||
cvt.reset(new wconv_from_utf<CharType>());
|
||||
if(cvt->open(charset,how))
|
||||
return cvt->convert(begin,end);
|
||||
#endif
|
||||
throw invalid_charset_error(charset);
|
||||
}
|
||||
|
||||
std::string normalize_encoding(char const *ccharset)
|
||||
{
|
||||
std::string charset;
|
||||
charset.reserve(std::strlen(ccharset));
|
||||
while(*ccharset!=0) {
|
||||
char c=*ccharset++;
|
||||
if('0' <= c && c<= '9')
|
||||
charset+=c;
|
||||
else if('a' <=c && c <='z')
|
||||
charset+=c;
|
||||
else if('A' <=c && c <='Z')
|
||||
charset+=char(c-'A'+'a');
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
|
||||
|
||||
} // impl
|
||||
|
||||
using namespace impl;
|
||||
|
||||
std::string between(char const *begin,char const *end,
|
||||
std::string const &to_charset,std::string const &from_charset,method_type how)
|
||||
{
|
||||
return convert_between(begin,end,to_charset.c_str(),from_charset.c_str(),how);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::basic_string<char> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_to<char>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string from_utf(char const *begin,char const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_from<char>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::basic_string<wchar_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_to<wchar_t>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string from_utf(wchar_t const *begin,wchar_t const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_from<wchar_t>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
template<>
|
||||
std::basic_string<char16_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_to<char16_t>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string from_utf(char16_t const *begin,char16_t const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_from<char16_t>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
template<>
|
||||
std::basic_string<char32_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_to<char32_t>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string from_utf(char32_t const *begin,char32_t const *end,std::string const &charset,method_type how)
|
||||
{
|
||||
return convert_from<char32_t>(begin,end,charset.c_str(),how);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
118
src/boost/libs/locale/src/encoding/conv.hpp
Normal file
118
src/boost/libs/locale/src/encoding/conv.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_LOCALE_CONV_IMPL_HPP
|
||||
#define BOOST_LOCALE_CONV_IMPL_HPP
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace conv {
|
||||
namespace impl {
|
||||
|
||||
template<typename CharType>
|
||||
char const *utf_name()
|
||||
{
|
||||
union {
|
||||
char first;
|
||||
uint16_t u16;
|
||||
uint32_t u32;
|
||||
} v;
|
||||
|
||||
if(sizeof(CharType) == 1) {
|
||||
return "UTF-8";
|
||||
}
|
||||
else if(sizeof(CharType) == 2) {
|
||||
v.u16 = 1;
|
||||
if(v.first == 1) {
|
||||
return "UTF-16LE";
|
||||
}
|
||||
else {
|
||||
return "UTF-16BE";
|
||||
}
|
||||
}
|
||||
else if(sizeof(CharType) == 4) {
|
||||
v.u32 = 1;
|
||||
if(v.first == 1) {
|
||||
return "UTF-32LE";
|
||||
}
|
||||
else {
|
||||
return "UTF-32BE";
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
return "Unknown Character Encoding";
|
||||
}
|
||||
}
|
||||
|
||||
std::string normalize_encoding(char const *encoding);
|
||||
|
||||
inline int compare_encodings(char const *l,char const *r)
|
||||
{
|
||||
return normalize_encoding(l).compare(normalize_encoding(r));
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
int encoding_to_windows_codepage(char const *ccharset);
|
||||
#endif
|
||||
|
||||
class converter_between {
|
||||
public:
|
||||
typedef char char_type;
|
||||
|
||||
typedef std::string string_type;
|
||||
|
||||
virtual bool open(char const *to_charset,char const *from_charset,method_type how) = 0;
|
||||
|
||||
virtual std::string convert(char const *begin,char const *end) = 0;
|
||||
|
||||
virtual ~converter_between()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class converter_from_utf {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
virtual bool open(char const *charset,method_type how) = 0;
|
||||
|
||||
virtual std::string convert(CharType const *begin,CharType const *end) = 0;
|
||||
|
||||
virtual ~converter_from_utf()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class converter_to_utf {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
virtual bool open(char const *charset,method_type how) = 0;
|
||||
|
||||
virtual string_type convert(char const *begin,char const *end) = 0;
|
||||
|
||||
virtual ~converter_to_utf()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
#endif
|
||||
201
src/boost/libs/locale/src/encoding/iconv_codepage.ipp
Normal file
201
src/boost/libs/locale/src/encoding/iconv_codepage.ipp
Normal file
@@ -0,0 +1,201 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
|
||||
#define BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
|
||||
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include "../util/iconv.hpp"
|
||||
#include <errno.h>
|
||||
#include "conv.hpp"
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace conv {
|
||||
namespace impl {
|
||||
|
||||
class iconverter_base {
|
||||
public:
|
||||
|
||||
iconverter_base() :
|
||||
cvt_((iconv_t)(-1))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~iconverter_base()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
size_t conv(char const **inbufc,size_t *inchar_left,
|
||||
char **outbuf,size_t *outchar_left)
|
||||
{
|
||||
char **inbuf = const_cast<char **>(inbufc);
|
||||
return call_iconv(cvt_,inbuf,inchar_left,outbuf,outchar_left);
|
||||
}
|
||||
|
||||
bool open(char const *to,char const *from,method_type how)
|
||||
{
|
||||
close();
|
||||
cvt_ = iconv_open(to,from);
|
||||
how_ = how;
|
||||
return cvt_ != (iconv_t)(-1);
|
||||
}
|
||||
|
||||
template<typename OutChar,typename InChar>
|
||||
std::basic_string<OutChar> real_convert(InChar const *ubegin,InChar const *uend)
|
||||
{
|
||||
std::basic_string<OutChar> sresult;
|
||||
|
||||
sresult.reserve(uend - ubegin);
|
||||
|
||||
OutChar result[64];
|
||||
|
||||
char *out_start = reinterpret_cast<char *>(&result[0]);
|
||||
char const *begin = reinterpret_cast<char const *>(ubegin);
|
||||
char const *end = reinterpret_cast<char const *>(uend);
|
||||
|
||||
enum { normal , unshifting , done } state = normal;
|
||||
|
||||
while(state!=done) {
|
||||
|
||||
size_t in_left = end - begin;
|
||||
size_t out_left = sizeof(result);
|
||||
|
||||
char *out_ptr = out_start;
|
||||
size_t res = 0;
|
||||
if(in_left == 0)
|
||||
state = unshifting;
|
||||
|
||||
if(state == normal)
|
||||
res = conv(&begin,&in_left,&out_ptr,&out_left);
|
||||
else
|
||||
res = conv(0,0,&out_ptr,&out_left);
|
||||
|
||||
int err = errno;
|
||||
|
||||
size_t output_count = (out_ptr - out_start) / sizeof(OutChar);
|
||||
|
||||
sresult.append(&result[0],output_count);
|
||||
|
||||
if(res == (size_t)(-1)) {
|
||||
if(err == EILSEQ || err == EINVAL) {
|
||||
if(how_ == stop) {
|
||||
throw conversion_error();
|
||||
}
|
||||
|
||||
if(begin != end) {
|
||||
begin+=sizeof(InChar);
|
||||
if(begin >= end)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (err==E2BIG) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// We should never get there
|
||||
// but if we do
|
||||
if(how_ == stop)
|
||||
throw conversion_error();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(state == unshifting)
|
||||
state = done;
|
||||
}
|
||||
return sresult;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void close()
|
||||
{
|
||||
if(cvt_!=(iconv_t)(-1)) {
|
||||
iconv_close(cvt_);
|
||||
cvt_ = (iconv_t)(-1);
|
||||
}
|
||||
}
|
||||
|
||||
iconv_t cvt_;
|
||||
|
||||
method_type how_;
|
||||
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class iconv_from_utf : public iconverter_base, public converter_from_utf<CharType>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CharType char_type;
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
return iconverter_base::open(charset,utf_name<CharType>(),how);
|
||||
}
|
||||
|
||||
virtual std::string convert(char_type const *ubegin,char_type const *uend)
|
||||
{
|
||||
return real_convert<char,char_type>(ubegin,uend);
|
||||
}
|
||||
};
|
||||
|
||||
class iconv_between: public iconverter_base, public converter_between
|
||||
{
|
||||
public:
|
||||
virtual bool open(char const *to_charset,char const *from_charset,method_type how)
|
||||
{
|
||||
return iconverter_base::open(to_charset,from_charset,how);
|
||||
}
|
||||
virtual std::string convert(char const *begin,char const *end)
|
||||
{
|
||||
return real_convert<char,char>(begin,end);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class iconv_to_utf : public iconverter_base, public converter_to_utf<CharType>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
return iconverter_base::open(utf_name<CharType>(),charset,how);
|
||||
}
|
||||
|
||||
virtual string_type convert(char const *begin,char const *end)
|
||||
{
|
||||
return real_convert<char_type,char>(begin,end);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // impl
|
||||
} // conv
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
162
src/boost/libs/locale/src/encoding/uconv_codepage.ipp
Normal file
162
src/boost/libs/locale/src/encoding/uconv_codepage.ipp
Normal file
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
|
||||
#define BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include "conv.hpp"
|
||||
#include "../icu/icu_util.hpp"
|
||||
#include "../icu/uconv.hpp"
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/ucnv_err.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace conv {
|
||||
namespace impl {
|
||||
template<typename CharType>
|
||||
class uconv_to_utf : public converter_to_utf<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
close();
|
||||
try {
|
||||
cvt_from_.reset(new from_type(charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
|
||||
cvt_to_.reset(new to_type("UTF-8",how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void close()
|
||||
{
|
||||
cvt_from_.reset();
|
||||
cvt_to_.reset();
|
||||
}
|
||||
|
||||
virtual string_type convert(char const *begin,char const *end)
|
||||
{
|
||||
try {
|
||||
return cvt_to_->std(cvt_from_->icu_checked(begin,end));
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
throw conversion_error();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef impl_icu::icu_std_converter<char> from_type;
|
||||
typedef impl_icu::icu_std_converter<CharType> to_type;
|
||||
|
||||
std::auto_ptr<from_type> cvt_from_;
|
||||
std::auto_ptr<to_type> cvt_to_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class uconv_from_utf : public converter_from_utf<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
close();
|
||||
try {
|
||||
cvt_from_.reset(new from_type("UTF-8",how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
|
||||
cvt_to_.reset(new to_type(charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void close()
|
||||
{
|
||||
cvt_from_.reset();
|
||||
cvt_to_.reset();
|
||||
}
|
||||
|
||||
virtual std::string convert(CharType const *begin,CharType const *end)
|
||||
{
|
||||
try {
|
||||
return cvt_to_->std(cvt_from_->icu_checked(begin,end));
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
throw conversion_error();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef impl_icu::icu_std_converter<CharType> from_type;
|
||||
typedef impl_icu::icu_std_converter<char> to_type;
|
||||
|
||||
std::auto_ptr<from_type> cvt_from_;
|
||||
std::auto_ptr<to_type> cvt_to_;
|
||||
|
||||
};
|
||||
|
||||
class uconv_between : public converter_between {
|
||||
public:
|
||||
virtual bool open(char const *to_charset,char const *from_charset,method_type how)
|
||||
{
|
||||
close();
|
||||
try {
|
||||
cvt_from_.reset(new from_type(from_charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
|
||||
cvt_to_.reset(new to_type(to_charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void close()
|
||||
{
|
||||
cvt_from_.reset();
|
||||
cvt_to_.reset();
|
||||
}
|
||||
|
||||
virtual std::string convert(char const *begin,char const *end)
|
||||
{
|
||||
try {
|
||||
return cvt_to_->std(cvt_from_->icu(begin,end));
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
throw conversion_error();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef impl_icu::icu_std_converter<char> from_type;
|
||||
typedef impl_icu::icu_std_converter<char> to_type;
|
||||
|
||||
std::auto_ptr<from_type> cvt_from_;
|
||||
std::auto_ptr<to_type> cvt_to_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // impl
|
||||
} // conv
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
#endif
|
||||
539
src/boost/libs/locale/src/encoding/wconv_codepage.ipp
Normal file
539
src/boost/libs/locale/src/encoding/wconv_codepage.ipp
Normal file
@@ -0,0 +1,539 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_LOCALE_IMPL_WCONV_CODEPAGE_HPP
|
||||
#define BOOST_LOCALE_IMPL_WCONV_CODEPAGE_HPP
|
||||
|
||||
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "conv.hpp"
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace conv {
|
||||
namespace impl {
|
||||
|
||||
struct windows_encoding {
|
||||
char const *name;
|
||||
unsigned codepage;
|
||||
unsigned was_tested;
|
||||
};
|
||||
|
||||
bool operator<(windows_encoding const &l,windows_encoding const &r)
|
||||
{
|
||||
return strcmp(l.name,r.name) < 0;
|
||||
}
|
||||
|
||||
windows_encoding all_windows_encodings[] = {
|
||||
{ "big5", 950, 0 },
|
||||
{ "cp1250", 1250, 0 },
|
||||
{ "cp1251", 1251, 0 },
|
||||
{ "cp1252", 1252, 0 },
|
||||
{ "cp1253", 1253, 0 },
|
||||
{ "cp1254", 1254, 0 },
|
||||
{ "cp1255", 1255, 0 },
|
||||
{ "cp1256", 1256, 0 },
|
||||
{ "cp1257", 1257, 0 },
|
||||
{ "cp874", 874, 0 },
|
||||
{ "cp932", 932, 0 },
|
||||
{ "cp936", 936, 0 },
|
||||
{ "eucjp", 20932, 0 },
|
||||
{ "euckr", 51949, 0 },
|
||||
{ "gb18030", 54936, 0 },
|
||||
{ "gb2312", 20936, 0 },
|
||||
{ "gbk", 936, 0 },
|
||||
{ "iso2022jp", 50220, 0 },
|
||||
{ "iso2022kr", 50225, 0 },
|
||||
{ "iso88591", 28591, 0 },
|
||||
{ "iso885913", 28603, 0 },
|
||||
{ "iso885915", 28605, 0 },
|
||||
{ "iso88592", 28592, 0 },
|
||||
{ "iso88593", 28593, 0 },
|
||||
{ "iso88594", 28594, 0 },
|
||||
{ "iso88595", 28595, 0 },
|
||||
{ "iso88596", 28596, 0 },
|
||||
{ "iso88597", 28597, 0 },
|
||||
{ "iso88598", 28598, 0 },
|
||||
{ "iso88599", 28599, 0 },
|
||||
{ "koi8r", 20866, 0 },
|
||||
{ "koi8u", 21866, 0 },
|
||||
{ "ms936", 936, 0 },
|
||||
{ "shiftjis", 932, 0 },
|
||||
{ "sjis", 932, 0 },
|
||||
{ "usascii", 20127, 0 },
|
||||
{ "utf8", 65001, 0 },
|
||||
{ "windows1250", 1250, 0 },
|
||||
{ "windows1251", 1251, 0 },
|
||||
{ "windows1252", 1252, 0 },
|
||||
{ "windows1253", 1253, 0 },
|
||||
{ "windows1254", 1254, 0 },
|
||||
{ "windows1255", 1255, 0 },
|
||||
{ "windows1256", 1256, 0 },
|
||||
{ "windows1257", 1257, 0 },
|
||||
{ "windows874", 874, 0 },
|
||||
{ "windows932", 932, 0 },
|
||||
{ "windows936", 936, 0 },
|
||||
};
|
||||
|
||||
size_t remove_substitutions(std::vector<char> &v)
|
||||
{
|
||||
if(std::find(v.begin(),v.end(),0) == v.end()) {
|
||||
return v.size();
|
||||
}
|
||||
std::vector<char> v2;
|
||||
v2.reserve(v.size());
|
||||
for(unsigned i=0;i<v.size();i++) {
|
||||
if(v[i]!=0)
|
||||
v2.push_back(v[i]);
|
||||
}
|
||||
v.swap(v2);
|
||||
return v.size();
|
||||
}
|
||||
|
||||
void multibyte_to_wide_one_by_one(int codepage,char const *begin,char const *end,std::vector<wchar_t> &buf)
|
||||
{
|
||||
buf.reserve(end-begin);
|
||||
while(begin!=end) {
|
||||
wchar_t wide_buf[4];
|
||||
int n = 0;
|
||||
int len = IsDBCSLeadByteEx(codepage,*begin) ? 2 : 1;
|
||||
if(len == 2 && begin+1==end)
|
||||
return;
|
||||
n = MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,len,wide_buf,4);
|
||||
for(int i=0;i<n;i++)
|
||||
buf.push_back(wide_buf[i]);
|
||||
begin+=len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void multibyte_to_wide(int codepage,char const *begin,char const *end,bool do_skip,std::vector<wchar_t> &buf)
|
||||
{
|
||||
if(begin==end)
|
||||
return;
|
||||
int n = MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,end-begin,0,0);
|
||||
if(n == 0) {
|
||||
if(do_skip) {
|
||||
multibyte_to_wide_one_by_one(codepage,begin,end,buf);
|
||||
return;
|
||||
}
|
||||
throw conversion_error();
|
||||
}
|
||||
|
||||
buf.resize(n,0);
|
||||
if(MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,end-begin,&buf.front(),buf.size())==0)
|
||||
throw conversion_error();
|
||||
}
|
||||
|
||||
void wide_to_multibyte_non_zero(int codepage,wchar_t const *begin,wchar_t const *end,bool do_skip,std::vector<char> &buf)
|
||||
{
|
||||
if(begin==end)
|
||||
return;
|
||||
BOOL substitute = FALSE;
|
||||
BOOL *substitute_ptr = codepage == 65001 || codepage == 65000 ? 0 : &substitute;
|
||||
char subst_char = 0;
|
||||
char *subst_char_ptr = codepage == 65001 || codepage == 65000 ? 0 : &subst_char;
|
||||
|
||||
int n = WideCharToMultiByte(codepage,0,begin,end-begin,0,0,subst_char_ptr,substitute_ptr);
|
||||
buf.resize(n);
|
||||
|
||||
if(WideCharToMultiByte(codepage,0,begin,end-begin,&buf[0],n,subst_char_ptr,substitute_ptr)==0)
|
||||
throw conversion_error();
|
||||
if(substitute) {
|
||||
if(do_skip)
|
||||
remove_substitutions(buf);
|
||||
else
|
||||
throw conversion_error();
|
||||
}
|
||||
}
|
||||
|
||||
void wide_to_multibyte(int codepage,wchar_t const *begin,wchar_t const *end,bool do_skip,std::vector<char> &buf)
|
||||
{
|
||||
if(begin==end)
|
||||
return;
|
||||
buf.reserve(end-begin);
|
||||
wchar_t const *e = std::find(begin,end,L'\0');
|
||||
wchar_t const *b = begin;
|
||||
for(;;) {
|
||||
std::vector<char> tmp;
|
||||
wide_to_multibyte_non_zero(codepage,b,e,do_skip,tmp);
|
||||
size_t osize = buf.size();
|
||||
buf.resize(osize+tmp.size());
|
||||
std::copy(tmp.begin(),tmp.end(),buf.begin()+osize);
|
||||
if(e!=end) {
|
||||
buf.push_back('\0');
|
||||
b=e+1;
|
||||
e=std::find(b,end,L'0');
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int encoding_to_windows_codepage(char const *ccharset)
|
||||
{
|
||||
std::string charset = normalize_encoding(ccharset);
|
||||
windows_encoding ref;
|
||||
ref.name = charset.c_str();
|
||||
size_t n = sizeof(all_windows_encodings)/sizeof(all_windows_encodings[0]);
|
||||
windows_encoding *begin = all_windows_encodings;
|
||||
windows_encoding *end = all_windows_encodings + n;
|
||||
windows_encoding *ptr = std::lower_bound(begin,end,ref);
|
||||
if(ptr!=end && strcmp(ptr->name,charset.c_str())==0) {
|
||||
if(ptr->was_tested) {
|
||||
return ptr->codepage;
|
||||
}
|
||||
else if(IsValidCodePage(ptr->codepage)) {
|
||||
// the thread safety is not an issue, maximum
|
||||
// it would be checked more then once
|
||||
ptr->was_tested=1;
|
||||
return ptr->codepage;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
bool validate_utf16(CharType const *str,unsigned len)
|
||||
{
|
||||
CharType const *begin = str;
|
||||
CharType const *end = str+len;
|
||||
while(begin!=end) {
|
||||
utf::code_point c = utf::utf_traits<CharType,2>::template decode<CharType const *>(begin,end);
|
||||
if(c==utf::illegal || c==utf::incomplete)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename CharType,typename OutChar>
|
||||
void clean_invalid_utf16(CharType const *str,unsigned len,std::vector<OutChar> &out)
|
||||
{
|
||||
out.reserve(len);
|
||||
for(unsigned i=0;i<len;i++) {
|
||||
uint16_t c = static_cast<uint16_t>(str[i]);
|
||||
|
||||
if(0xD800 <= c && c<= 0xDBFF) {
|
||||
i++;
|
||||
if(i>=len)
|
||||
return;
|
||||
uint16_t c2=static_cast<uint16_t>(str[i]);
|
||||
if(0xDC00 <= c2 && c2 <= 0xDFFF) {
|
||||
out.push_back(static_cast<OutChar>(c));
|
||||
out.push_back(static_cast<OutChar>(c2));
|
||||
}
|
||||
}
|
||||
else if(0xDC00 <= c && c <=0xDFFF)
|
||||
continue;
|
||||
else
|
||||
out.push_back(static_cast<OutChar>(c));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class wconv_between : public converter_between {
|
||||
public:
|
||||
wconv_between() :
|
||||
how_(skip),
|
||||
to_code_page_ (-1),
|
||||
from_code_page_ ( -1)
|
||||
{
|
||||
}
|
||||
bool open(char const *to_charset,char const *from_charset,method_type how)
|
||||
{
|
||||
how_ = how;
|
||||
to_code_page_ = encoding_to_windows_codepage(to_charset);
|
||||
from_code_page_ = encoding_to_windows_codepage(from_charset);
|
||||
if(to_code_page_ == -1 || from_code_page_ == -1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
virtual std::string convert(char const *begin,char const *end)
|
||||
{
|
||||
if(to_code_page_ == 65001 && from_code_page_ == 65001)
|
||||
return utf_to_utf<char>(begin,end,how_);
|
||||
|
||||
std::string res;
|
||||
|
||||
std::vector<wchar_t> tmp; // buffer for mb2w
|
||||
std::wstring tmps; // buffer for utf_to_utf
|
||||
wchar_t const *wbegin=0;
|
||||
wchar_t const *wend=0;
|
||||
|
||||
if(from_code_page_ == 65001) {
|
||||
tmps = utf_to_utf<wchar_t>(begin,end,how_);
|
||||
if(tmps.empty())
|
||||
return res;
|
||||
wbegin = tmps.c_str();
|
||||
wend = wbegin + tmps.size();
|
||||
}
|
||||
else {
|
||||
multibyte_to_wide(from_code_page_,begin,end,how_ == skip,tmp);
|
||||
if(tmp.empty())
|
||||
return res;
|
||||
wbegin = &tmp[0];
|
||||
wend = wbegin + tmp.size();
|
||||
}
|
||||
|
||||
if(to_code_page_ == 65001) {
|
||||
return utf_to_utf<char>(wbegin,wend,how_);
|
||||
}
|
||||
|
||||
std::vector<char> ctmp;
|
||||
wide_to_multibyte(to_code_page_,wbegin,wend,how_ == skip,ctmp);
|
||||
if(ctmp.empty())
|
||||
return res;
|
||||
res.assign(&ctmp.front(),ctmp.size());
|
||||
return res;
|
||||
}
|
||||
private:
|
||||
method_type how_;
|
||||
int to_code_page_;
|
||||
int from_code_page_;
|
||||
};
|
||||
|
||||
template<typename CharType,int size = sizeof(CharType) >
|
||||
class wconv_to_utf;
|
||||
|
||||
template<typename CharType,int size = sizeof(CharType) >
|
||||
class wconv_from_utf;
|
||||
|
||||
template<>
|
||||
class wconv_to_utf<char,1> : public converter_to_utf<char> , public wconv_between {
|
||||
public:
|
||||
virtual bool open(char const *cs,method_type how)
|
||||
{
|
||||
return wconv_between::open("UTF-8",cs,how);
|
||||
}
|
||||
virtual std::string convert(char const *begin,char const *end)
|
||||
{
|
||||
return wconv_between::convert(begin,end);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class wconv_from_utf<char,1> : public converter_from_utf<char> , public wconv_between {
|
||||
public:
|
||||
virtual bool open(char const *cs,method_type how)
|
||||
{
|
||||
return wconv_between::open(cs,"UTF-8",how);
|
||||
}
|
||||
virtual std::string convert(char const *begin,char const *end)
|
||||
{
|
||||
return wconv_between::convert(begin,end);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class wconv_to_utf<CharType,2> : public converter_to_utf<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
wconv_to_utf() :
|
||||
how_(skip),
|
||||
code_page_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
how_ = how;
|
||||
code_page_ = encoding_to_windows_codepage(charset);
|
||||
return code_page_ != -1;
|
||||
}
|
||||
|
||||
virtual string_type convert(char const *begin,char const *end)
|
||||
{
|
||||
if(code_page_ == 65001) {
|
||||
return utf_to_utf<char_type>(begin,end,how_);
|
||||
}
|
||||
std::vector<wchar_t> tmp;
|
||||
multibyte_to_wide(code_page_,begin,end,how_ == skip,tmp);
|
||||
string_type res;
|
||||
if(!tmp.empty())
|
||||
res.assign(reinterpret_cast<char_type *>(&tmp.front()),tmp.size());
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
method_type how_;
|
||||
int code_page_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class wconv_from_utf<CharType,2> : public converter_from_utf<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
wconv_from_utf() :
|
||||
how_(skip),
|
||||
code_page_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
how_ = how;
|
||||
code_page_ = encoding_to_windows_codepage(charset);
|
||||
return code_page_ != -1;
|
||||
}
|
||||
|
||||
virtual std::string convert(CharType const *begin,CharType const *end)
|
||||
{
|
||||
if(code_page_ == 65001) {
|
||||
return utf_to_utf<char>(begin,end,how_);
|
||||
}
|
||||
wchar_t const *wbegin = 0;
|
||||
wchar_t const *wend = 0;
|
||||
std::vector<wchar_t> buffer; // if needed
|
||||
if(begin==end)
|
||||
return std::string();
|
||||
if(validate_utf16(begin,end-begin)) {
|
||||
wbegin = reinterpret_cast<wchar_t const *>(begin);
|
||||
wend = reinterpret_cast<wchar_t const *>(end);
|
||||
}
|
||||
else {
|
||||
if(how_ == stop) {
|
||||
throw conversion_error();
|
||||
}
|
||||
else {
|
||||
clean_invalid_utf16(begin,end-begin,buffer);
|
||||
if(!buffer.empty()) {
|
||||
wbegin = &buffer[0];
|
||||
wend = wbegin + buffer.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string res;
|
||||
if(wbegin==wend)
|
||||
return res;
|
||||
std::vector<char> ctmp;
|
||||
wide_to_multibyte(code_page_,wbegin,wend,how_ == skip,ctmp);
|
||||
if(ctmp.empty())
|
||||
return res;
|
||||
res.assign(&ctmp.front(),ctmp.size());
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
method_type how_;
|
||||
int code_page_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class wconv_to_utf<CharType,4> : public converter_to_utf<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
wconv_to_utf() :
|
||||
how_(skip),
|
||||
code_page_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
how_ = how;
|
||||
code_page_ = encoding_to_windows_codepage(charset);
|
||||
return code_page_ != -1;
|
||||
}
|
||||
|
||||
virtual string_type convert(char const *begin,char const *end)
|
||||
{
|
||||
if(code_page_ == 65001) {
|
||||
return utf_to_utf<char_type>(begin,end,how_);
|
||||
}
|
||||
std::vector<wchar_t> buf;
|
||||
multibyte_to_wide(code_page_,begin,end,how_ == skip,buf);
|
||||
|
||||
if(buf.empty())
|
||||
return string_type();
|
||||
|
||||
return utf_to_utf<CharType>(&buf[0],&buf[0]+buf.size(),how_);
|
||||
}
|
||||
private:
|
||||
method_type how_;
|
||||
int code_page_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class wconv_from_utf<CharType,4> : public converter_from_utf<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
wconv_from_utf() :
|
||||
how_(skip),
|
||||
code_page_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool open(char const *charset,method_type how)
|
||||
{
|
||||
how_ = how;
|
||||
code_page_ = encoding_to_windows_codepage(charset);
|
||||
return code_page_ != -1;
|
||||
}
|
||||
|
||||
virtual std::string convert(CharType const *begin,CharType const *end)
|
||||
{
|
||||
if(code_page_ == 65001) {
|
||||
return utf_to_utf<char>(begin,end,how_);
|
||||
}
|
||||
std::wstring tmp = utf_to_utf<wchar_t>(begin,end,how_);
|
||||
|
||||
std::vector<char> ctmp;
|
||||
wide_to_multibyte(code_page_,tmp.c_str(),tmp.c_str()+tmp.size(),how_ == skip,ctmp);
|
||||
std::string res;
|
||||
if(ctmp.empty())
|
||||
return res;
|
||||
res.assign(&ctmp.front(),ctmp.size());
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
method_type how_;
|
||||
int code_page_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // impl
|
||||
} // conv
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
48
src/boost/libs/locale/src/posix/all_generator.hpp
Normal file
48
src/boost/libs/locale/src/posix/all_generator.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_POSIX_ALL_GENERATOR_HPP
|
||||
#define BOOST_LOCALE_IMPL_POSIX_ALL_GENERATOR_HPP
|
||||
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
|
||||
std::locale create_convert( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_collate( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_formatting( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_parsing( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type);
|
||||
std::locale create_codecvt( std::locale const &in,
|
||||
std::string const &encoding,
|
||||
character_facet_type type);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
251
src/boost/libs/locale/src/posix/codecvt.cpp
Normal file
251
src/boost/libs/locale/src/posix/codecvt.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "../encoding/conv.hpp"
|
||||
#include <boost/locale/util.hpp>
|
||||
#include "all_generator.hpp"
|
||||
|
||||
#include <errno.h>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include "codecvt.hpp"
|
||||
|
||||
#ifdef BOOST_LOCALE_WITH_ICONV
|
||||
#include "../util/iconv.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
|
||||
#ifdef BOOST_LOCALE_WITH_ICONV
|
||||
class mb2_iconv_converter : public util::base_converter {
|
||||
public:
|
||||
|
||||
mb2_iconv_converter(std::string const &encoding) :
|
||||
encoding_(encoding),
|
||||
to_utf_((iconv_t)(-1)),
|
||||
from_utf_((iconv_t)(-1))
|
||||
{
|
||||
iconv_t d = (iconv_t)(-1);
|
||||
std::vector<uint32_t> first_byte_table;
|
||||
try {
|
||||
d = iconv_open(utf32_encoding(),encoding.c_str());
|
||||
if(d == (iconv_t)(-1)) {
|
||||
throw std::runtime_error("Unsupported encoding" + encoding);
|
||||
}
|
||||
for(unsigned c=0;c<256;c++) {
|
||||
char ibuf[2] = { char(c) , 0 };
|
||||
char *in = ibuf;
|
||||
size_t insize =2;
|
||||
uint32_t obuf[2] = {illegal,illegal};
|
||||
char *out = reinterpret_cast<char *>(obuf);
|
||||
size_t outsize = 8;
|
||||
// Basic sigle codepoint conversion
|
||||
call_iconv(d,&in,&insize,&out,&outsize);
|
||||
if(insize == 0 && outsize == 0 && obuf[1] == 0) {
|
||||
first_byte_table.push_back(obuf[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Test if this is illegal first byte or incomplete
|
||||
in = ibuf;
|
||||
insize = 1;
|
||||
out = reinterpret_cast<char *>(obuf);
|
||||
outsize = 8;
|
||||
call_iconv(d,0,0,0,0);
|
||||
size_t res = call_iconv(d,&in,&insize,&out,&outsize);
|
||||
|
||||
// Now if this single byte starts a sequence we add incomplete
|
||||
// to know to ask that we need two bytes, othewise it may only be
|
||||
// illegal
|
||||
|
||||
uint32_t point;
|
||||
if(res == (size_t)(-1) && errno == EINVAL)
|
||||
point = incomplete;
|
||||
else
|
||||
point = illegal;
|
||||
first_byte_table.push_back(point);
|
||||
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
if(d!=(iconv_t)(-1))
|
||||
iconv_close(d);
|
||||
throw;
|
||||
}
|
||||
iconv_close(d);
|
||||
first_byte_table_.reset(new std::vector<uint32_t>());
|
||||
first_byte_table_->swap(first_byte_table);
|
||||
}
|
||||
|
||||
mb2_iconv_converter(mb2_iconv_converter const &other) :
|
||||
first_byte_table_(other.first_byte_table_),
|
||||
encoding_(other.encoding_),
|
||||
to_utf_((iconv_t)(-1)),
|
||||
from_utf_((iconv_t)(-1))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~mb2_iconv_converter()
|
||||
{
|
||||
if(to_utf_ != (iconv_t)(-1))
|
||||
iconv_close(to_utf_);
|
||||
if(from_utf_ != (iconv_t)(-1))
|
||||
iconv_close(from_utf_);
|
||||
|
||||
}
|
||||
|
||||
virtual bool is_thread_safe() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual mb2_iconv_converter *clone() const
|
||||
{
|
||||
return new mb2_iconv_converter(*this);
|
||||
}
|
||||
|
||||
uint32_t to_unicode(char const *&begin,char const *end)
|
||||
{
|
||||
if(begin == end)
|
||||
return incomplete;
|
||||
|
||||
unsigned char seq0 = *begin;
|
||||
uint32_t index = (*first_byte_table_)[seq0];
|
||||
if(index == illegal)
|
||||
return illegal;
|
||||
if(index != incomplete) {
|
||||
begin++;
|
||||
return index;
|
||||
}
|
||||
else if(begin+1 == end)
|
||||
return incomplete;
|
||||
|
||||
open(to_utf_,utf32_encoding(),encoding_.c_str());
|
||||
|
||||
// maybe illegal or may be double byte
|
||||
|
||||
char inseq[3] = { static_cast<char>(seq0) , begin[1], 0};
|
||||
char *inbuf = inseq;
|
||||
size_t insize = 3;
|
||||
uint32_t result[2] = { illegal, illegal };
|
||||
size_t outsize = 8;
|
||||
char *outbuf = reinterpret_cast<char*>(result);
|
||||
call_iconv(to_utf_,&inbuf,&insize,&outbuf,&outsize);
|
||||
if(outsize == 0 && insize == 0 && result[1]==0 ) {
|
||||
begin+=2;
|
||||
return result[0];
|
||||
}
|
||||
return illegal;
|
||||
}
|
||||
|
||||
uint32_t from_unicode(uint32_t cp,char *begin,char const *end)
|
||||
{
|
||||
if(cp == 0) {
|
||||
if(begin!=end) {
|
||||
*begin = 0;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return incomplete;
|
||||
}
|
||||
}
|
||||
|
||||
open(from_utf_,encoding_.c_str(),utf32_encoding());
|
||||
|
||||
uint32_t codepoints[2] = {cp,0};
|
||||
char *inbuf = reinterpret_cast<char *>(codepoints);
|
||||
size_t insize = sizeof(codepoints);
|
||||
char outseq[3] = {0};
|
||||
char *outbuf = outseq;
|
||||
size_t outsize = 3;
|
||||
|
||||
call_iconv(from_utf_,&inbuf,&insize,&outbuf,&outsize);
|
||||
|
||||
if(insize != 0 || outsize > 1)
|
||||
return illegal;
|
||||
size_t len = 2 - outsize ;
|
||||
size_t reminder = end - begin;
|
||||
if(reminder < len)
|
||||
return incomplete;
|
||||
for(unsigned i=0;i<len;i++)
|
||||
*begin++ = outseq[i];
|
||||
return len;
|
||||
}
|
||||
|
||||
void open(iconv_t &d,char const *to,char const *from)
|
||||
{
|
||||
if(d!=(iconv_t)(-1))
|
||||
return;
|
||||
d=iconv_open(to,from);
|
||||
}
|
||||
|
||||
static char const *utf32_encoding()
|
||||
{
|
||||
union { char one; uint32_t value; } test;
|
||||
test.value = 1;
|
||||
if(test.one == 1)
|
||||
return "UTF-32LE";
|
||||
else
|
||||
return "UTF-32BE";
|
||||
}
|
||||
|
||||
virtual int max_len() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<std::vector<uint32_t> > first_byte_table_;
|
||||
std::string encoding_;
|
||||
iconv_t to_utf_;
|
||||
iconv_t from_utf_;
|
||||
};
|
||||
|
||||
std::auto_ptr<util::base_converter> create_iconv_converter(std::string const &encoding)
|
||||
{
|
||||
std::auto_ptr<util::base_converter> cvt;
|
||||
try {
|
||||
cvt.reset(new mb2_iconv_converter(encoding));
|
||||
}
|
||||
catch(std::exception const &e) {
|
||||
// Nothing to do, just retrun empty cvt
|
||||
}
|
||||
return cvt;
|
||||
}
|
||||
|
||||
#else // no iconv
|
||||
std::auto_ptr<util::base_converter> create_iconv_converter(std::string const &/*encoding*/)
|
||||
{
|
||||
std::auto_ptr<util::base_converter> cvt;
|
||||
return cvt;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::locale create_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type)
|
||||
{
|
||||
std::auto_ptr<util::base_converter> cvt;
|
||||
if(conv::impl::normalize_encoding(encoding.c_str())=="utf8")
|
||||
cvt = util::create_utf8_converter();
|
||||
else {
|
||||
cvt = util::create_simple_converter(encoding);
|
||||
if(!cvt.get())
|
||||
cvt = create_iconv_converter(encoding);
|
||||
}
|
||||
return util::create_codecvt(in,cvt,type);
|
||||
}
|
||||
|
||||
} // impl_posix
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
28
src/boost/libs/locale/src/posix/codecvt.hpp
Normal file
28
src/boost/libs/locale/src/posix/codecvt.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_POSIX_CODECVT_HPP
|
||||
#define BOOST_LOCALE_IMPL_POSIX_CODECVT_HPP
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/locale/util.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
BOOST_LOCALE_DECL
|
||||
std::auto_ptr<util::base_converter> create_iconv_converter(std::string const &encoding);
|
||||
|
||||
} // impl_posix
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
121
src/boost/libs/locale/src/posix/collate.cpp
Normal file
121
src/boost/libs/locale/src/posix/collate.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <ios>
|
||||
#include <vector>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include "../shared/mo_hash.hpp"
|
||||
|
||||
#include "all_generator.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
|
||||
template<typename CharType>
|
||||
struct coll_traits;
|
||||
|
||||
template<>
|
||||
struct coll_traits<char> {
|
||||
static size_t xfrm(char *out,char const *in,size_t n,locale_t l)
|
||||
{
|
||||
return strxfrm_l(out,in,n,l);
|
||||
}
|
||||
static size_t coll(char const *left,char const *right,locale_t l)
|
||||
{
|
||||
return strcoll_l(left,right,l);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct coll_traits<wchar_t> {
|
||||
static size_t xfrm(wchar_t *out,wchar_t const *in,size_t n,locale_t l)
|
||||
{
|
||||
return wcsxfrm_l(out,in,n,l);
|
||||
}
|
||||
static size_t coll(wchar_t const *left,wchar_t const *right,locale_t l)
|
||||
{
|
||||
return wcscoll_l(left,right,l);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class collator : public std::collate<CharType> {
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
collator(boost::shared_ptr<locale_t> l,size_t refs = 0) :
|
||||
std::collate<CharType>(refs),
|
||||
lc_(l)
|
||||
{
|
||||
}
|
||||
virtual ~collator()
|
||||
{
|
||||
}
|
||||
virtual int do_compare(char_type const *lb,char_type const *le,char_type const *rb,char_type const *re) const
|
||||
{
|
||||
string_type left(lb,le-lb);
|
||||
string_type right(rb,re-rb);
|
||||
int res = coll_traits<char_type>::coll(left.c_str(),right.c_str(),*lc_);
|
||||
if(res < 0)
|
||||
return -1;
|
||||
if(res > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
virtual long do_hash(char_type const *b,char_type const *e) const
|
||||
{
|
||||
string_type s(do_transform(b,e));
|
||||
char const *begin = reinterpret_cast<char const *>(s.c_str());
|
||||
char const *end = begin + s.size() * sizeof(char_type);
|
||||
return gnu_gettext::pj_winberger_hash_function(begin,end);
|
||||
}
|
||||
virtual string_type do_transform(char_type const *b,char_type const *e) const
|
||||
{
|
||||
string_type s(b,e-b);
|
||||
std::vector<char_type> buf((e-b)*2+1);
|
||||
size_t n = coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),buf.size(),*lc_);
|
||||
if(n>buf.size()) {
|
||||
buf.resize(n);
|
||||
coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),n,*lc_);
|
||||
}
|
||||
return string_type(&buf.front(),n);
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
|
||||
std::locale create_collate( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(in,new collator<char>(lc));
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new collator<wchar_t>(lc));
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
162
src/boost/libs/locale/src/posix/converter.cpp
Normal file
162
src/boost/libs/locale/src/posix/converter.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include <wctype.h>
|
||||
#include <ctype.h>
|
||||
#include <langinfo.h>
|
||||
#include "all_generator.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
|
||||
template<typename CharType>
|
||||
struct case_traits;
|
||||
|
||||
template<>
|
||||
struct case_traits<char> {
|
||||
static char lower(char c,locale_t lc)
|
||||
{
|
||||
return tolower_l(c,lc);
|
||||
}
|
||||
static char upper(char c,locale_t lc)
|
||||
{
|
||||
return toupper_l(c,lc);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct case_traits<wchar_t> {
|
||||
static wchar_t lower(wchar_t c,locale_t lc)
|
||||
{
|
||||
return towlower_l(c,lc);
|
||||
}
|
||||
static wchar_t upper(wchar_t c,locale_t lc)
|
||||
{
|
||||
return towupper_l(c,lc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class std_converter : public converter<CharType>
|
||||
{
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
typedef std::ctype<char_type> ctype_type;
|
||||
std_converter(boost::shared_ptr<locale_t> lc,size_t refs = 0) :
|
||||
converter<CharType>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const
|
||||
{
|
||||
switch(how) {
|
||||
case converter_base::upper_case:
|
||||
{
|
||||
string_type res;
|
||||
res.reserve(end-begin);
|
||||
while(begin!=end) {
|
||||
res+=case_traits<char_type>::upper(*begin++,*lc_);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
case converter_base::lower_case:
|
||||
case converter_base::case_folding:
|
||||
{
|
||||
string_type res;
|
||||
res.reserve(end-begin);
|
||||
while(begin!=end) {
|
||||
res+=case_traits<char_type>::lower(*begin++,*lc_);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
default:
|
||||
return string_type(begin,end-begin);
|
||||
}
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
class utf8_converter : public converter<char> {
|
||||
public:
|
||||
utf8_converter(boost::shared_ptr<locale_t> lc,size_t refs = 0) :
|
||||
converter<char>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const
|
||||
{
|
||||
switch(how) {
|
||||
case upper_case:
|
||||
{
|
||||
std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
|
||||
std::wstring wres;
|
||||
wres.reserve(tmp.size());
|
||||
for(unsigned i=0;i<tmp.size();i++)
|
||||
wres+=towupper_l(tmp[i],*lc_);
|
||||
return conv::from_utf<wchar_t>(wres,"UTF-8");
|
||||
}
|
||||
|
||||
case lower_case:
|
||||
case case_folding:
|
||||
{
|
||||
std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
|
||||
std::wstring wres;
|
||||
wres.reserve(tmp.size());
|
||||
for(unsigned i=0;i<tmp.size();i++)
|
||||
wres+=towlower_l(tmp[i],*lc_);
|
||||
return conv::from_utf<wchar_t>(wres,"UTF-8");
|
||||
}
|
||||
default:
|
||||
return std::string(begin,end-begin);
|
||||
}
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
std::locale create_convert( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
{
|
||||
std::string encoding = nl_langinfo_l(CODESET,*lc);
|
||||
for(unsigned i=0;i<encoding.size();i++)
|
||||
if('A'<=encoding[i] && encoding[i]<='Z')
|
||||
encoding[i]=encoding[i]-'A'+'a';
|
||||
if(encoding=="utf-8" || encoding=="utf8" || encoding=="utf_8") {
|
||||
return std::locale(in,new utf8_converter(lc));
|
||||
}
|
||||
return std::locale(in,new std_converter<char>(lc));
|
||||
}
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new std_converter<wchar_t>(lc));
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace impl_std
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
511
src/boost/libs/locale/src/posix/numeric.cpp
Normal file
511
src/boost/libs/locale/src/posix/numeric.cpp
Normal file
@@ -0,0 +1,511 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <wctype.h>
|
||||
#include <ctype.h>
|
||||
#include <langinfo.h>
|
||||
#include <monetary.h>
|
||||
#include <errno.h>
|
||||
#include "../util/numeric.hpp"
|
||||
#include "all_generator.hpp"
|
||||
|
||||
|
||||
#if defined(__linux) || defined(__APPLE__)
|
||||
#define BOOST_LOCALE_HAVE_WCSFTIME_L
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
|
||||
template<typename CharType>
|
||||
class num_format : public util::base_num_format<CharType>
|
||||
{
|
||||
public:
|
||||
typedef typename std::num_put<CharType>::iter_type iter_type;
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
typedef CharType char_type;
|
||||
|
||||
num_format(boost::shared_ptr<locale_t> lc,size_t refs = 0) :
|
||||
util::base_num_format<CharType>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
|
||||
virtual iter_type do_format_currency(bool intl,iter_type out,std::ios_base &/*ios*/,char_type /*fill*/,long double val) const
|
||||
{
|
||||
char buf[4]={};
|
||||
char const *format = intl ? "%i" : "%n";
|
||||
errno=0;
|
||||
ssize_t n = strfmon_l(buf,sizeof(buf),*lc_,format,static_cast<double>(val));
|
||||
if(n >= 0)
|
||||
return write_it(out,buf,n);
|
||||
|
||||
for(std::vector<char> tmp(sizeof(buf)*2);tmp.size() <= 4098;tmp.resize(tmp.size()*2)) {
|
||||
n = strfmon_l(&tmp.front(),tmp.size(),*lc_,format,static_cast<double>(val));
|
||||
if(n >= 0)
|
||||
return write_it(out,&tmp.front(),n);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,char const *ptr,size_t n) const
|
||||
{
|
||||
for(size_t i=0;i<n;i++)
|
||||
*out++ = *ptr++;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,char const *ptr,size_t n) const
|
||||
{
|
||||
std::wstring tmp = conv::to_utf<wchar_t>(ptr,ptr+n,nl_langinfo_l(CODESET,*lc_));
|
||||
for(size_t i=0;i<tmp.size();i++)
|
||||
*out++ = tmp[i];
|
||||
return out;
|
||||
}
|
||||
private:
|
||||
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
|
||||
}; /// num_format
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
struct ftime_traits;
|
||||
|
||||
template<>
|
||||
struct ftime_traits<char> {
|
||||
static std::string ftime(char const *format,const struct tm *t,locale_t lc)
|
||||
{
|
||||
char buf[16];
|
||||
size_t n=strftime_l(buf,sizeof(buf),format,t,lc);
|
||||
if(n == 0) {
|
||||
// should be big enough
|
||||
//
|
||||
// Note standard specifies that in case of the error
|
||||
// the function returns 0, however 0 may be actually
|
||||
// valid output value of for example empty format or an
|
||||
// output of %p in some locales
|
||||
//
|
||||
// Thus we try to guess that 1024 would be enough.
|
||||
std::vector<char> v(1024);
|
||||
n = strftime_l(&v.front(),1024,format,t,lc);
|
||||
return std::string(&v.front(),n);
|
||||
}
|
||||
return std::string(buf,n);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ftime_traits<wchar_t> {
|
||||
static std::wstring ftime(wchar_t const *format,const struct tm *t,locale_t lc)
|
||||
{
|
||||
#ifdef HAVE_WCSFTIME_L
|
||||
wchar_t buf[16];
|
||||
size_t n=wcsftime_l(buf,sizeof(buf)/sizeof(buf[0]),format,t,lc);
|
||||
if(n == 0) {
|
||||
// should be big enough
|
||||
//
|
||||
// Note standard specifies that in case of the error
|
||||
// the function returns 0, however 0 may be actually
|
||||
// valid output value of for example empty format or an
|
||||
// output of %p in some locales
|
||||
//
|
||||
// Thus we try to guess that 1024 would be enough.
|
||||
std::vector<wchar_t> v(1024);
|
||||
n = wcsftime_l(&v.front(),1024,format,t,lc);
|
||||
}
|
||||
return std::wstring(&v.front(),n);
|
||||
#else
|
||||
std::string enc = nl_langinfo_l(CODESET,lc);
|
||||
std::string nformat = conv::from_utf<wchar_t>(format,enc);
|
||||
std::string nres = ftime_traits<char>::ftime(nformat.c_str(),t,lc);
|
||||
return conv::to_utf<wchar_t>(nres,enc);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class time_put_posix : public std::time_put<CharType> {
|
||||
public:
|
||||
time_put_posix(boost::shared_ptr<locale_t> lc, size_t refs = 0) :
|
||||
std::time_put<CharType>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual ~time_put_posix()
|
||||
{
|
||||
}
|
||||
typedef typename std::time_put<CharType>::iter_type iter_type;
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType /*fill*/,std::tm const *tm,char format,char modifier) const
|
||||
{
|
||||
char_type fmt[4] = { '%' , modifier != 0 ? modifier : format , modifier == 0 ? '\0' : format };
|
||||
string_type res = ftime_traits<char_type>::ftime(fmt,tm,*lc_);
|
||||
for(unsigned i=0;i<res.size();i++)
|
||||
*out++ = res[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class ctype_posix;
|
||||
|
||||
template<>
|
||||
class ctype_posix<char> : public std::ctype<char> {
|
||||
public:
|
||||
|
||||
ctype_posix(boost::shared_ptr<locale_t> lc)
|
||||
{
|
||||
lc_ = lc;
|
||||
}
|
||||
|
||||
bool do_is(mask m,char c) const
|
||||
{
|
||||
if((m & space) && isspace_l(c,*lc_))
|
||||
return true;
|
||||
if((m & print) && isprint_l(c,*lc_))
|
||||
return true;
|
||||
if((m & cntrl) && iscntrl_l(c,*lc_))
|
||||
return true;
|
||||
if((m & upper) && isupper_l(c,*lc_))
|
||||
return true;
|
||||
if((m & lower) && islower_l(c,*lc_))
|
||||
return true;
|
||||
if((m & alpha) && isalpha_l(c,*lc_))
|
||||
return true;
|
||||
if((m & digit) && isdigit_l(c,*lc_))
|
||||
return true;
|
||||
if((m & xdigit) && isxdigit_l(c,*lc_))
|
||||
return true;
|
||||
if((m & punct) && ispunct_l(c,*lc_))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
char const *do_is(char const *begin,char const *end,mask *m) const
|
||||
{
|
||||
while(begin!=end) {
|
||||
char c= *begin++;
|
||||
int r=0;
|
||||
if(isspace_l(c,*lc_))
|
||||
r|=space;
|
||||
if(isprint_l(c,*lc_))
|
||||
r|=cntrl;
|
||||
if(iscntrl_l(c,*lc_))
|
||||
r|=space;
|
||||
if(isupper_l(c,*lc_))
|
||||
r|=upper;
|
||||
if(islower_l(c,*lc_))
|
||||
r|=lower;
|
||||
if(isalpha_l(c,*lc_))
|
||||
r|=alpha;
|
||||
if(isdigit_l(c,*lc_))
|
||||
r|=digit;
|
||||
if(isxdigit_l(c,*lc_))
|
||||
r|=xdigit;
|
||||
if(ispunct_l(c,*lc_))
|
||||
r|=punct;
|
||||
// r actually should be mask, but some standard
|
||||
// libraries (like STLPort)
|
||||
// do not define operator | properly so using int+cast
|
||||
*m++ = static_cast<mask>(r);
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
char const *do_scan_is(mask m,char const *begin,char const *end) const
|
||||
{
|
||||
while(begin!=end)
|
||||
if(do_is(m,*begin))
|
||||
return begin;
|
||||
return begin;
|
||||
}
|
||||
char const *do_scan_not(mask m,char const *begin,char const *end) const
|
||||
{
|
||||
while(begin!=end)
|
||||
if(!do_is(m,*begin))
|
||||
return begin;
|
||||
return begin;
|
||||
}
|
||||
char toupper(char c) const
|
||||
{
|
||||
return toupper_l(c,*lc_);
|
||||
}
|
||||
char const *toupper(char *begin,char const *end) const
|
||||
{
|
||||
for(;begin!=end;begin++)
|
||||
*begin = toupper_l(*begin,*lc_);
|
||||
return begin;
|
||||
}
|
||||
char tolower(char c) const
|
||||
{
|
||||
return tolower_l(c,*lc_);
|
||||
}
|
||||
char const *tolower(char *begin,char const *end) const
|
||||
{
|
||||
for(;begin!=end;begin++)
|
||||
*begin = tolower_l(*begin,*lc_);
|
||||
return begin;
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
template<>
|
||||
class ctype_posix<wchar_t> : public std::ctype<wchar_t> {
|
||||
public:
|
||||
ctype_posix(boost::shared_ptr<locale_t> lc)
|
||||
{
|
||||
lc_ = lc;
|
||||
}
|
||||
|
||||
bool do_is(mask m,wchar_t c) const
|
||||
{
|
||||
if((m & space) && iswspace_l(c,*lc_))
|
||||
return true;
|
||||
if((m & print) && iswprint_l(c,*lc_))
|
||||
return true;
|
||||
if((m & cntrl) && iswcntrl_l(c,*lc_))
|
||||
return true;
|
||||
if((m & upper) && iswupper_l(c,*lc_))
|
||||
return true;
|
||||
if((m & lower) && iswlower_l(c,*lc_))
|
||||
return true;
|
||||
if((m & alpha) && iswalpha_l(c,*lc_))
|
||||
return true;
|
||||
if((m & digit) && iswdigit_l(c,*lc_))
|
||||
return true;
|
||||
if((m & xdigit) && iswxdigit_l(c,*lc_))
|
||||
return true;
|
||||
if((m & punct) && iswpunct_l(c,*lc_))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
wchar_t const *do_is(wchar_t const *begin,wchar_t const *end,mask *m) const
|
||||
{
|
||||
while(begin!=end) {
|
||||
wchar_t c= *begin++;
|
||||
int r=0;
|
||||
if(iswspace_l(c,*lc_))
|
||||
r|=space;
|
||||
if(iswprint_l(c,*lc_))
|
||||
r|=cntrl;
|
||||
if(iswcntrl_l(c,*lc_))
|
||||
r|=space;
|
||||
if(iswupper_l(c,*lc_))
|
||||
r|=upper;
|
||||
if(iswlower_l(c,*lc_))
|
||||
r|=lower;
|
||||
if(iswalpha_l(c,*lc_))
|
||||
r|=alpha;
|
||||
if(iswdigit_l(c,*lc_))
|
||||
r|=digit;
|
||||
if(iswxdigit_l(c,*lc_))
|
||||
r|=xdigit;
|
||||
if(iswpunct_l(c,*lc_))
|
||||
r|=punct;
|
||||
// r actually should be mask, but some standard
|
||||
// libraries (like STLPort)
|
||||
// do not define operator | properly so using int+cast
|
||||
*m++ = static_cast<mask>(r);
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
wchar_t const *do_scan_is(mask m,wchar_t const *begin,wchar_t const *end) const
|
||||
{
|
||||
while(begin!=end)
|
||||
if(do_is(m,*begin))
|
||||
return begin;
|
||||
return begin;
|
||||
}
|
||||
wchar_t const *do_scan_not(mask m,wchar_t const *begin,wchar_t const *end) const
|
||||
{
|
||||
while(begin!=end)
|
||||
if(!do_is(m,*begin))
|
||||
return begin;
|
||||
return begin;
|
||||
}
|
||||
wchar_t toupper(wchar_t c) const
|
||||
{
|
||||
return towupper_l(c,*lc_);
|
||||
}
|
||||
wchar_t const *toupper(wchar_t *begin,wchar_t const *end) const
|
||||
{
|
||||
for(;begin!=end;begin++)
|
||||
*begin = towupper_l(*begin,*lc_);
|
||||
return begin;
|
||||
}
|
||||
wchar_t tolower(wchar_t c) const
|
||||
{
|
||||
return tolower_l(c,*lc_);
|
||||
}
|
||||
wchar_t const *tolower(wchar_t *begin,wchar_t const *end) const
|
||||
{
|
||||
for(;begin!=end;begin++)
|
||||
*begin = tolower_l(*begin,*lc_);
|
||||
return begin;
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct basic_numpunct {
|
||||
std::string grouping;
|
||||
std::string thousands_sep;
|
||||
std::string decimal_point;
|
||||
basic_numpunct() :
|
||||
decimal_point(".")
|
||||
{
|
||||
}
|
||||
basic_numpunct(locale_t lc)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
lconv *cv = localeconv_l(lc);
|
||||
grouping = cv->grouping;
|
||||
thousands_sep = cv->thousands_sep;
|
||||
decimal_point = cv->decimal_point;
|
||||
#else
|
||||
thousands_sep = nl_langinfo_l(THOUSEP,lc);
|
||||
decimal_point = nl_langinfo_l(RADIXCHAR,lc);
|
||||
#ifdef GROUPING
|
||||
grouping = nl_langinfo_l(GROUPING,lc);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class num_punct_posix : public std::numpunct<CharType> {
|
||||
public:
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
num_punct_posix(locale_t lc,size_t refs = 0) :
|
||||
std::numpunct<CharType>(refs)
|
||||
{
|
||||
basic_numpunct np(lc);
|
||||
to_str(np.thousands_sep,thousands_sep_,lc);
|
||||
to_str(np.decimal_point,decimal_point_,lc);
|
||||
grouping_ = np.grouping;
|
||||
if(thousands_sep_.size() > 1)
|
||||
grouping_ = std::string();
|
||||
if(decimal_point_.size() > 1)
|
||||
decimal_point_ = CharType('.');
|
||||
}
|
||||
void to_str(std::string &s1,std::string &s2,locale_t /*lc*/)
|
||||
{
|
||||
s2.swap(s1);
|
||||
}
|
||||
void to_str(std::string &s1,std::wstring &s2,locale_t lc)
|
||||
{
|
||||
s2=conv::to_utf<wchar_t>(s1,nl_langinfo_l(CODESET,lc));
|
||||
}
|
||||
virtual CharType do_decimal_point() const
|
||||
{
|
||||
return *decimal_point_.c_str();
|
||||
}
|
||||
virtual CharType do_thousands_sep() const
|
||||
{
|
||||
return *thousands_sep_.c_str();
|
||||
}
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
return grouping_;
|
||||
}
|
||||
virtual string_type do_truename() const
|
||||
{
|
||||
static const char t[]="true";
|
||||
return string_type(t,t+sizeof(t)-1);
|
||||
}
|
||||
virtual string_type do_falsename() const
|
||||
{
|
||||
static const char t[]="false";
|
||||
return string_type(t,t+sizeof(t)-1);
|
||||
}
|
||||
private:
|
||||
string_type decimal_point_;
|
||||
string_type thousands_sep_;
|
||||
std::string grouping_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
std::locale create_formatting_impl(std::locale const &in,boost::shared_ptr<locale_t> lc)
|
||||
{
|
||||
std::locale tmp = std::locale(in,new num_punct_posix<CharType>(*lc));
|
||||
tmp = std::locale(tmp,new ctype_posix<CharType>(lc));
|
||||
tmp = std::locale(tmp,new time_put_posix<CharType>(lc));
|
||||
tmp = std::locale(tmp,new num_format<CharType>(lc));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
std::locale create_parsing_impl(std::locale const &in,boost::shared_ptr<locale_t> lc)
|
||||
{
|
||||
std::locale tmp = std::locale(in,new num_punct_posix<CharType>(*lc));
|
||||
tmp = std::locale(tmp,new ctype_posix<CharType>(lc));
|
||||
tmp = std::locale(tmp,new util::base_num_parse<CharType>());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
std::locale create_formatting( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return create_formatting_impl<char>(in,lc);
|
||||
case wchar_t_facet:
|
||||
return create_formatting_impl<wchar_t>(in,lc);
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
std::locale create_parsing( std::locale const &in,
|
||||
boost::shared_ptr<locale_t> lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return create_parsing_impl<char>(in,lc);
|
||||
case wchar_t_facet:
|
||||
return create_parsing_impl<wchar_t>(in,lc);
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
181
src/boost/libs/locale/src/posix/posix_backend.cpp
Normal file
181
src/boost/libs/locale/src/posix/posix_backend.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/locale/gnu_gettext.hpp>
|
||||
#include <boost/locale/info.hpp>
|
||||
#include "all_generator.hpp"
|
||||
#include "posix_backend.hpp"
|
||||
|
||||
#include "../util/locale_data.hpp"
|
||||
#include "../util/gregorian.hpp"
|
||||
#include <boost/locale/util.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <langinfo.h>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_posix {
|
||||
|
||||
class posix_localization_backend : public localization_backend {
|
||||
public:
|
||||
posix_localization_backend() :
|
||||
invalid_(true)
|
||||
{
|
||||
}
|
||||
posix_localization_backend(posix_localization_backend const &other) :
|
||||
localization_backend(),
|
||||
paths_(other.paths_),
|
||||
domains_(other.domains_),
|
||||
locale_id_(other.locale_id_),
|
||||
invalid_(true)
|
||||
{
|
||||
}
|
||||
virtual posix_localization_backend *clone() const
|
||||
{
|
||||
return new posix_localization_backend(*this);
|
||||
}
|
||||
|
||||
void set_option(std::string const &name,std::string const &value)
|
||||
{
|
||||
invalid_ = true;
|
||||
if(name=="locale")
|
||||
locale_id_ = value;
|
||||
else if(name=="message_path")
|
||||
paths_.push_back(value);
|
||||
else if(name=="message_application")
|
||||
domains_.push_back(value);
|
||||
|
||||
}
|
||||
void clear_options()
|
||||
{
|
||||
invalid_ = true;
|
||||
locale_id_.clear();
|
||||
paths_.clear();
|
||||
domains_.clear();
|
||||
}
|
||||
|
||||
static void free_locale_by_ptr(locale_t *lc)
|
||||
{
|
||||
freelocale(*lc);
|
||||
delete lc;
|
||||
}
|
||||
|
||||
void prepare_data()
|
||||
{
|
||||
if(!invalid_)
|
||||
return;
|
||||
invalid_ = false;
|
||||
lc_.reset();
|
||||
real_id_ = locale_id_;
|
||||
if(real_id_.empty())
|
||||
real_id_ = util::get_system_locale();
|
||||
|
||||
locale_t tmp = newlocale(LC_ALL_MASK,real_id_.c_str(),0);
|
||||
|
||||
if(!tmp) {
|
||||
tmp=newlocale(LC_ALL_MASK,"C",0);
|
||||
}
|
||||
if(!tmp) {
|
||||
throw std::runtime_error("newlocale failed");
|
||||
}
|
||||
|
||||
locale_t *tmp_p = 0;
|
||||
|
||||
try {
|
||||
tmp_p = new locale_t();
|
||||
}
|
||||
catch(...) {
|
||||
freelocale(tmp);
|
||||
throw;
|
||||
}
|
||||
|
||||
*tmp_p = tmp;
|
||||
lc_ = boost::shared_ptr<locale_t>(tmp_p,free_locale_by_ptr);
|
||||
}
|
||||
|
||||
virtual std::locale install(std::locale const &base,
|
||||
locale_category_type category,
|
||||
character_facet_type type = nochar_facet)
|
||||
{
|
||||
prepare_data();
|
||||
|
||||
switch(category) {
|
||||
case convert_facet:
|
||||
return create_convert(base,lc_,type);
|
||||
case collation_facet:
|
||||
return create_collate(base,lc_,type);
|
||||
case formatting_facet:
|
||||
return create_formatting(base,lc_,type);
|
||||
case parsing_facet:
|
||||
return create_parsing(base,lc_,type);
|
||||
case codepage_facet:
|
||||
return create_codecvt(base,nl_langinfo_l(CODESET,*lc_),type);
|
||||
case calendar_facet:
|
||||
{
|
||||
util::locale_data inf;
|
||||
inf.parse(real_id_);
|
||||
return util::install_gregorian_calendar(base,inf.country);
|
||||
}
|
||||
case message_facet:
|
||||
{
|
||||
gnu_gettext::messages_info minf;
|
||||
util::locale_data inf;
|
||||
inf.parse(real_id_);
|
||||
minf.language = inf.language;
|
||||
minf.country = inf.country;
|
||||
minf.variant = inf.variant;
|
||||
minf.encoding = inf.encoding;
|
||||
std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
|
||||
minf.paths = paths_;
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
|
||||
case wchar_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
case char16_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
|
||||
#endif
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
case char32_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
|
||||
#endif
|
||||
default:
|
||||
return base;
|
||||
}
|
||||
}
|
||||
case information_facet:
|
||||
return util::create_info(base,real_id_);
|
||||
default:
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::string> paths_;
|
||||
std::vector<std::string> domains_;
|
||||
std::string locale_id_;
|
||||
std::string real_id_;
|
||||
|
||||
bool invalid_;
|
||||
boost::shared_ptr<locale_t> lc_;
|
||||
};
|
||||
|
||||
localization_backend *create_localization_backend()
|
||||
{
|
||||
return new posix_localization_backend();
|
||||
}
|
||||
|
||||
} // impl posix
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
20
src/boost/libs/locale/src/posix/posix_backend.hpp
Normal file
20
src/boost/libs/locale/src/posix/posix_backend.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP
|
||||
#define BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
class localization_backend;
|
||||
namespace impl_posix {
|
||||
localization_backend *create_localization_backend();
|
||||
} // impl_std
|
||||
} // locale
|
||||
} // boost
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
468
src/boost/libs/locale/src/shared/date_time.cpp
Normal file
468
src/boost/libs/locale/src/shared/date_time.cpp
Normal file
@@ -0,0 +1,468 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/date_time.hpp>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <math.h>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
|
||||
using namespace period;
|
||||
|
||||
/////////////////////////
|
||||
// Calendar
|
||||
////////////////////////
|
||||
|
||||
calendar::calendar(std::locale const &l,std::string const &zone) :
|
||||
locale_(l),
|
||||
tz_(zone),
|
||||
impl_(std::use_facet<calendar_facet>(l).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(tz_);
|
||||
}
|
||||
|
||||
calendar::calendar(std::string const &zone) :
|
||||
tz_(zone),
|
||||
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(tz_);
|
||||
}
|
||||
|
||||
|
||||
calendar::calendar(std::locale const &l) :
|
||||
locale_(l),
|
||||
tz_(time_zone::global()),
|
||||
impl_(std::use_facet<calendar_facet>(l).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(tz_);
|
||||
}
|
||||
|
||||
calendar::calendar(std::ios_base &ios) :
|
||||
locale_(ios.getloc()),
|
||||
tz_(ios_info::get(ios).time_zone()),
|
||||
impl_(std::use_facet<calendar_facet>(locale_).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(tz_);
|
||||
|
||||
}
|
||||
|
||||
calendar::calendar() :
|
||||
tz_(time_zone::global()),
|
||||
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(tz_);
|
||||
}
|
||||
|
||||
calendar::~calendar()
|
||||
{
|
||||
}
|
||||
|
||||
calendar::calendar(calendar const &other) :
|
||||
locale_(other.locale_),
|
||||
tz_(other.tz_),
|
||||
impl_(other.impl_->clone())
|
||||
{
|
||||
}
|
||||
|
||||
calendar const &calendar::operator = (calendar const &other)
|
||||
{
|
||||
if(this !=&other) {
|
||||
impl_.reset(other.impl_->clone());
|
||||
locale_ = other.locale_;
|
||||
tz_ = other.tz_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool calendar::is_gregorian() const
|
||||
{
|
||||
return impl_->get_option(abstract_calendar::is_gregorian)!=0;
|
||||
}
|
||||
|
||||
std::string calendar::get_time_zone() const
|
||||
{
|
||||
return tz_;
|
||||
}
|
||||
|
||||
std::locale calendar::get_locale() const
|
||||
{
|
||||
return locale_;
|
||||
}
|
||||
|
||||
int calendar::minimum(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::absolute_minimum);
|
||||
}
|
||||
|
||||
int calendar::greatest_minimum(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::greatest_minimum);
|
||||
}
|
||||
|
||||
int calendar::maximum(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::absolute_maximum);
|
||||
}
|
||||
|
||||
int calendar::least_maximum(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::least_maximum);
|
||||
}
|
||||
|
||||
int calendar::first_day_of_week() const
|
||||
{
|
||||
return impl_->get_value(period::marks::first_day_of_week,abstract_calendar::current);
|
||||
}
|
||||
|
||||
bool calendar::operator==(calendar const &other) const
|
||||
{
|
||||
return impl_->same(other.impl_.get());
|
||||
}
|
||||
|
||||
bool calendar::operator!=(calendar const &other) const
|
||||
{
|
||||
return !(*this==other);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// date_time
|
||||
/////////////////
|
||||
|
||||
date_time::date_time() :
|
||||
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(time_zone::global());
|
||||
}
|
||||
|
||||
date_time::date_time(date_time const &other)
|
||||
{
|
||||
impl_.reset(other.impl_->clone());
|
||||
}
|
||||
|
||||
date_time::date_time(date_time const &other,date_time_period_set const &s)
|
||||
{
|
||||
impl_.reset(other.impl_->clone());
|
||||
for(unsigned i=0;i<s.size();i++) {
|
||||
impl_->set_value(s[i].type.mark(),s[i].value);
|
||||
}
|
||||
impl_->normalize();
|
||||
}
|
||||
|
||||
date_time const &date_time::operator = (date_time const &other)
|
||||
{
|
||||
if(this != &other) {
|
||||
date_time tmp(other);
|
||||
swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time::~date_time()
|
||||
{
|
||||
}
|
||||
|
||||
date_time::date_time(double t) :
|
||||
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(time_zone::global());
|
||||
time(t);
|
||||
}
|
||||
|
||||
date_time::date_time(double t,calendar const &cal) :
|
||||
impl_(cal.impl_->clone())
|
||||
{
|
||||
time(t);
|
||||
}
|
||||
|
||||
date_time::date_time(calendar const &cal) :
|
||||
impl_(cal.impl_->clone())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
date_time::date_time(date_time_period_set const &s) :
|
||||
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
|
||||
{
|
||||
impl_->set_timezone(time_zone::global());
|
||||
for(unsigned i=0;i<s.size();i++) {
|
||||
impl_->set_value(s[i].type.mark(),s[i].value);
|
||||
}
|
||||
impl_->normalize();
|
||||
}
|
||||
date_time::date_time(date_time_period_set const &s,calendar const &cal) :
|
||||
impl_(cal.impl_->clone())
|
||||
{
|
||||
for(unsigned i=0;i<s.size();i++) {
|
||||
impl_->set_value(s[i].type.mark(),s[i].value);
|
||||
}
|
||||
impl_->normalize();
|
||||
}
|
||||
|
||||
date_time const &date_time::operator=(date_time_period_set const &s)
|
||||
{
|
||||
for(unsigned i=0;i<s.size();i++)
|
||||
impl_->set_value(s[i].type.mark(),s[i].value);
|
||||
impl_->normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void date_time::set(period_type f,int v)
|
||||
{
|
||||
impl_->set_value(f.mark(),v);
|
||||
impl_->normalize();
|
||||
}
|
||||
|
||||
int date_time::get(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::current);
|
||||
}
|
||||
|
||||
date_time date_time::operator+(date_time_period const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp+=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time date_time::operator-(date_time_period const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp-=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time date_time::operator<<(date_time_period const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp<<=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time date_time::operator>>(date_time_period const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp>>=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator+=(date_time_period const &v)
|
||||
{
|
||||
impl_->adjust_value(v.type.mark(),abstract_calendar::move,v.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator-=(date_time_period const &v)
|
||||
{
|
||||
impl_->adjust_value(v.type.mark(),abstract_calendar::move,-v.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator<<=(date_time_period const &v)
|
||||
{
|
||||
impl_->adjust_value(v.type.mark(),abstract_calendar::roll,v.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator>>=(date_time_period const &v)
|
||||
{
|
||||
impl_->adjust_value(v.type.mark(),abstract_calendar::roll,-v.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
date_time date_time::operator+(date_time_period_set const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp+=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time date_time::operator-(date_time_period_set const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp-=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time date_time::operator<<(date_time_period_set const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp<<=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time date_time::operator>>(date_time_period_set const &v) const
|
||||
{
|
||||
date_time tmp(*this);
|
||||
tmp>>=v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator+=(date_time_period_set const &v)
|
||||
{
|
||||
for(unsigned i=0;i<v.size();i++) {
|
||||
*this+=v[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator-=(date_time_period_set const &v)
|
||||
{
|
||||
for(unsigned i=0;i<v.size();i++) {
|
||||
*this-=v[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator<<=(date_time_period_set const &v)
|
||||
{
|
||||
for(unsigned i=0;i<v.size();i++) {
|
||||
*this<<=v[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
date_time const &date_time::operator>>=(date_time_period_set const &v)
|
||||
{
|
||||
for(unsigned i=0;i<v.size();i++) {
|
||||
*this>>=v[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
double date_time::time() const
|
||||
{
|
||||
posix_time ptime = impl_->get_time();
|
||||
return double(ptime.seconds)+1e-9*ptime.nanoseconds;
|
||||
}
|
||||
|
||||
void date_time::time(double v)
|
||||
{
|
||||
double dseconds = floor(v);
|
||||
int64_t seconds = static_cast<int64_t>(dseconds);
|
||||
double fract = v - dseconds;
|
||||
int nano = static_cast<int>(fract * 1e9);
|
||||
if(nano < 0)
|
||||
nano = 0;
|
||||
else if(nano >999999999)
|
||||
nano = 999999999;
|
||||
posix_time ptime;
|
||||
ptime.seconds = seconds;
|
||||
ptime.nanoseconds = nano;
|
||||
impl_->set_time(ptime);
|
||||
}
|
||||
|
||||
namespace {
|
||||
int compare(posix_time const &left,posix_time const &right)
|
||||
{
|
||||
if(left.seconds < right.seconds)
|
||||
return -1;
|
||||
if(left.seconds > right.seconds)
|
||||
return 1;
|
||||
if(left.nanoseconds < right.nanoseconds)
|
||||
return -1;
|
||||
if(left.nanoseconds > right.nanoseconds)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool date_time::operator==(date_time const &other) const
|
||||
{
|
||||
return compare(impl_->get_time(),other.impl_->get_time()) == 0;
|
||||
}
|
||||
|
||||
bool date_time::operator!=(date_time const &other) const
|
||||
{
|
||||
return !(*this==other);
|
||||
}
|
||||
|
||||
bool date_time::operator<(date_time const &other) const
|
||||
{
|
||||
return compare(impl_->get_time(),other.impl_->get_time()) < 0;
|
||||
}
|
||||
|
||||
bool date_time::operator>=(date_time const &other) const
|
||||
{
|
||||
return !(*this<other);
|
||||
}
|
||||
|
||||
bool date_time::operator>(date_time const &other) const
|
||||
{
|
||||
return compare(impl_->get_time(),other.impl_->get_time()) > 0;
|
||||
}
|
||||
|
||||
bool date_time::operator<=(date_time const &other) const
|
||||
{
|
||||
return !(*this>other);
|
||||
}
|
||||
|
||||
void date_time::swap(date_time &other)
|
||||
{
|
||||
impl_.swap(other.impl_);
|
||||
}
|
||||
|
||||
int date_time::difference(date_time const &other,period_type f) const
|
||||
{
|
||||
return impl_->difference(other.impl_.get(),f.mark());
|
||||
}
|
||||
|
||||
int date_time::maximum(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::actual_maximum);
|
||||
}
|
||||
|
||||
int date_time::minimum(period_type f) const
|
||||
{
|
||||
return impl_->get_value(f.mark(),abstract_calendar::actual_minimum);
|
||||
}
|
||||
|
||||
bool date_time::is_in_daylight_saving_time() const
|
||||
{
|
||||
return impl_->get_option(abstract_calendar::is_dst)!=0;
|
||||
}
|
||||
|
||||
namespace time_zone {
|
||||
boost::mutex &tz_mutex()
|
||||
{
|
||||
static boost::mutex m;
|
||||
return m;
|
||||
}
|
||||
std::string &tz_id()
|
||||
{
|
||||
static std::string id;
|
||||
return id;
|
||||
}
|
||||
std::string global()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(tz_mutex());
|
||||
std::string id = tz_id();
|
||||
return id;
|
||||
}
|
||||
std::string global(std::string const &new_id)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(tz_mutex());
|
||||
std::string id = tz_id();
|
||||
tz_id() = new_id;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
188
src/boost/libs/locale/src/shared/format.cpp
Normal file
188
src/boost/libs/locale/src/shared/format.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/format.hpp>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/info.hpp>
|
||||
#include <limits>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace details {
|
||||
struct format_parser::data {
|
||||
unsigned position;
|
||||
std::streamsize precision;
|
||||
std::ios_base::fmtflags flags;
|
||||
ios_info info;
|
||||
std::locale saved_locale;
|
||||
bool restore_locale;
|
||||
void *cookie;
|
||||
void (*imbuer)(void *,std::locale const &);
|
||||
};
|
||||
|
||||
format_parser::format_parser(std::ios_base &ios,void *cookie,void (*imbuer)(void *,std::locale const &)) :
|
||||
ios_(ios),
|
||||
d(new data)
|
||||
{
|
||||
d->position=std::numeric_limits<unsigned>::max();
|
||||
d->precision=ios.precision();
|
||||
d->flags = ios.flags();
|
||||
d->info=ios_info::get(ios);
|
||||
d->saved_locale = ios.getloc();
|
||||
d->restore_locale=false;
|
||||
d->cookie = cookie;
|
||||
d->imbuer = imbuer;
|
||||
}
|
||||
|
||||
void format_parser::imbue(std::locale const &l)
|
||||
{
|
||||
d->imbuer(d->cookie,l);
|
||||
}
|
||||
|
||||
format_parser::~format_parser()
|
||||
{
|
||||
}
|
||||
|
||||
void format_parser::restore()
|
||||
{
|
||||
ios_info::get(ios_) = d->info;
|
||||
ios_.width(0);
|
||||
ios_.flags(d->flags);
|
||||
if(d->restore_locale)
|
||||
imbue(d->saved_locale);
|
||||
}
|
||||
|
||||
unsigned format_parser::get_position()
|
||||
{
|
||||
return d->position;
|
||||
}
|
||||
|
||||
void format_parser::set_one_flag(std::string const &key,std::string const &value)
|
||||
{
|
||||
if(key.empty())
|
||||
return;
|
||||
unsigned i;
|
||||
for(i=0;i<key.size();i++) {
|
||||
if(key[i] < '0' || '9'< key[i])
|
||||
break;
|
||||
}
|
||||
if(i==key.size()) {
|
||||
d->position=atoi(key.c_str()) - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(key=="num" || key=="number") {
|
||||
as::number(ios_);
|
||||
|
||||
if(value=="hex")
|
||||
ios_.setf(std::ios_base::hex,std::ios_base::basefield);
|
||||
else if(value=="oct")
|
||||
ios_.setf(std::ios_base::oct,std::ios_base::basefield);
|
||||
else if(value=="sci" || value=="scientific")
|
||||
ios_.setf(std::ios_base::scientific,std::ios_base::floatfield);
|
||||
else if(value=="fix" || value=="fixed")
|
||||
ios_.setf(std::ios_base::fixed,std::ios_base::floatfield);
|
||||
}
|
||||
else if(key=="cur" || key=="currency") {
|
||||
as::currency(ios_);
|
||||
if(value=="iso")
|
||||
as::currency_iso(ios_);
|
||||
else if(value=="nat" || value=="national")
|
||||
as::currency_national(ios_);
|
||||
}
|
||||
else if(key=="per" || key=="percent") {
|
||||
as::percent(ios_);
|
||||
}
|
||||
else if(key=="date") {
|
||||
as::date(ios_);
|
||||
if(value=="s" || value=="short")
|
||||
as::date_short(ios_);
|
||||
else if(value=="m" || value=="medium")
|
||||
as::date_medium(ios_);
|
||||
else if(value=="l" || value=="long")
|
||||
as::date_long(ios_);
|
||||
else if(value=="f" || value=="full")
|
||||
as::date_full(ios_);
|
||||
}
|
||||
else if(key=="time") {
|
||||
as::time(ios_);
|
||||
if(value=="s" || value=="short")
|
||||
as::time_short(ios_);
|
||||
else if(value=="m" || value=="medium")
|
||||
as::time_medium(ios_);
|
||||
else if(value=="l" || value=="long")
|
||||
as::time_long(ios_);
|
||||
else if(value=="f" || value=="full")
|
||||
as::time_full(ios_);
|
||||
}
|
||||
else if(key=="dt" || key=="datetime") {
|
||||
as::datetime(ios_);
|
||||
if(value=="s" || value=="short") {
|
||||
as::date_short(ios_);
|
||||
as::time_short(ios_);
|
||||
}
|
||||
else if(value=="m" || value=="medium") {
|
||||
as::date_medium(ios_);
|
||||
as::time_medium(ios_);
|
||||
}
|
||||
else if(value=="l" || value=="long") {
|
||||
as::date_long(ios_);
|
||||
as::time_long(ios_);
|
||||
}
|
||||
else if(value=="f" || value=="full") {
|
||||
as::date_full(ios_);
|
||||
as::time_full(ios_);
|
||||
}
|
||||
}
|
||||
else if(key=="spell" || key=="spellout") {
|
||||
as::spellout(ios_);
|
||||
}
|
||||
else if(key=="ord" || key=="ordinal") {
|
||||
as::ordinal(ios_);
|
||||
}
|
||||
else if(key=="left" || key=="<")
|
||||
ios_.setf(std::ios_base::left,std::ios_base::adjustfield);
|
||||
else if(key=="right" || key==">")
|
||||
ios_.setf(std::ios_base::right,std::ios_base::adjustfield);
|
||||
else if(key=="gmt")
|
||||
as::gmt(ios_);
|
||||
else if(key=="local")
|
||||
as::local_time(ios_);
|
||||
else if(key=="timezone" || key=="tz")
|
||||
ios_info::get(ios_).time_zone(value);
|
||||
else if(key=="w" || key=="width")
|
||||
ios_.width(atoi(value.c_str()));
|
||||
else if(key=="p" || key=="precision")
|
||||
ios_.precision(atoi(value.c_str()));
|
||||
else if(key=="locale") {
|
||||
if(!d->restore_locale) {
|
||||
d->saved_locale=ios_.getloc();
|
||||
d->restore_locale=true;
|
||||
}
|
||||
|
||||
std::string encoding=std::use_facet<info>(d->saved_locale).encoding();
|
||||
generator gen;
|
||||
gen.categories(formatting_facet);
|
||||
|
||||
std::locale new_loc;
|
||||
if(value.find('.')==std::string::npos)
|
||||
new_loc = gen(value + "." + encoding);
|
||||
else
|
||||
new_loc = gen(value);
|
||||
|
||||
imbue(new_loc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
180
src/boost/libs/locale/src/shared/formatting.cpp
Normal file
180
src/boost/libs/locale/src/shared/formatting.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/locale/date_time.hpp>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include "ios_prop.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
|
||||
ios_info::string_set::string_set() :
|
||||
type(0),
|
||||
size(0),
|
||||
ptr(0)
|
||||
{
|
||||
}
|
||||
ios_info::string_set::~string_set()
|
||||
{
|
||||
delete [] ptr;
|
||||
}
|
||||
ios_info::string_set::string_set(string_set const &other)
|
||||
{
|
||||
if(other.ptr!=0) {
|
||||
ptr=new char[other.size];
|
||||
size=other.size;
|
||||
type=other.type;
|
||||
memcpy(ptr,other.ptr,size);
|
||||
}
|
||||
else {
|
||||
ptr=0;
|
||||
size=0;
|
||||
type=0;
|
||||
}
|
||||
}
|
||||
|
||||
void ios_info::string_set::swap(string_set &other)
|
||||
{
|
||||
std::swap(type,other.type);
|
||||
std::swap(size,other.size);
|
||||
std::swap(ptr,other.ptr);
|
||||
}
|
||||
|
||||
ios_info::string_set const &ios_info::string_set::operator=(string_set const &other)
|
||||
{
|
||||
if(this!=&other) {
|
||||
string_set tmp(other);
|
||||
swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct ios_info::data {};
|
||||
|
||||
ios_info::ios_info() :
|
||||
flags_(0),
|
||||
domain_id_(0),
|
||||
d(0)
|
||||
{
|
||||
time_zone_ = time_zone::global();
|
||||
}
|
||||
ios_info::~ios_info()
|
||||
{
|
||||
}
|
||||
|
||||
ios_info::ios_info(ios_info const &other)
|
||||
{
|
||||
flags_ = other.flags_;
|
||||
domain_id_ = other.domain_id_;
|
||||
time_zone_ = other.time_zone_;
|
||||
datetime_ = other.datetime_;
|
||||
}
|
||||
|
||||
|
||||
ios_info const &ios_info::operator=(ios_info const &other)
|
||||
{
|
||||
if(this!=&other) {
|
||||
flags_ = other.flags_;
|
||||
domain_id_ = other.domain_id_;
|
||||
time_zone_ = other.time_zone_;
|
||||
datetime_ = other.datetime_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ios_info::display_flags(uint64_t f)
|
||||
{
|
||||
flags_ = (flags_ & ~uint64_t(flags::display_flags_mask)) | f;
|
||||
}
|
||||
void ios_info::currency_flags(uint64_t f)
|
||||
{
|
||||
flags_ = (flags_ & ~uint64_t(flags::currency_flags_mask)) | f;
|
||||
}
|
||||
void ios_info::date_flags(uint64_t f)
|
||||
{
|
||||
flags_ = (flags_ & ~uint64_t(flags::date_flags_mask)) | f;
|
||||
}
|
||||
void ios_info::time_flags(uint64_t f)
|
||||
{
|
||||
flags_ = (flags_ & ~uint64_t(flags::time_flags_mask)) | f;
|
||||
}
|
||||
|
||||
void ios_info::domain_id(int id)
|
||||
{
|
||||
domain_id_ = id;
|
||||
}
|
||||
|
||||
void ios_info::time_zone(std::string const &tz)
|
||||
{
|
||||
time_zone_ = tz;
|
||||
}
|
||||
|
||||
uint64_t ios_info::display_flags() const
|
||||
{
|
||||
return flags_ & flags::display_flags_mask;
|
||||
}
|
||||
|
||||
uint64_t ios_info::currency_flags() const
|
||||
{
|
||||
return flags_ & flags::currency_flags_mask;
|
||||
}
|
||||
|
||||
uint64_t ios_info::date_flags() const
|
||||
{
|
||||
return flags_ & flags::date_flags_mask;
|
||||
}
|
||||
|
||||
uint64_t ios_info::time_flags() const
|
||||
{
|
||||
return flags_ & flags::time_flags_mask;
|
||||
}
|
||||
|
||||
int ios_info::domain_id() const
|
||||
{
|
||||
return domain_id_;
|
||||
}
|
||||
|
||||
std::string ios_info::time_zone() const
|
||||
{
|
||||
return time_zone_;
|
||||
}
|
||||
|
||||
ios_info::string_set const &ios_info::date_time_pattern_set() const
|
||||
{
|
||||
return datetime_;
|
||||
}
|
||||
|
||||
|
||||
ios_info::string_set &ios_info::date_time_pattern_set()
|
||||
{
|
||||
return datetime_;
|
||||
}
|
||||
|
||||
ios_info &ios_info::get(std::ios_base &ios)
|
||||
{
|
||||
return impl::ios_prop<ios_info>::get(ios);
|
||||
}
|
||||
|
||||
void ios_info::on_imbue()
|
||||
{
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct initializer {
|
||||
initializer() {
|
||||
impl::ios_prop<ios_info>::global_init();
|
||||
}
|
||||
} initializer_instance;
|
||||
} // namespace
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
191
src/boost/libs/locale/src/shared/generator.cpp
Normal file
191
src/boost/libs/locale/src/shared/generator.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
struct generator::data {
|
||||
data(localization_backend_manager const &mgr) :
|
||||
cats(all_categories),
|
||||
chars(all_characters),
|
||||
caching_enabled(false),
|
||||
use_ansi_encoding(false),
|
||||
backend_manager(mgr)
|
||||
{
|
||||
}
|
||||
|
||||
typedef std::map<std::string,std::locale> cached_type;
|
||||
mutable cached_type cached;
|
||||
mutable boost::mutex cached_lock;
|
||||
|
||||
locale_category_type cats;
|
||||
character_facet_type chars;
|
||||
|
||||
bool caching_enabled;
|
||||
bool use_ansi_encoding;
|
||||
|
||||
std::vector<std::string> paths;
|
||||
std::vector<std::string> domains;
|
||||
|
||||
std::map<std::string,std::vector<std::string> > options;
|
||||
|
||||
localization_backend_manager backend_manager;
|
||||
|
||||
};
|
||||
|
||||
generator::generator(localization_backend_manager const &mgr) :
|
||||
d(new generator::data(mgr))
|
||||
{
|
||||
}
|
||||
generator::generator() :
|
||||
d(new generator::data(localization_backend_manager::global()))
|
||||
{
|
||||
}
|
||||
generator::~generator()
|
||||
{
|
||||
}
|
||||
|
||||
locale_category_type generator::categories() const
|
||||
{
|
||||
return d->cats;
|
||||
}
|
||||
void generator::categories(locale_category_type t)
|
||||
{
|
||||
d->cats=t;
|
||||
}
|
||||
|
||||
void generator::characters(character_facet_type t)
|
||||
{
|
||||
d->chars=t;
|
||||
}
|
||||
|
||||
character_facet_type generator::characters() const
|
||||
{
|
||||
return d->chars;
|
||||
}
|
||||
|
||||
void generator::add_messages_domain(std::string const &domain)
|
||||
{
|
||||
if(std::find(d->domains.begin(),d->domains.end(),domain) == d->domains.end())
|
||||
d->domains.push_back(domain);
|
||||
}
|
||||
|
||||
void generator::set_default_messages_domain(std::string const &domain)
|
||||
{
|
||||
std::vector<std::string>::iterator p;
|
||||
if((p=std::find(d->domains.begin(),d->domains.end(),domain)) == d->domains.end()) {
|
||||
d->domains.erase(p);
|
||||
}
|
||||
d->domains.insert(d->domains.begin(),domain);
|
||||
}
|
||||
|
||||
void generator::clear_domains()
|
||||
{
|
||||
d->domains.clear();
|
||||
}
|
||||
void generator::add_messages_path(std::string const &path)
|
||||
{
|
||||
d->paths.push_back(path);
|
||||
}
|
||||
void generator::clear_paths()
|
||||
{
|
||||
d->paths.clear();
|
||||
}
|
||||
void generator::clear_cache()
|
||||
{
|
||||
d->cached.clear();
|
||||
}
|
||||
|
||||
std::locale generator::generate(std::string const &id) const
|
||||
{
|
||||
std::locale base=std::locale::classic();
|
||||
|
||||
return generate(base,id);
|
||||
}
|
||||
|
||||
std::locale generator::generate(std::locale const &base,std::string const &id) const
|
||||
{
|
||||
if(d->caching_enabled) {
|
||||
boost::unique_lock<boost::mutex> guard(d->cached_lock);
|
||||
data::cached_type::const_iterator p = d->cached.find(id);
|
||||
if(p!=d->cached.end()) {
|
||||
return p->second;
|
||||
}
|
||||
}
|
||||
shared_ptr<localization_backend> backend(d->backend_manager.get());
|
||||
set_all_options(backend,id);
|
||||
|
||||
std::locale result = base;
|
||||
locale_category_type facets = d->cats;
|
||||
character_facet_type chars = d->chars;
|
||||
|
||||
for(locale_category_type facet = per_character_facet_first; facet <= per_character_facet_last && facet!=0; facet <<=1) {
|
||||
if(!(facets & facet))
|
||||
continue;
|
||||
for(character_facet_type ch = character_first_facet ; ch<=character_last_facet;ch <<=1) {
|
||||
if(!(ch & chars))
|
||||
continue;
|
||||
result = backend->install(result,facet,ch);
|
||||
}
|
||||
}
|
||||
for(locale_category_type facet = non_character_facet_first; facet <= non_character_facet_last && facet!=0; facet <<=1) {
|
||||
if(!(facets & facet))
|
||||
continue;
|
||||
result = backend->install(result,facet);
|
||||
}
|
||||
if(d->caching_enabled) {
|
||||
boost::unique_lock<boost::mutex> guard(d->cached_lock);
|
||||
data::cached_type::const_iterator p = d->cached.find(id);
|
||||
if(p==d->cached.end()) {
|
||||
d->cached[id] = result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool generator::use_ansi_encoding() const
|
||||
{
|
||||
return d->use_ansi_encoding;
|
||||
}
|
||||
|
||||
void generator::use_ansi_encoding(bool v)
|
||||
{
|
||||
d->use_ansi_encoding = v;
|
||||
}
|
||||
|
||||
bool generator::locale_cache_enabled() const
|
||||
{
|
||||
return d->caching_enabled;
|
||||
}
|
||||
void generator::locale_cache_enabled(bool enabled)
|
||||
{
|
||||
d->caching_enabled = enabled;
|
||||
}
|
||||
|
||||
void generator::set_all_options(shared_ptr<localization_backend> backend,std::string const &id) const
|
||||
{
|
||||
backend->set_option("locale",id);
|
||||
if(d->use_ansi_encoding)
|
||||
backend->set_option("use_ansi_encoding","true");
|
||||
for(size_t i=0;i<d->domains.size();i++)
|
||||
backend->set_option("message_application",d->domains[i]);
|
||||
for(size_t i=0;i<d->paths.size();i++)
|
||||
backend->set_option("message_path",d->paths[i]);
|
||||
}
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
88
src/boost/libs/locale/src/shared/ids.cpp
Normal file
88
src/boost/libs/locale/src/shared/ids.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/boundary.hpp>
|
||||
#include <boost/locale/collator.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/date_time_facet.hpp>
|
||||
#include <boost/locale/message.hpp>
|
||||
#include <boost/locale/info.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
|
||||
std::locale::id info::id;
|
||||
std::locale::id calendar_facet::id;
|
||||
|
||||
std::locale::id converter<char>::id;
|
||||
std::locale::id base_message_format<char>::id;
|
||||
|
||||
std::locale::id converter<wchar_t>::id;
|
||||
std::locale::id base_message_format<wchar_t>::id;
|
||||
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
|
||||
std::locale::id converter<char16_t>::id;
|
||||
std::locale::id base_message_format<char16_t>::id;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
|
||||
std::locale::id converter<char32_t>::id;
|
||||
std::locale::id base_message_format<char32_t>::id;
|
||||
|
||||
#endif
|
||||
|
||||
namespace boundary {
|
||||
|
||||
std::locale::id boundary_indexing<char>::id;
|
||||
|
||||
std::locale::id boundary_indexing<wchar_t>::id;
|
||||
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
std::locale::id boundary_indexing<char16_t>::id;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
std::locale::id boundary_indexing<char32_t>::id;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct install_all {
|
||||
install_all()
|
||||
{
|
||||
std::locale l = std::locale::classic();
|
||||
install_by<char>();
|
||||
install_by<wchar_t>();
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
install_by<char16_t>();
|
||||
#endif
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
install_by<char32_t>();
|
||||
#endif
|
||||
|
||||
std::has_facet<info>(l);
|
||||
std::has_facet<calendar_facet>(l);
|
||||
}
|
||||
template<typename Char>
|
||||
void install_by()
|
||||
{
|
||||
std::locale l = std::locale::classic();
|
||||
std::has_facet<boundary::boundary_indexing<Char> >(l);
|
||||
std::has_facet<converter<Char> >(l);
|
||||
std::has_facet<base_message_format<Char> >(l);
|
||||
}
|
||||
} installer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
109
src/boost/libs/locale/src/shared/ios_prop.hpp
Normal file
109
src/boost/libs/locale/src/shared/ios_prop.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_SRC_LOCALE_IOS_PROP_HPP
|
||||
#define BOOST_SRC_LOCALE_IOS_PROP_HPP
|
||||
#include <ios>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl {
|
||||
|
||||
template<typename Property>
|
||||
class ios_prop {
|
||||
public:
|
||||
static void set(Property const &prop,std::ios_base &ios)
|
||||
{
|
||||
int id=get_id();
|
||||
if(ios.pword(id)==0) {
|
||||
ios.pword(id) = new Property(prop);
|
||||
ios.register_callback(callback,id);
|
||||
}
|
||||
else if(ios.pword(id)==invalid) {
|
||||
ios.pword(id) = new Property(prop);
|
||||
}
|
||||
else {
|
||||
*static_cast<Property *>(ios.pword(id))=prop;
|
||||
}
|
||||
}
|
||||
|
||||
static Property &get(std::ios_base &ios)
|
||||
{
|
||||
int id=get_id();
|
||||
if(!has(ios))
|
||||
set(Property(),ios);
|
||||
return *static_cast<Property *>(ios.pword(id));
|
||||
}
|
||||
|
||||
static bool has(std::ios_base &ios)
|
||||
{
|
||||
int id=get_id();
|
||||
if(ios.pword(id)==0 || ios.pword(id)==invalid)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void unset(std::ios_base &ios)
|
||||
{
|
||||
if(has(ios)) {
|
||||
int id=get_id();
|
||||
Property *p=static_cast<Property *>(ios.pword(id));
|
||||
delete p;
|
||||
ios.pword(id)=invalid;
|
||||
}
|
||||
}
|
||||
static void global_init()
|
||||
{
|
||||
get_id();
|
||||
}
|
||||
private:
|
||||
static void * const invalid;
|
||||
|
||||
static void callback(std::ios_base::event ev,std::ios_base &ios,int id)
|
||||
{
|
||||
switch(ev) {
|
||||
case std::ios_base::erase_event:
|
||||
if(!has(ios))
|
||||
break;
|
||||
delete reinterpret_cast<Property *>(ios.pword(id));
|
||||
break;
|
||||
case std::ios_base::copyfmt_event:
|
||||
if(ios.pword(id)==invalid || ios.pword(id)==0)
|
||||
break;
|
||||
ios.pword(id)=new Property(*reinterpret_cast<Property *>(ios.pword(id)));
|
||||
break;
|
||||
case std::ios_base::imbue_event:
|
||||
if(ios.pword(id)==invalid || ios.pword(id)==0)
|
||||
break;
|
||||
reinterpret_cast<Property *>(ios.pword(id))->on_imbue();
|
||||
break;
|
||||
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
static int get_id()
|
||||
{
|
||||
static int id = std::ios_base::xalloc();
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Property>
|
||||
void * const ios_prop<Property>::invalid = (void *)(-1);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
264
src/boost/libs/locale/src/shared/localization_backend.cpp
Normal file
264
src/boost/libs/locale/src/shared/localization_backend.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_LOCALE_WITH_ICU
|
||||
#include "../icu/icu_backend.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOCALE_NO_POSIX_BACKEND
|
||||
#include "../posix/posix_backend.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOCALE_NO_STD_BACKEND
|
||||
#include "../std/std_backend.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
|
||||
#include "../win32/win_backend.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
class localization_backend_manager::impl {
|
||||
void operator = (impl const &);
|
||||
public:
|
||||
impl(impl const &other) :
|
||||
default_backends_(other.default_backends_)
|
||||
{
|
||||
for(all_backends_type::const_iterator p=other.all_backends_.begin();p!=other.all_backends_.end();++p) {
|
||||
all_backends_type::value_type v;
|
||||
v.first=p->first;
|
||||
v.second.reset(p->second->clone());
|
||||
all_backends_.push_back(v);
|
||||
}
|
||||
}
|
||||
impl() :
|
||||
default_backends_(32,-1)
|
||||
{
|
||||
}
|
||||
std::auto_ptr<localization_backend> get() const
|
||||
{
|
||||
std::vector<boost::shared_ptr<localization_backend> > backends;
|
||||
for(unsigned i=0;i<all_backends_.size();i++)
|
||||
backends.push_back(all_backends_[i].second);
|
||||
std::auto_ptr<localization_backend> res(new actual_backend(backends,default_backends_));
|
||||
return res;
|
||||
}
|
||||
void add_backend(std::string const &name,std::auto_ptr<localization_backend> backend_ptr)
|
||||
{
|
||||
boost::shared_ptr<localization_backend> sptr(backend_ptr);
|
||||
if(all_backends_.empty()) {
|
||||
all_backends_.push_back(std::make_pair(name,sptr));
|
||||
for(unsigned i=0;i<default_backends_.size();i++)
|
||||
default_backends_[i]=0;
|
||||
}
|
||||
else {
|
||||
for(unsigned i=0;i<all_backends_.size();i++)
|
||||
if(all_backends_[i].first == name)
|
||||
return;
|
||||
all_backends_.push_back(std::make_pair(name,sptr));
|
||||
}
|
||||
}
|
||||
|
||||
void select(std::string const &backend_name,locale_category_type category = all_categories)
|
||||
{
|
||||
unsigned id;
|
||||
for(id=0;id<all_backends_.size();id++) {
|
||||
if(all_backends_[id].first == backend_name)
|
||||
break;
|
||||
}
|
||||
if(id==all_backends_.size())
|
||||
return;
|
||||
for(unsigned flag = 1,i=0;i<default_backends_.size();flag <<=1,i++) {
|
||||
if(category & flag) {
|
||||
default_backends_[i]=id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remove_all_backends()
|
||||
{
|
||||
all_backends_.clear();
|
||||
for(unsigned i=0;i<default_backends_.size();i++) {
|
||||
default_backends_[i]=-1;
|
||||
}
|
||||
}
|
||||
std::vector<std::string> get_all_backends() const
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
all_backends_type::const_iterator p;
|
||||
for(p=all_backends_.begin();p!=all_backends_.end();++p) {
|
||||
res.push_back(p->first);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
class actual_backend : public localization_backend {
|
||||
public:
|
||||
actual_backend(std::vector<boost::shared_ptr<localization_backend> > const &backends,std::vector<int> const &index):
|
||||
index_(index)
|
||||
{
|
||||
backends_.resize(backends.size());
|
||||
for(unsigned i=0;i<backends.size();i++) {
|
||||
backends_[i].reset(backends[i]->clone());
|
||||
}
|
||||
}
|
||||
virtual actual_backend *clone() const
|
||||
{
|
||||
return new actual_backend(backends_,index_);
|
||||
}
|
||||
virtual void set_option(std::string const &name,std::string const &value)
|
||||
{
|
||||
for(unsigned i=0;i<backends_.size();i++)
|
||||
backends_[i]->set_option(name,value);
|
||||
}
|
||||
virtual void clear_options()
|
||||
{
|
||||
for(unsigned i=0;i<backends_.size();i++)
|
||||
backends_[i]->clear_options();
|
||||
}
|
||||
virtual std::locale install(std::locale const &l,locale_category_type category,character_facet_type type = nochar_facet)
|
||||
{
|
||||
int id;
|
||||
unsigned v;
|
||||
for(v=1,id=0;v!=0;v<<=1,id++) {
|
||||
if(category == v)
|
||||
break;
|
||||
}
|
||||
if(v==0)
|
||||
return l;
|
||||
if(unsigned(id) >= index_.size())
|
||||
return l;
|
||||
if(index_[id]==-1)
|
||||
return l;
|
||||
return backends_[index_[id]]->install(l,category,type);
|
||||
}
|
||||
private:
|
||||
std::vector<boost::shared_ptr<localization_backend> > backends_;
|
||||
std::vector<int> index_;
|
||||
};
|
||||
|
||||
typedef std::vector<std::pair<std::string,boost::shared_ptr<localization_backend> > > all_backends_type;
|
||||
all_backends_type all_backends_;
|
||||
std::vector<int> default_backends_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
localization_backend_manager::localization_backend_manager() :
|
||||
pimpl_(new impl())
|
||||
{
|
||||
}
|
||||
|
||||
localization_backend_manager::~localization_backend_manager()
|
||||
{
|
||||
}
|
||||
|
||||
localization_backend_manager::localization_backend_manager(localization_backend_manager const &other) :
|
||||
pimpl_(new impl(*other.pimpl_))
|
||||
{
|
||||
}
|
||||
|
||||
localization_backend_manager const &localization_backend_manager::operator = (localization_backend_manager const &other)
|
||||
{
|
||||
if(this!=&other) {
|
||||
pimpl_.reset(new impl(*other.pimpl_));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::auto_ptr<localization_backend> localization_backend_manager::get() const
|
||||
{
|
||||
return pimpl_->get();
|
||||
}
|
||||
|
||||
void localization_backend_manager::add_backend(std::string const &name,std::auto_ptr<localization_backend> backend)
|
||||
{
|
||||
pimpl_->add_backend(name,backend);
|
||||
}
|
||||
void localization_backend_manager::remove_all_backends()
|
||||
{
|
||||
pimpl_->remove_all_backends();
|
||||
}
|
||||
std::vector<std::string> localization_backend_manager::get_all_backends() const
|
||||
{
|
||||
return pimpl_->get_all_backends();
|
||||
}
|
||||
void localization_backend_manager::select(std::string const &backend_name,locale_category_type category)
|
||||
{
|
||||
pimpl_->select(backend_name,category);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// prevent initialization order fiasco
|
||||
boost::mutex &localization_backend_manager_mutex()
|
||||
{
|
||||
static boost::mutex the_mutex;
|
||||
return the_mutex;
|
||||
}
|
||||
// prevent initialization order fiasco
|
||||
localization_backend_manager &localization_backend_manager_global()
|
||||
{
|
||||
static localization_backend_manager the_manager;
|
||||
return the_manager;
|
||||
}
|
||||
|
||||
struct init {
|
||||
init() {
|
||||
localization_backend_manager mgr;
|
||||
std::auto_ptr<localization_backend> backend;
|
||||
#ifdef BOOST_LOCALE_WITH_ICU
|
||||
backend.reset(impl_icu::create_localization_backend());
|
||||
mgr.add_backend("icu",backend);
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOCALE_NO_POSIX_BACKEND
|
||||
backend.reset(impl_posix::create_localization_backend());
|
||||
mgr.add_backend("posix",backend);
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
|
||||
backend.reset(impl_win::create_localization_backend());
|
||||
mgr.add_backend("winapi",backend);
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOCALE_NO_STD_BACKEND
|
||||
backend.reset(impl_std::create_localization_backend());
|
||||
mgr.add_backend("std",backend);
|
||||
#endif
|
||||
|
||||
localization_backend_manager::global(mgr);
|
||||
}
|
||||
} do_init;
|
||||
}
|
||||
|
||||
localization_backend_manager localization_backend_manager::global()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
|
||||
localization_backend_manager mgr = localization_backend_manager_global();
|
||||
return mgr;
|
||||
}
|
||||
localization_backend_manager localization_backend_manager::global(localization_backend_manager const &in)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
|
||||
localization_backend_manager mgr = localization_backend_manager_global();
|
||||
localization_backend_manager_global() = in;
|
||||
return mgr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
782
src/boost/libs/locale/src/shared/message.cpp
Normal file
782
src/boost/libs/locale/src/shared/message.cpp
Normal file
@@ -0,0 +1,782 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/locale/message.hpp>
|
||||
#include <boost/locale/gnu_gettext.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
|
||||
#if BOOST_VERSION >= 103600
|
||||
#define BOOST_LOCALE_UNORDERED_CATALOG
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LOCALE_UNORDERED_CATALOG
|
||||
#include <boost/unordered_map.hpp>
|
||||
#else
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#include "mo_hash.hpp"
|
||||
#include "mo_lambda.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace gnu_gettext {
|
||||
|
||||
class c_file {
|
||||
c_file(c_file const &);
|
||||
void operator=(c_file const &);
|
||||
public:
|
||||
|
||||
FILE *file;
|
||||
|
||||
c_file() :
|
||||
file(0)
|
||||
{
|
||||
}
|
||||
~c_file()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if(file) {
|
||||
fclose(file);
|
||||
file=0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
bool open(std::string const &file_name,std::string const &encoding)
|
||||
{
|
||||
close();
|
||||
|
||||
//
|
||||
// Under windows we have to use "_wfopen" to get
|
||||
// access to path's with Unicode in them
|
||||
//
|
||||
// As not all standard C++ libraries support nonstandard std::istream::open(wchar_t const *)
|
||||
// we would use old and good stdio and _wfopen CRTL functions
|
||||
//
|
||||
|
||||
std::wstring wfile_name = conv::to_utf<wchar_t>(file_name,encoding);
|
||||
file = _wfopen(wfile_name.c_str(),L"rb");
|
||||
|
||||
return file!=0;
|
||||
}
|
||||
|
||||
#else // POSIX systems do not have all this Wide API crap, as native codepages are UTF-8
|
||||
|
||||
// We do not use encoding as we use native file name encoding
|
||||
|
||||
bool open(std::string const &file_name,std::string const &/* encoding */)
|
||||
{
|
||||
close();
|
||||
|
||||
file = fopen(file_name.c_str(),"rb");
|
||||
|
||||
return file!=0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
class mo_file {
|
||||
public:
|
||||
typedef std::pair<char const *,char const *> pair_type;
|
||||
|
||||
mo_file(std::vector<char> &file) :
|
||||
native_byteorder_(true),
|
||||
size_(0)
|
||||
{
|
||||
load_file(file);
|
||||
init();
|
||||
}
|
||||
|
||||
mo_file(FILE *file) :
|
||||
native_byteorder_(true),
|
||||
size_(0)
|
||||
{
|
||||
load_file(file);
|
||||
init();
|
||||
}
|
||||
|
||||
pair_type find(char const *context_in,char const *key_in) const
|
||||
{
|
||||
pair_type null_pair((char const *)0,(char const *)0);
|
||||
if(hash_size_==0)
|
||||
return null_pair;
|
||||
uint32_t hkey = 0;
|
||||
if(context_in == 0)
|
||||
hkey = pj_winberger_hash_function(key_in);
|
||||
else {
|
||||
pj_winberger_hash::state_type st = pj_winberger_hash::initial_state;
|
||||
st = pj_winberger_hash::update_state(st,context_in);
|
||||
st = pj_winberger_hash::update_state(st,'\4'); // EOT
|
||||
st = pj_winberger_hash::update_state(st,key_in);
|
||||
hkey = st;
|
||||
}
|
||||
uint32_t incr = 1 + hkey % (hash_size_-2);
|
||||
hkey %= hash_size_;
|
||||
uint32_t orig=hkey;
|
||||
|
||||
|
||||
do {
|
||||
uint32_t idx = get(hash_offset_ + 4*hkey);
|
||||
/// Not found
|
||||
if(idx == 0)
|
||||
return null_pair;
|
||||
/// If equal values return translation
|
||||
if(key_equals(key(idx-1),context_in,key_in))
|
||||
return value(idx-1);
|
||||
/// Rehash
|
||||
hkey=(hkey + incr) % hash_size_;
|
||||
} while(hkey!=orig);
|
||||
return null_pair;
|
||||
}
|
||||
|
||||
static bool key_equals(char const *real_key,char const *cntx,char const *key)
|
||||
{
|
||||
if(cntx == 0)
|
||||
return strcmp(real_key,key) == 0;
|
||||
else {
|
||||
size_t real_len = strlen(real_key);
|
||||
size_t cntx_len = strlen(cntx);
|
||||
size_t key_len = strlen(key);
|
||||
if(cntx_len + 1 + key_len != real_len)
|
||||
return false;
|
||||
return
|
||||
memcmp(real_key,cntx,cntx_len) == 0
|
||||
&& real_key[cntx_len] == '\4'
|
||||
&& memcmp(real_key + cntx_len + 1 ,key,key_len) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
char const *key(int id) const
|
||||
{
|
||||
uint32_t off = get(keys_offset_ + id*8 + 4);
|
||||
return data_ + off;
|
||||
}
|
||||
|
||||
pair_type value(int id) const
|
||||
{
|
||||
uint32_t len = get(translations_offset_ + id*8);
|
||||
uint32_t off = get(translations_offset_ + id*8 + 4);
|
||||
if(off >= file_size_ || off + len >= file_size_)
|
||||
throw std::runtime_error("Bad mo-file format");
|
||||
return pair_type(&data_[off],&data_[off]+len);
|
||||
}
|
||||
|
||||
bool has_hash() const
|
||||
{
|
||||
return hash_size_ != 0;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void init()
|
||||
{
|
||||
// Read all format sizes
|
||||
size_=get(8);
|
||||
keys_offset_=get(12);
|
||||
translations_offset_=get(16);
|
||||
hash_size_=get(20);
|
||||
hash_offset_=get(24);
|
||||
}
|
||||
|
||||
void load_file(std::vector<char> &data)
|
||||
{
|
||||
vdata_.swap(data);
|
||||
file_size_ = vdata_.size();
|
||||
data_ = &vdata_[0];
|
||||
if(file_size_ < 4 )
|
||||
throw std::runtime_error("invalid 'mo' file format - the file is too short");
|
||||
uint32_t magic=0;
|
||||
memcpy(&magic,data_,4);
|
||||
if(magic == 0x950412de)
|
||||
native_byteorder_ = true;
|
||||
else if(magic == 0xde120495)
|
||||
native_byteorder_ = false;
|
||||
else
|
||||
throw std::runtime_error("Invalid file format - invalid magic number");
|
||||
}
|
||||
|
||||
void load_file(FILE *file)
|
||||
{
|
||||
uint32_t magic=0;
|
||||
// if the size is wrong magic would be wrong
|
||||
// ok to ingnore fread result
|
||||
size_t four_bytes = fread(&magic,4,1,file);
|
||||
(void)four_bytes; // shut GCC
|
||||
|
||||
if(magic == 0x950412de)
|
||||
native_byteorder_ = true;
|
||||
else if(magic == 0xde120495)
|
||||
native_byteorder_ = false;
|
||||
else
|
||||
throw std::runtime_error("Invalid file format");
|
||||
|
||||
fseek(file,0,SEEK_END);
|
||||
long len=ftell(file);
|
||||
if(len < 0) {
|
||||
throw std::runtime_error("Wrong file object");
|
||||
}
|
||||
fseek(file,0,SEEK_SET);
|
||||
vdata_.resize(len+1,0); // +1 to make sure the vector is not empty
|
||||
if(fread(&vdata_.front(),1,len,file)!=unsigned(len))
|
||||
throw std::runtime_error("Failed to read file");
|
||||
data_ = &vdata_[0];
|
||||
file_size_ = len;
|
||||
}
|
||||
|
||||
uint32_t get(unsigned offset) const
|
||||
{
|
||||
uint32_t tmp;
|
||||
if(offset > file_size_ - 4) {
|
||||
throw std::runtime_error("Bad mo-file format");
|
||||
}
|
||||
memcpy(&tmp,data_ + offset,4);
|
||||
convert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void convert(uint32_t &v) const
|
||||
{
|
||||
if(native_byteorder_)
|
||||
return;
|
||||
v = ((v & 0xFF) << 24)
|
||||
| ((v & 0xFF00) << 8)
|
||||
| ((v & 0xFF0000) >> 8)
|
||||
| ((v & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
uint32_t keys_offset_;
|
||||
uint32_t translations_offset_;
|
||||
uint32_t hash_size_;
|
||||
uint32_t hash_offset_;
|
||||
|
||||
char const *data_;
|
||||
size_t file_size_;
|
||||
std::vector<char> vdata_;
|
||||
bool native_byteorder_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
struct mo_file_use_traits {
|
||||
static const bool in_use = false;
|
||||
typedef CharType char_type;
|
||||
typedef std::pair<char_type const *,char_type const *> pair_type;
|
||||
static pair_type use(mo_file const &/*mo*/,char_type const * /*context*/,char_type const * /*key*/)
|
||||
{
|
||||
return pair_type((char_type const *)(0),(char_type const *)(0));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct mo_file_use_traits<char> {
|
||||
static const bool in_use = true;
|
||||
typedef char char_type;
|
||||
typedef std::pair<char_type const *,char_type const *> pair_type;
|
||||
static pair_type use(mo_file const &mo,char const *context,char const *key)
|
||||
{
|
||||
return mo.find(context,key);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
class converter {
|
||||
public:
|
||||
converter(std::string /*out_enc*/,std::string in_enc) :
|
||||
in_(in_enc)
|
||||
{
|
||||
}
|
||||
|
||||
std::basic_string<CharType> operator()(char const *begin,char const *end)
|
||||
{
|
||||
return conv::to_utf<CharType>(begin,end,in_,conv::stop);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string in_;
|
||||
};
|
||||
|
||||
template<>
|
||||
class converter<char> {
|
||||
public:
|
||||
converter(std::string out_enc,std::string in_enc) :
|
||||
out_(out_enc),
|
||||
in_(in_enc)
|
||||
{
|
||||
}
|
||||
|
||||
std::string operator()(char const *begin,char const *end)
|
||||
{
|
||||
return conv::between(begin,end,out_,in_,conv::stop);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string out_,in_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
struct message_key {
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
|
||||
message_key(string_type const &c = string_type()) :
|
||||
c_context_(0),
|
||||
c_key_(0)
|
||||
{
|
||||
size_t pos = c.find(char_type(4));
|
||||
if(pos == string_type::npos) {
|
||||
key_ = c;
|
||||
}
|
||||
else {
|
||||
context_ = c.substr(0,pos);
|
||||
key_ = c.substr(pos+1);
|
||||
}
|
||||
}
|
||||
message_key(char_type const *c,char_type const *k) :
|
||||
c_key_(k)
|
||||
{
|
||||
static const char_type empty = 0;
|
||||
if(c!=0)
|
||||
c_context_ = c;
|
||||
else
|
||||
c_context_ = ∅
|
||||
}
|
||||
bool operator < (message_key const &other) const
|
||||
{
|
||||
int cc = compare(context(),other.context());
|
||||
if(cc != 0)
|
||||
return cc < 0;
|
||||
return compare(key(),other.key()) < 0;
|
||||
}
|
||||
bool operator==(message_key const &other) const
|
||||
{
|
||||
return compare(context(),other.context()) == 0
|
||||
&& compare(key(),other.key())==0;
|
||||
}
|
||||
bool operator!=(message_key const &other) const
|
||||
{
|
||||
return !(*this==other);
|
||||
}
|
||||
char_type const *context() const
|
||||
{
|
||||
if(c_context_)
|
||||
return c_context_;
|
||||
return context_.c_str();
|
||||
}
|
||||
char_type const *key() const
|
||||
{
|
||||
if(c_key_)
|
||||
return c_key_;
|
||||
return key_.c_str();
|
||||
}
|
||||
private:
|
||||
static int compare(char_type const *l,char_type const *r)
|
||||
{
|
||||
typedef std::char_traits<char_type> traits_type;
|
||||
for(;;) {
|
||||
char_type cl = *l++;
|
||||
char_type cr = *r++;
|
||||
if(cl == 0 && cr == 0)
|
||||
return 0;
|
||||
if(traits_type::lt(cl,cr))
|
||||
return -1;
|
||||
if(traits_type::lt(cr,cl))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
string_type context_;
|
||||
string_type key_;
|
||||
char_type const *c_context_;
|
||||
char_type const *c_key_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
struct hash_function {
|
||||
size_t operator()(message_key<CharType> const &msg) const
|
||||
{
|
||||
pj_winberger_hash::state_type state = pj_winberger_hash::initial_state;
|
||||
CharType const *p = msg.context();
|
||||
if(*p != 0) {
|
||||
CharType const *e = p;
|
||||
while(*e)
|
||||
e++;
|
||||
state = pj_winberger_hash::update_state(state,
|
||||
static_cast<char const *>(p),
|
||||
static_cast<char const *>(e));
|
||||
state = pj_winberger_hash::update_state(state,'\4');
|
||||
}
|
||||
p = msg.key();
|
||||
CharType const *e = p;
|
||||
while(*e)
|
||||
e++;
|
||||
state = pj_winberger_hash::update_state(state,
|
||||
static_cast<char const *>(p),
|
||||
static_cast<char const *>(e));
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// By default for wide types the conversion is not requiredyy
|
||||
template<typename CharType>
|
||||
CharType const *runtime_conversion(CharType const *msg,
|
||||
std::basic_string<CharType> &/*buffer*/,
|
||||
bool /*do_conversion*/,
|
||||
std::string const &/*locale_encoding*/,
|
||||
std::string const &/*key_encoding*/)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
|
||||
// But still need to specialize for char
|
||||
template<>
|
||||
char const *runtime_conversion( char const *msg,
|
||||
std::string &buffer,
|
||||
bool do_conversion,
|
||||
std::string const &locale_encoding,
|
||||
std::string const &key_encoding)
|
||||
{
|
||||
if(!do_conversion)
|
||||
return msg;
|
||||
if(details::is_us_ascii_string(msg))
|
||||
return msg;
|
||||
std::string tmp = conv::between(msg,locale_encoding,key_encoding,conv::skip);
|
||||
buffer.swap(tmp);
|
||||
return buffer.c_str();
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
class mo_message : public message_format<CharType> {
|
||||
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
typedef message_key<CharType> key_type;
|
||||
#ifdef BOOST_LOCALE_UNORDERED_CATALOG
|
||||
typedef boost::unordered_map<key_type,string_type,hash_function<CharType> > catalog_type;
|
||||
#else
|
||||
typedef std::map<key_type,string_type> catalog_type;
|
||||
#endif
|
||||
typedef std::vector<catalog_type> catalogs_set_type;
|
||||
typedef std::map<std::string,int> domains_map_type;
|
||||
public:
|
||||
|
||||
typedef std::pair<CharType const *,CharType const *> pair_type;
|
||||
|
||||
virtual char_type const *get(int domain_id,char_type const *context,char_type const *id) const
|
||||
{
|
||||
return get_string(domain_id,context,id).first;
|
||||
}
|
||||
|
||||
virtual char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const
|
||||
{
|
||||
pair_type ptr = get_string(domain_id,context,single_id);
|
||||
if(!ptr.first)
|
||||
return 0;
|
||||
int form=0;
|
||||
if(plural_forms_.at(domain_id))
|
||||
form = (*plural_forms_[domain_id])(n);
|
||||
else
|
||||
form = n == 1 ? 0 : 1; // Fallback to english plural form
|
||||
|
||||
CharType const *p=ptr.first;
|
||||
for(int i=0;p < ptr.second && i<form;i++) {
|
||||
p=std::find(p,ptr.second,0);
|
||||
if(p==ptr.second)
|
||||
return 0;
|
||||
++p;
|
||||
}
|
||||
if(p>=ptr.second)
|
||||
return 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
virtual int domain(std::string const &domain) const
|
||||
{
|
||||
domains_map_type::const_iterator p=domains_.find(domain);
|
||||
if(p==domains_.end())
|
||||
return -1;
|
||||
return p->second;
|
||||
}
|
||||
|
||||
mo_message(messages_info const &inf)
|
||||
{
|
||||
std::string language = inf.language;
|
||||
std::string variant = inf.variant;
|
||||
std::string country = inf.country;
|
||||
std::string encoding = inf.encoding;
|
||||
std::string lc_cat = inf.locale_category;
|
||||
std::vector<messages_info::domain> const &domains = inf.domains;
|
||||
std::vector<std::string> const &search_paths = inf.paths;
|
||||
|
||||
//
|
||||
// List of fallbacks: en_US@euro, en@euro, en_US, en.
|
||||
//
|
||||
std::vector<std::string> paths;
|
||||
|
||||
|
||||
if(!variant.empty() && !country.empty())
|
||||
paths.push_back(language + "_" + country + "@" + variant);
|
||||
|
||||
if(!variant.empty())
|
||||
paths.push_back(language + "@" + variant);
|
||||
|
||||
if(!country.empty())
|
||||
paths.push_back(language + "_" + country);
|
||||
|
||||
paths.push_back(language);
|
||||
|
||||
catalogs_.resize(domains.size());
|
||||
mo_catalogs_.resize(domains.size());
|
||||
plural_forms_.resize(domains.size());
|
||||
|
||||
|
||||
for(unsigned id=0;id<domains.size();id++) {
|
||||
std::string domain=domains[id].name;
|
||||
std::string key_encoding = domains[id].encoding;
|
||||
domains_[domain]=id;
|
||||
|
||||
|
||||
bool found=false;
|
||||
for(unsigned j=0;!found && j<paths.size();j++) {
|
||||
for(unsigned i=0;!found && i<search_paths.size();i++) {
|
||||
std::string full_path = search_paths[i]+"/"+paths[j]+"/" + lc_cat + "/"+domain+".mo";
|
||||
found = load_file(full_path,encoding,key_encoding,id,inf.callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char_type const *convert(char_type const *msg,string_type &buffer) const
|
||||
{
|
||||
return runtime_conversion<char_type>(msg,buffer,key_conversion_required_,locale_encoding_,key_encoding_);
|
||||
}
|
||||
|
||||
virtual ~mo_message()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int compare_encodings(std::string const &left,std::string const &right)
|
||||
{
|
||||
return convert_encoding_name(left).compare(convert_encoding_name(right));
|
||||
}
|
||||
|
||||
std::string convert_encoding_name(std::string const &in)
|
||||
{
|
||||
std::string result;
|
||||
for(unsigned i=0;i<in.size();i++) {
|
||||
char c=in[i];
|
||||
if('A' <= c && c<='Z')
|
||||
c=c-'A' + 'a';
|
||||
else if(('a' <= c && c<='z') || ('0' <= c && c<='9'))
|
||||
;
|
||||
else
|
||||
continue;
|
||||
result+=c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool load_file( std::string const &file_name,
|
||||
std::string const &locale_encoding,
|
||||
std::string const &key_encoding,
|
||||
int id,
|
||||
messages_info::callback_type const &callback)
|
||||
{
|
||||
locale_encoding_ = locale_encoding;
|
||||
key_encoding_ = key_encoding;
|
||||
|
||||
key_conversion_required_ = sizeof(CharType) == 1
|
||||
&& compare_encodings(locale_encoding,key_encoding)!=0;
|
||||
|
||||
std::auto_ptr<mo_file> mo;
|
||||
|
||||
if(callback) {
|
||||
std::vector<char> vfile = callback(file_name,locale_encoding);
|
||||
if(vfile.empty())
|
||||
return false;
|
||||
mo.reset(new mo_file(vfile));
|
||||
}
|
||||
else {
|
||||
c_file the_file;
|
||||
the_file.open(file_name,locale_encoding);
|
||||
if(!the_file.file)
|
||||
return false;
|
||||
mo.reset(new mo_file(the_file.file));
|
||||
}
|
||||
|
||||
std::string plural = extract(mo->value(0).first,"plural=","\r\n;");
|
||||
|
||||
std::string mo_encoding = extract(mo->value(0).first,"charset="," \r\n;");
|
||||
|
||||
if(mo_encoding.empty())
|
||||
throw std::runtime_error("Invalid mo-format, encoding is not specified");
|
||||
|
||||
if(!plural.empty()) {
|
||||
std::auto_ptr<lambda::plural> ptr=lambda::compile(plural.c_str());
|
||||
plural_forms_[id] = ptr;
|
||||
}
|
||||
|
||||
if( mo_useable_directly(mo_encoding,*mo) )
|
||||
{
|
||||
mo_catalogs_[id]=mo;
|
||||
}
|
||||
else {
|
||||
converter<CharType> cvt_value(locale_encoding,mo_encoding);
|
||||
converter<CharType> cvt_key(key_encoding,mo_encoding);
|
||||
for(unsigned i=0;i<mo->size();i++) {
|
||||
char const *ckey = mo->key(i);
|
||||
string_type skey = cvt_key(ckey,ckey+strlen(ckey));
|
||||
key_type key(skey);
|
||||
|
||||
mo_file::pair_type tmp = mo->value(i);
|
||||
string_type value = cvt_value(tmp.first,tmp.second);
|
||||
catalogs_[id][key].swap(value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Check if the mo file as-is is useful
|
||||
// 1. It is char and not wide character
|
||||
// 2. The locale encoding and mo encoding is same
|
||||
// 3. The source strings encoding and mo encoding is same or all
|
||||
// mo key strings are US-ASCII
|
||||
bool mo_useable_directly( std::string const &mo_encoding,
|
||||
mo_file const &mo)
|
||||
{
|
||||
if(sizeof(CharType) != 1)
|
||||
return false;
|
||||
if(!mo.has_hash())
|
||||
return false;
|
||||
if(compare_encodings(mo_encoding.c_str(),locale_encoding_.c_str())!=0)
|
||||
return false;
|
||||
if(compare_encodings(mo_encoding.c_str(),key_encoding_.c_str())==0) {
|
||||
return true;
|
||||
}
|
||||
for(unsigned i=0;i<mo.size();i++) {
|
||||
if(!details::is_us_ascii_string(mo.key(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::string extract(std::string const &meta,std::string const &key,char const *separator)
|
||||
{
|
||||
size_t pos=meta.find(key);
|
||||
if(pos == std::string::npos)
|
||||
return "";
|
||||
pos+=key.size(); /// size of charset=
|
||||
size_t end_pos = meta.find_first_of(separator,pos);
|
||||
return meta.substr(pos,end_pos - pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pair_type get_string(int domain_id,char_type const *context,char_type const *in_id) const
|
||||
{
|
||||
pair_type null_pair((CharType const *)0,(CharType const *)0);
|
||||
if(domain_id < 0 || size_t(domain_id) >= catalogs_.size())
|
||||
return null_pair;
|
||||
if(mo_file_use_traits<char_type>::in_use && mo_catalogs_[domain_id]) {
|
||||
return mo_file_use_traits<char_type>::use(*mo_catalogs_[domain_id],context,in_id);
|
||||
}
|
||||
else {
|
||||
key_type key(context,in_id);
|
||||
catalog_type const &cat = catalogs_[domain_id];
|
||||
typename catalog_type::const_iterator p = cat.find(key);
|
||||
if(p==cat.end()) {
|
||||
return null_pair;
|
||||
}
|
||||
return pair_type(p->second.data(),p->second.data()+p->second.size());
|
||||
}
|
||||
}
|
||||
|
||||
catalogs_set_type catalogs_;
|
||||
std::vector<boost::shared_ptr<mo_file> > mo_catalogs_;
|
||||
std::vector<boost::shared_ptr<lambda::plural> > plural_forms_;
|
||||
domains_map_type domains_;
|
||||
|
||||
std::string locale_encoding_;
|
||||
std::string key_encoding_;
|
||||
bool key_conversion_required_;
|
||||
};
|
||||
|
||||
template<>
|
||||
message_format<char> *create_messages_facet(messages_info const &info)
|
||||
{
|
||||
return new mo_message<char>(info);
|
||||
}
|
||||
|
||||
template<>
|
||||
message_format<wchar_t> *create_messages_facet(messages_info const &info)
|
||||
{
|
||||
return new mo_message<wchar_t>(info);
|
||||
}
|
||||
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
|
||||
template<>
|
||||
message_format<char16_t> *create_messages_facet(messages_info const &info)
|
||||
{
|
||||
return new mo_message<char16_t>(info);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
|
||||
template<>
|
||||
message_format<char32_t> *create_messages_facet(messages_info const &info)
|
||||
{
|
||||
return new mo_message<char32_t>(info);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} /// gnu_gettext
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
61
src/boost/libs/locale/src/shared/mo_hash.hpp
Normal file
61
src/boost/libs/locale/src/shared/mo_hash.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace gnu_gettext {
|
||||
|
||||
struct pj_winberger_hash {
|
||||
|
||||
typedef uint32_t state_type;
|
||||
|
||||
static const state_type initial_state = 0;
|
||||
|
||||
static state_type update_state(state_type value,char c)
|
||||
{
|
||||
value = (value << 4) + static_cast<unsigned char>(c);
|
||||
uint32_t high = (value & 0xF0000000U);
|
||||
if(high!=0)
|
||||
value = (value ^ (high >> 24)) ^ high;
|
||||
return value;
|
||||
}
|
||||
static state_type update_state(state_type value,char const *ptr)
|
||||
{
|
||||
while(*ptr)
|
||||
value = update_state(value,*ptr++);
|
||||
return value;
|
||||
}
|
||||
static state_type update_state(state_type value,char const *begin,char const *end)
|
||||
{
|
||||
while(begin!=end)
|
||||
value = update_state(value,*begin++);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
inline pj_winberger_hash::state_type pj_winberger_hash_function(char const *ptr)
|
||||
{
|
||||
pj_winberger_hash::state_type state = pj_winberger_hash::initial_state;
|
||||
state = pj_winberger_hash::update_state(state,ptr);
|
||||
return state;
|
||||
}
|
||||
|
||||
inline pj_winberger_hash::state_type pj_winberger_hash_function(char const *begin,char const *end)
|
||||
{
|
||||
pj_winberger_hash::state_type state = pj_winberger_hash::initial_state;
|
||||
state = pj_winberger_hash::update_state(state,begin,end);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
422
src/boost/libs/locale/src/shared/mo_lambda.cpp
Normal file
422
src/boost/libs/locale/src/shared/mo_lambda.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "mo_lambda.hpp"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace gnu_gettext {
|
||||
namespace lambda {
|
||||
|
||||
namespace { // anon
|
||||
struct identity : public plural {
|
||||
virtual int operator()(int n) const
|
||||
{
|
||||
return n;
|
||||
};
|
||||
virtual identity *clone() const
|
||||
{
|
||||
return new identity();
|
||||
}
|
||||
};
|
||||
|
||||
struct unary : public plural
|
||||
{
|
||||
unary(plural_ptr ptr) :
|
||||
op1(ptr)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
plural_ptr op1;
|
||||
};
|
||||
|
||||
|
||||
struct binary : public plural
|
||||
{
|
||||
binary(plural_ptr p1,plural_ptr p2) :
|
||||
op1(p1),
|
||||
op2(p2)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
plural_ptr op1,op2;
|
||||
};
|
||||
|
||||
struct number : public plural
|
||||
{
|
||||
number(int v) :
|
||||
val(v)
|
||||
{
|
||||
}
|
||||
virtual int operator()(int /*n*/) const
|
||||
{
|
||||
return val;
|
||||
}
|
||||
virtual number *clone() const
|
||||
{
|
||||
return new number(val);
|
||||
}
|
||||
|
||||
private:
|
||||
int val;
|
||||
};
|
||||
|
||||
#define UNOP(name,oper) \
|
||||
struct name: public unary { \
|
||||
name(plural_ptr op) : unary(op) \
|
||||
{ \
|
||||
}; \
|
||||
virtual int operator()(int n) const \
|
||||
{ \
|
||||
return oper (*op1)(n); \
|
||||
} \
|
||||
virtual name *clone() const \
|
||||
{ \
|
||||
plural_ptr op1_copy(op1->clone()); \
|
||||
return new name(op1_copy); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define BINOP(name,oper) \
|
||||
struct name : public binary \
|
||||
{ \
|
||||
name(plural_ptr p1,plural_ptr p2) : \
|
||||
binary(p1,p2) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
virtual int operator()(int n) const \
|
||||
{ \
|
||||
return (*op1)(n) oper (*op2)(n); \
|
||||
} \
|
||||
virtual name *clone() const \
|
||||
{ \
|
||||
plural_ptr op1_copy(op1->clone()); \
|
||||
plural_ptr op2_copy(op2->clone()); \
|
||||
return new name(op1_copy,op2_copy); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define BINOPD(name,oper) \
|
||||
struct name : public binary { \
|
||||
name(plural_ptr p1,plural_ptr p2) : \
|
||||
binary(p1,p2) \
|
||||
{ \
|
||||
} \
|
||||
virtual int operator()(int n) const \
|
||||
{ \
|
||||
int v1=(*op1)(n); \
|
||||
int v2=(*op2)(n); \
|
||||
return v2==0 ? 0 : v1 oper v2; \
|
||||
} \
|
||||
virtual name *clone() const \
|
||||
{ \
|
||||
plural_ptr op1_copy(op1->clone()); \
|
||||
plural_ptr op2_copy(op2->clone()); \
|
||||
return new name(op1_copy,op2_copy); \
|
||||
} \
|
||||
};
|
||||
|
||||
enum { END = 0 , SHL = 256, SHR, GTE,LTE, EQ, NEQ, AND, OR, NUM, VARIABLE };
|
||||
|
||||
UNOP(l_not,!)
|
||||
UNOP(minus,-)
|
||||
UNOP(bin_not,~)
|
||||
|
||||
BINOP(mul,*)
|
||||
BINOPD(div,/)
|
||||
BINOPD(mod,%)
|
||||
static int level10[]={3,'*','/','%'};
|
||||
|
||||
BINOP(add,+)
|
||||
BINOP(sub,-)
|
||||
static int level9[]={2,'+','-'};
|
||||
|
||||
BINOP(shl,<<)
|
||||
BINOP(shr,>>)
|
||||
static int level8[]={2,SHL,SHR};
|
||||
|
||||
BINOP(gt,>)
|
||||
BINOP(lt,<)
|
||||
BINOP(gte,>=)
|
||||
BINOP(lte,<=)
|
||||
static int level7[]={4,'<','>',GTE,LTE};
|
||||
|
||||
BINOP(eq,==)
|
||||
BINOP(neq,!=)
|
||||
static int level6[]={2,EQ,NEQ};
|
||||
|
||||
BINOP(bin_and,&)
|
||||
static int level5[]={1,'&'};
|
||||
|
||||
BINOP(bin_xor,^)
|
||||
static int level4[]={1,'^'};
|
||||
|
||||
BINOP(bin_or,|)
|
||||
static int level3[]={1,'|'};
|
||||
|
||||
BINOP(l_and,&&)
|
||||
static int level2[]={1,AND};
|
||||
|
||||
BINOP(l_or,||)
|
||||
static int level1[]={1,OR};
|
||||
|
||||
struct conditional : public plural {
|
||||
conditional(plural_ptr p1,plural_ptr p2,plural_ptr p3) :
|
||||
op1(p1),
|
||||
op2(p2),
|
||||
op3(p3)
|
||||
{
|
||||
}
|
||||
virtual int operator()(int n) const
|
||||
{
|
||||
return (*op1)(n) ? (*op2)(n) : (*op3)(n);
|
||||
}
|
||||
virtual conditional *clone() const
|
||||
{
|
||||
plural_ptr op1_copy(op1->clone());
|
||||
plural_ptr op2_copy(op2->clone());
|
||||
plural_ptr op3_copy(op3->clone());
|
||||
return new conditional(op1_copy,op2_copy,op3_copy);
|
||||
}
|
||||
private:
|
||||
plural_ptr op1,op2,op3;
|
||||
};
|
||||
|
||||
|
||||
plural_ptr bin_factory(int value,plural_ptr left,plural_ptr right)
|
||||
{
|
||||
|
||||
switch(value) {
|
||||
case '/': return plural_ptr(new div(left,right));
|
||||
case '*': return plural_ptr(new mul(left,right));
|
||||
case '%': return plural_ptr(new mod(left,right));
|
||||
case '+': return plural_ptr(new add(left,right));
|
||||
case '-': return plural_ptr(new sub(left,right));
|
||||
case SHL: return plural_ptr(new shl(left,right));
|
||||
case SHR: return plural_ptr(new shr(left,right));
|
||||
case '>': return plural_ptr(new gt(left,right));
|
||||
case '<': return plural_ptr(new lt(left,right));
|
||||
case GTE: return plural_ptr(new gte(left,right));
|
||||
case LTE: return plural_ptr(new lte(left,right));
|
||||
case EQ: return plural_ptr(new eq(left,right));
|
||||
case NEQ: return plural_ptr(new neq(left,right));
|
||||
case '&': return plural_ptr(new bin_and(left,right));
|
||||
case '^': return plural_ptr(new bin_xor(left,right));
|
||||
case '|': return plural_ptr(new bin_or (left,right));
|
||||
case AND: return plural_ptr(new l_and(left,right));
|
||||
case OR: return plural_ptr(new l_or(left,right));
|
||||
default:
|
||||
return plural_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
plural_ptr un_factory(int value,plural_ptr op)
|
||||
{
|
||||
switch(value) {
|
||||
case '!': return plural_ptr(new l_not(op));
|
||||
case '~': return plural_ptr(new bin_not(op));
|
||||
case '-': return plural_ptr(new minus(op));
|
||||
default:
|
||||
return plural_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_in(int v,int *p)
|
||||
{
|
||||
int len=*p;
|
||||
p++;
|
||||
while(len && *p!=v) { p++;len--; }
|
||||
return len!=0;
|
||||
}
|
||||
|
||||
|
||||
class tokenizer {
|
||||
public:
|
||||
tokenizer(char const *s) { text=s; pos=0; step(); };
|
||||
int get(int *val=NULL){
|
||||
int iv=int_value;
|
||||
int res=next_tocken;
|
||||
step();
|
||||
if(val && res==NUM){
|
||||
*val=iv;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
int next(int *val=NULL) {
|
||||
if(val && next_tocken==NUM) {
|
||||
*val=int_value;
|
||||
return NUM;
|
||||
}
|
||||
return next_tocken;
|
||||
}
|
||||
private:
|
||||
char const *text;
|
||||
int pos;
|
||||
int next_tocken;
|
||||
int int_value;
|
||||
bool is_blank(char c)
|
||||
{
|
||||
return c==' ' || c=='\r' || c=='\n' || c=='\t';
|
||||
}
|
||||
bool isdigit(char c)
|
||||
{
|
||||
return '0'<=c && c<='9';
|
||||
}
|
||||
void step()
|
||||
{
|
||||
while(text[pos] && is_blank(text[pos])) pos++;
|
||||
char const *ptr=text+pos;
|
||||
char *tmp_ptr;
|
||||
if(strncmp(ptr,"<<",2)==0) { pos+=2; next_tocken=SHL; }
|
||||
else if(strncmp(ptr,">>",2)==0) { pos+=2; next_tocken=SHR; }
|
||||
else if(strncmp(ptr,"&&",2)==0) { pos+=2; next_tocken=AND; }
|
||||
else if(strncmp(ptr,"||",2)==0) { pos+=2; next_tocken=OR; }
|
||||
else if(strncmp(ptr,"<=",2)==0) { pos+=2; next_tocken=LTE; }
|
||||
else if(strncmp(ptr,">=",2)==0) { pos+=2; next_tocken=GTE; }
|
||||
else if(strncmp(ptr,"==",2)==0) { pos+=2; next_tocken=EQ; }
|
||||
else if(strncmp(ptr,"!=",2)==0) { pos+=2; next_tocken=NEQ; }
|
||||
else if(*ptr=='n') { pos++; next_tocken=VARIABLE; }
|
||||
else if(isdigit(*ptr)) { int_value=strtol(text+pos,&tmp_ptr,0); pos=tmp_ptr-text; next_tocken=NUM; }
|
||||
else if(*ptr=='\0') { next_tocken=0; }
|
||||
else { next_tocken=*ptr; pos++; }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define BINARY_EXPR(expr,hexpr,list) \
|
||||
plural_ptr expr() \
|
||||
{ \
|
||||
plural_ptr op1,op2; \
|
||||
if((op1=hexpr()).get()==0) \
|
||||
return plural_ptr(); \
|
||||
while(is_in(t.next(),list)) { \
|
||||
int o=t.get(); \
|
||||
if((op2=hexpr()).get()==0) \
|
||||
return plural_ptr(); \
|
||||
op1=bin_factory(o,op1,op2); \
|
||||
} \
|
||||
return op1; \
|
||||
}
|
||||
|
||||
class parser {
|
||||
public:
|
||||
|
||||
parser(tokenizer &tin) : t(tin) {};
|
||||
|
||||
plural_ptr compile()
|
||||
{
|
||||
plural_ptr res=cond_expr();
|
||||
if(res.get() && t.next()!=END) {
|
||||
return plural_ptr();
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
plural_ptr value_expr()
|
||||
{
|
||||
plural_ptr op;
|
||||
if(t.next()=='(') {
|
||||
t.get();
|
||||
if((op=cond_expr()).get()==0)
|
||||
return plural_ptr();
|
||||
if(t.get()!=')')
|
||||
return plural_ptr();
|
||||
return op;
|
||||
}
|
||||
else if(t.next()==NUM) {
|
||||
int value;
|
||||
t.get(&value);
|
||||
return plural_ptr(new number(value));
|
||||
}
|
||||
else if(t.next()==VARIABLE) {
|
||||
t.get();
|
||||
return plural_ptr(new identity());
|
||||
}
|
||||
return plural_ptr();
|
||||
};
|
||||
|
||||
plural_ptr un_expr()
|
||||
{
|
||||
plural_ptr op1;
|
||||
static int level_unary[]={3,'-','!','~'};
|
||||
if(is_in(t.next(),level_unary)) {
|
||||
int op=t.get();
|
||||
if((op1=un_expr()).get()==0)
|
||||
return plural_ptr();
|
||||
switch(op) {
|
||||
case '-':
|
||||
return plural_ptr(new minus(op1));
|
||||
case '!':
|
||||
return plural_ptr(new l_not(op1));
|
||||
case '~':
|
||||
return plural_ptr(new bin_not(op1));
|
||||
default:
|
||||
return plural_ptr();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return value_expr();
|
||||
}
|
||||
};
|
||||
|
||||
BINARY_EXPR(l10,un_expr,level10);
|
||||
BINARY_EXPR(l9,l10,level9);
|
||||
BINARY_EXPR(l8,l9,level8);
|
||||
BINARY_EXPR(l7,l8,level7);
|
||||
BINARY_EXPR(l6,l7,level6);
|
||||
BINARY_EXPR(l5,l6,level5);
|
||||
BINARY_EXPR(l4,l5,level4);
|
||||
BINARY_EXPR(l3,l4,level3);
|
||||
BINARY_EXPR(l2,l3,level2);
|
||||
BINARY_EXPR(l1,l2,level1);
|
||||
|
||||
plural_ptr cond_expr()
|
||||
{
|
||||
plural_ptr cond,case1,case2;
|
||||
if((cond=l1()).get()==0)
|
||||
return plural_ptr();
|
||||
if(t.next()=='?') {
|
||||
t.get();
|
||||
if((case1=cond_expr()).get()==0)
|
||||
return plural_ptr();
|
||||
if(t.get()!=':')
|
||||
return plural_ptr();
|
||||
if((case2=cond_expr()).get()==0)
|
||||
return plural_ptr();
|
||||
}
|
||||
else {
|
||||
return cond;
|
||||
}
|
||||
return plural_ptr(new conditional(cond,case1,case2));
|
||||
}
|
||||
|
||||
tokenizer &t;
|
||||
|
||||
};
|
||||
|
||||
} // namespace anon
|
||||
|
||||
plural_ptr compile(char const *str)
|
||||
{
|
||||
tokenizer t(str);
|
||||
parser p(t);
|
||||
return p.compile();
|
||||
}
|
||||
|
||||
|
||||
} // lambda
|
||||
} // gnu_gettext
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
38
src/boost/libs/locale/src/shared/mo_lambda.hpp
Normal file
38
src/boost/libs/locale/src/shared/mo_lambda.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_SRC_LOCALE_MO_LAMBDA_HPP_INCLUDED
|
||||
#define BOOST_SRC_LOCALE_MO_LAMBDA_HPP_INCLUDED
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace gnu_gettext {
|
||||
namespace lambda {
|
||||
|
||||
struct plural {
|
||||
|
||||
virtual int operator()(int n) const = 0;
|
||||
virtual plural *clone() const = 0;
|
||||
virtual ~plural()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::auto_ptr<plural> plural_ptr;
|
||||
|
||||
plural_ptr compile(char const *c_expression);
|
||||
|
||||
} // lambda
|
||||
} // gnu_gettext
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
54
src/boost/libs/locale/src/std/all_generator.hpp
Normal file
54
src/boost/libs/locale/src/std/all_generator.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_STD_ALL_GENERATOR_HPP
|
||||
#define BOOST_LOCALE_IMPL_STD_ALL_GENERATOR_HPP
|
||||
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_std {
|
||||
typedef enum {
|
||||
utf8_none,
|
||||
utf8_native,
|
||||
utf8_native_with_wide,
|
||||
utf8_from_wide
|
||||
} utf8_support;
|
||||
|
||||
std::locale create_convert( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf = utf8_none);
|
||||
|
||||
std::locale create_collate( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf = utf8_none);
|
||||
|
||||
std::locale create_formatting( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf = utf8_none);
|
||||
|
||||
std::locale create_parsing( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf = utf8_none);
|
||||
|
||||
std::locale create_codecvt( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf = utf8_none);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
55
src/boost/libs/locale/src/std/codecvt.cpp
Normal file
55
src/boost/libs/locale/src/std/codecvt.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/locale/util.hpp>
|
||||
#include "all_generator.hpp"
|
||||
#include <vector>
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_std {
|
||||
template<typename CharType>
|
||||
std::locale codecvt_bychar( std::locale const &in,
|
||||
std::string const &locale_name)
|
||||
{
|
||||
return std::locale(in,new std::codecvt_byname<CharType,char,std::mbstate_t>(locale_name.c_str()));
|
||||
}
|
||||
|
||||
|
||||
std::locale create_codecvt( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf)
|
||||
{
|
||||
if(utf == utf8_from_wide) {
|
||||
return util::create_codecvt(in,util::create_utf8_converter(),type);
|
||||
}
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return codecvt_bychar<char>(in,locale_name);
|
||||
case wchar_t_facet:
|
||||
return codecvt_bychar<wchar_t>(in,locale_name);
|
||||
#if defined(BOOST_HAS_CHAR16_T) && !defined(BOOST_NO_CHAR16_T_CODECVT)
|
||||
case char16_t_facet:
|
||||
return codecvt_bychar<char16_t>(in,locale_name);
|
||||
#endif
|
||||
#if defined(BOOST_HAS_CHAR32_T) && !defined(BOOST_NO_CHAR32_T_CODECVT)
|
||||
case char32_t_facet:
|
||||
return codecvt_bychar<char32_t>(in,locale_name);
|
||||
#endif
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
113
src/boost/libs/locale/src/std/collate.cpp
Normal file
113
src/boost/libs/locale/src/std/collate.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include "all_generator.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_std {
|
||||
|
||||
class utf8_collator_from_wide : public std::collate<char> {
|
||||
public:
|
||||
typedef std::collate<wchar_t> wfacet;
|
||||
utf8_collator_from_wide(std::locale const &base,size_t refs = 0) :
|
||||
std::collate<char>(refs),
|
||||
base_(base)
|
||||
{
|
||||
}
|
||||
virtual int do_compare(char const *lb,char const *le,char const *rb,char const *re) const
|
||||
{
|
||||
std::wstring l=conv::to_utf<wchar_t>(lb,le,"UTF-8");
|
||||
std::wstring r=conv::to_utf<wchar_t>(rb,re,"UTF-8");
|
||||
return std::use_facet<wfacet>(base_).compare( l.c_str(),l.c_str()+l.size(),
|
||||
r.c_str(),r.c_str()+r.size());
|
||||
}
|
||||
virtual long do_hash(char const *b,char const *e) const
|
||||
{
|
||||
std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
|
||||
return std::use_facet<wfacet>(base_).hash(tmp.c_str(),tmp.c_str()+tmp.size());
|
||||
}
|
||||
virtual std::string do_transform(char const *b,char const *e) const
|
||||
{
|
||||
std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
|
||||
std::wstring wkey =
|
||||
std::use_facet<wfacet>(base_).transform(tmp.c_str(),tmp.c_str()+tmp.size());
|
||||
std::string key;
|
||||
if(sizeof(wchar_t)==2)
|
||||
key.reserve(wkey.size()*2);
|
||||
else
|
||||
key.reserve(wkey.size()*3);
|
||||
for(unsigned i=0;i<wkey.size();i++) {
|
||||
if(sizeof(wchar_t)==2) {
|
||||
uint16_t tv = static_cast<uint16_t>(wkey[i]);
|
||||
key += char(tv >> 8);
|
||||
key += char(tv & 0xFF);
|
||||
}
|
||||
else { // 4
|
||||
uint32_t tv = static_cast<uint32_t>(wkey[i]);
|
||||
// 21 bit
|
||||
key += char((tv >> 16) & 0xFF);
|
||||
key += char((tv >> 8) & 0xFF);
|
||||
key += char(tv & 0xFF);
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
private:
|
||||
std::locale base_;
|
||||
};
|
||||
|
||||
std::locale create_collate( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
{
|
||||
if(utf == utf8_from_wide) {
|
||||
std::locale base=
|
||||
std::locale(std::locale::classic(),
|
||||
new std::collate_byname<wchar_t>(locale_name.c_str()));
|
||||
return std::locale(in,new utf8_collator_from_wide(base));
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::locale(in,new std::collate_byname<char>(locale_name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new std::collate_byname<wchar_t>(locale_name.c_str()));
|
||||
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
case char16_t_facet:
|
||||
return std::locale(in,new std::collate_byname<char16_t>(locale_name.c_str()));
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
case char32_t_facet:
|
||||
return std::locale(in,new std::collate_byname<char32_t>(locale_name.c_str()));
|
||||
#endif
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
148
src/boost/libs/locale/src/std/converter.cpp
Normal file
148
src/boost/libs/locale/src/std/converter.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
#include "all_generator.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_std {
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class std_converter : public converter<CharType>
|
||||
{
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
typedef std::ctype<char_type> ctype_type;
|
||||
std_converter(std::locale const &base,size_t refs = 0) :
|
||||
converter<CharType>(refs),
|
||||
base_(base)
|
||||
{
|
||||
}
|
||||
virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const
|
||||
{
|
||||
switch(how) {
|
||||
case converter_base::upper_case:
|
||||
case converter_base::lower_case:
|
||||
case converter_base::case_folding:
|
||||
{
|
||||
ctype_type const &ct=std::use_facet<ctype_type>(base_);
|
||||
size_t len = end - begin;
|
||||
std::vector<char_type> res(len+1,0);
|
||||
char_type *lbegin = &res[0];
|
||||
std::copy(begin,end,lbegin);
|
||||
if(how == converter_base::upper_case)
|
||||
ct.toupper(lbegin,lbegin+len);
|
||||
else
|
||||
ct.tolower(lbegin,lbegin+len);
|
||||
return string_type(lbegin,len);
|
||||
}
|
||||
default:
|
||||
return string_type(begin,end-begin);
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::locale base_;
|
||||
};
|
||||
|
||||
class utf8_converter : public converter<char> {
|
||||
public:
|
||||
typedef std::ctype<char> ctype_type;
|
||||
typedef std::ctype<wchar_t> wctype_type;
|
||||
utf8_converter(std::locale const &base,size_t refs = 0) :
|
||||
converter<char>(refs),
|
||||
base_(base)
|
||||
{
|
||||
}
|
||||
virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const
|
||||
{
|
||||
switch(how) {
|
||||
case upper_case:
|
||||
case lower_case:
|
||||
case case_folding:
|
||||
{
|
||||
std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
|
||||
wctype_type const &ct=std::use_facet<wctype_type>(base_);
|
||||
size_t len = tmp.size();
|
||||
std::vector<wchar_t> res(len+1,0);
|
||||
wchar_t *lbegin = &res[0];
|
||||
std::copy(tmp.c_str(),tmp.c_str()+len,lbegin);
|
||||
if(how == upper_case)
|
||||
ct.toupper(lbegin,lbegin+len);
|
||||
else
|
||||
ct.tolower(lbegin,lbegin+len);
|
||||
return conv::from_utf<wchar_t>(lbegin,lbegin+len,"UTF-8");
|
||||
}
|
||||
default:
|
||||
return std::string(begin,end-begin);
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::locale base_;
|
||||
};
|
||||
|
||||
std::locale create_convert( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
{
|
||||
if(utf == utf8_native_with_wide || utf == utf8_from_wide) {
|
||||
std::locale base(std::locale::classic(),new std::ctype_byname<wchar_t>(locale_name.c_str()));
|
||||
return std::locale(in,new utf8_converter(base));
|
||||
}
|
||||
std::locale base(std::locale::classic(),new std::ctype_byname<char>(locale_name.c_str()));
|
||||
return std::locale(in,new std_converter<char>(base));
|
||||
}
|
||||
case wchar_t_facet:
|
||||
{
|
||||
std::locale base(std::locale::classic(),new std::ctype_byname<wchar_t>(locale_name.c_str()));
|
||||
return std::locale(in,new std_converter<wchar_t>(base));
|
||||
}
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
case char16_t_facet:
|
||||
{
|
||||
std::locale base(std::locale::classic(),new std::ctype_byname<char16_t>(locale_name.c_str()));
|
||||
return std::locale(in,new std_converter<char16_t>(base));
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
case char32_t_facet:
|
||||
{
|
||||
std::locale base(std::locale::classic(),new std::ctype_byname<char32_t>(locale_name.c_str()));
|
||||
return std::locale(in,new std_converter<char32_t>(base));
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace impl_std
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
456
src/boost/libs/locale/src/std/numeric.cpp
Normal file
456
src/boost/libs/locale/src/std/numeric.cpp
Normal file
@@ -0,0 +1,456 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../util/numeric.hpp"
|
||||
#include "all_generator.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_std {
|
||||
|
||||
template<typename CharType>
|
||||
class time_put_from_base : public std::time_put<CharType> {
|
||||
public:
|
||||
time_put_from_base(std::locale const &base, size_t refs = 0) :
|
||||
std::time_put<CharType>(refs),
|
||||
base_(base)
|
||||
{
|
||||
}
|
||||
typedef typename std::time_put<CharType>::iter_type iter_type;
|
||||
|
||||
virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType fill,std::tm const *tm,char format,char modifier) const
|
||||
{
|
||||
std::basic_stringstream<CharType> ss;
|
||||
ss.imbue(base_);
|
||||
return std::use_facet<std::time_put<CharType> >(base_).put(out,ss,fill,tm,format,modifier);
|
||||
}
|
||||
private:
|
||||
std::locale base_;
|
||||
};
|
||||
|
||||
class utf8_time_put_from_wide : public std::time_put<char> {
|
||||
public:
|
||||
utf8_time_put_from_wide(std::locale const &base, size_t refs = 0) :
|
||||
std::time_put<char>(refs),
|
||||
base_(base)
|
||||
{
|
||||
}
|
||||
virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,char fill,std::tm const *tm,char format,char modifier = 0) const
|
||||
{
|
||||
std::basic_ostringstream<wchar_t> wtmps;
|
||||
wtmps.imbue(base_);
|
||||
std::use_facet<std::time_put<wchar_t> >(base_).put(wtmps,wtmps,wchar_t(fill),tm,wchar_t(format),wchar_t(modifier));
|
||||
std::wstring wtmp=wtmps.str();
|
||||
std::string const tmp = conv::from_utf<wchar_t>(wtmp,"UTF-8");
|
||||
for(unsigned i=0;i<tmp.size();i++) {
|
||||
*out++ = tmp[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
private:
|
||||
std::locale base_;
|
||||
};
|
||||
|
||||
class utf8_numpunct_from_wide : public std::numpunct<char> {
|
||||
public:
|
||||
utf8_numpunct_from_wide(std::locale const &base,size_t refs = 0) : std::numpunct<char>(refs)
|
||||
{
|
||||
typedef std::numpunct<wchar_t> wfacet_type;
|
||||
wfacet_type const &wfacet = std::use_facet<wfacet_type>(base);
|
||||
|
||||
truename_ = conv::from_utf<wchar_t>(wfacet.truename(),"UTF-8");
|
||||
falsename_ = conv::from_utf<wchar_t>(wfacet.falsename(),"UTF-8");
|
||||
|
||||
wchar_t tmp_decimal_point = wfacet.decimal_point();
|
||||
wchar_t tmp_thousands_sep = wfacet.thousands_sep();
|
||||
std::string tmp_grouping = wfacet.grouping();
|
||||
|
||||
if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 &&
|
||||
32 <= tmp_decimal_point && tmp_decimal_point <=126)
|
||||
{
|
||||
thousands_sep_ = static_cast<char>(tmp_thousands_sep);
|
||||
decimal_point_ = static_cast<char>(tmp_decimal_point);
|
||||
grouping_ = tmp_grouping;
|
||||
}
|
||||
else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) {
|
||||
// workaround common bug - substitute NBSP with ordinary space
|
||||
thousands_sep_ = ' ';
|
||||
decimal_point_ = static_cast<char>(tmp_decimal_point);
|
||||
grouping_ = tmp_grouping;
|
||||
}
|
||||
else if(32 <= tmp_decimal_point && tmp_decimal_point <=126)
|
||||
{
|
||||
thousands_sep_=',';
|
||||
decimal_point_ = static_cast<char>(tmp_decimal_point);
|
||||
grouping_=std::string();
|
||||
}
|
||||
else {
|
||||
thousands_sep_ = ',';
|
||||
decimal_point_ = '.';
|
||||
grouping_=std::string();
|
||||
}
|
||||
}
|
||||
|
||||
virtual char do_decimal_point() const
|
||||
{
|
||||
return decimal_point_;
|
||||
}
|
||||
virtual char do_thousands_sep() const
|
||||
{
|
||||
return thousands_sep_;
|
||||
}
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
return grouping_;
|
||||
}
|
||||
virtual std::string do_truename() const
|
||||
{
|
||||
return truename_;
|
||||
}
|
||||
virtual std::string do_falsename() const
|
||||
{
|
||||
return falsename_;
|
||||
}
|
||||
private:
|
||||
std::string truename_;
|
||||
std::string falsename_;
|
||||
char thousands_sep_;
|
||||
char decimal_point_;
|
||||
std::string grouping_;
|
||||
|
||||
};
|
||||
|
||||
template<bool Intl>
|
||||
class utf8_moneypunct_from_wide : public std::moneypunct<char,Intl> {
|
||||
public:
|
||||
utf8_moneypunct_from_wide(std::locale const &base,size_t refs = 0) : std::moneypunct<char,Intl>(refs)
|
||||
{
|
||||
typedef std::moneypunct<wchar_t,Intl> wfacet_type;
|
||||
wfacet_type const &wfacet = std::use_facet<wfacet_type>(base);
|
||||
|
||||
curr_symbol_ = conv::from_utf<wchar_t>(wfacet.curr_symbol(),"UTF-8");
|
||||
positive_sign_ = conv::from_utf<wchar_t>(wfacet.positive_sign(),"UTF-8");
|
||||
negative_sign_ = conv::from_utf<wchar_t>(wfacet.negative_sign(),"UTF-8");
|
||||
frac_digits_ = wfacet.frac_digits();
|
||||
pos_format_ = wfacet.pos_format();
|
||||
neg_format_ = wfacet.neg_format();
|
||||
|
||||
wchar_t tmp_decimal_point = wfacet.decimal_point();
|
||||
wchar_t tmp_thousands_sep = wfacet.thousands_sep();
|
||||
std::string tmp_grouping = wfacet.grouping();
|
||||
if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 &&
|
||||
32 <= tmp_decimal_point && tmp_decimal_point <=126)
|
||||
{
|
||||
thousands_sep_ = static_cast<char>(tmp_thousands_sep);
|
||||
decimal_point_ = static_cast<char>(tmp_decimal_point);
|
||||
grouping_ = tmp_grouping;
|
||||
}
|
||||
else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) {
|
||||
// workaround common bug - substitute NBSP with ordinary space
|
||||
thousands_sep_ = ' ';
|
||||
decimal_point_ = static_cast<char>(tmp_decimal_point);
|
||||
grouping_ = tmp_grouping;
|
||||
}
|
||||
else if(32 <= tmp_decimal_point && tmp_decimal_point <=126)
|
||||
{
|
||||
thousands_sep_=',';
|
||||
decimal_point_ = static_cast<char>(tmp_decimal_point);
|
||||
grouping_=std::string();
|
||||
}
|
||||
else {
|
||||
thousands_sep_ = ',';
|
||||
decimal_point_ = '.';
|
||||
grouping_=std::string();
|
||||
}
|
||||
}
|
||||
|
||||
virtual char do_decimal_point() const
|
||||
{
|
||||
return decimal_point_;
|
||||
}
|
||||
|
||||
virtual char do_thousands_sep() const
|
||||
{
|
||||
return thousands_sep_;
|
||||
}
|
||||
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
return grouping_;
|
||||
}
|
||||
|
||||
virtual std::string do_curr_symbol() const
|
||||
{
|
||||
return curr_symbol_;
|
||||
}
|
||||
virtual std::string do_positive_sign () const
|
||||
{
|
||||
return positive_sign_;
|
||||
}
|
||||
virtual std::string do_negative_sign() const
|
||||
{
|
||||
return negative_sign_;
|
||||
}
|
||||
|
||||
virtual int do_frac_digits() const
|
||||
{
|
||||
return frac_digits_;
|
||||
}
|
||||
|
||||
virtual std::money_base::pattern do_pos_format() const
|
||||
{
|
||||
return pos_format_;
|
||||
}
|
||||
|
||||
virtual std::money_base::pattern do_neg_format() const
|
||||
{
|
||||
return neg_format_;
|
||||
}
|
||||
|
||||
private:
|
||||
char thousands_sep_;
|
||||
char decimal_point_;
|
||||
std::string grouping_;
|
||||
std::string curr_symbol_;
|
||||
std::string positive_sign_;
|
||||
std::string negative_sign_;
|
||||
int frac_digits_;
|
||||
std::money_base::pattern pos_format_,neg_format_;
|
||||
|
||||
};
|
||||
|
||||
class utf8_numpunct : public std::numpunct_byname<char> {
|
||||
public:
|
||||
typedef std::numpunct_byname<char> base_type;
|
||||
utf8_numpunct(char const *name,size_t refs = 0) :
|
||||
std::numpunct_byname<char>(name,refs)
|
||||
{
|
||||
}
|
||||
virtual char do_thousands_sep() const
|
||||
{
|
||||
unsigned char bs = base_type::do_thousands_sep();
|
||||
if(bs > 127)
|
||||
if(bs == 0xA0)
|
||||
return ' ';
|
||||
else
|
||||
return 0;
|
||||
else
|
||||
return bs;
|
||||
}
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
unsigned char bs = base_type::do_thousands_sep();
|
||||
if(bs > 127 && bs != 0xA0)
|
||||
return std::string();
|
||||
return base_type::do_grouping();
|
||||
}
|
||||
};
|
||||
|
||||
template<bool Intl>
|
||||
class utf8_moneypunct : public std::moneypunct_byname<char,Intl> {
|
||||
public:
|
||||
typedef std::moneypunct_byname<char,Intl> base_type;
|
||||
utf8_moneypunct(char const *name,size_t refs = 0) :
|
||||
std::moneypunct_byname<char,Intl>(name,refs)
|
||||
{
|
||||
}
|
||||
virtual char do_thousands_sep() const
|
||||
{
|
||||
unsigned char bs = base_type::do_thousands_sep();
|
||||
if(bs > 127)
|
||||
if(bs == 0xA0)
|
||||
return ' ';
|
||||
else
|
||||
return 0;
|
||||
else
|
||||
return bs;
|
||||
}
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
unsigned char bs = base_type::do_thousands_sep();
|
||||
if(bs > 127 && bs != 0xA0)
|
||||
return std::string();
|
||||
return base_type::do_grouping();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
std::locale create_basic_parsing(std::locale const &in,std::string const &locale_name)
|
||||
{
|
||||
std::locale tmp = std::locale(in,new std::numpunct_byname<CharType>(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new std::moneypunct_byname<CharType,true>(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new std::moneypunct_byname<CharType,false>(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new std::ctype_byname<CharType>(locale_name.c_str()));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
std::locale create_basic_formatting(std::locale const &in,std::string const &locale_name)
|
||||
{
|
||||
std::locale tmp = create_basic_parsing<CharType>(in,locale_name);
|
||||
std::locale base(locale_name.c_str());
|
||||
tmp = std::locale(tmp,new time_put_from_base<CharType>(base));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
std::locale create_formatting( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
{
|
||||
if(utf == utf8_from_wide ) {
|
||||
std::locale base = std::locale(locale_name.c_str());
|
||||
|
||||
std::locale tmp = std::locale(in,new utf8_time_put_from_wide(base));
|
||||
tmp = std::locale(tmp,new utf8_numpunct_from_wide(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
|
||||
return std::locale(tmp,new util::base_num_format<char>());
|
||||
}
|
||||
else if(utf == utf8_native) {
|
||||
std::locale base = std::locale(locale_name.c_str());
|
||||
|
||||
std::locale tmp = std::locale(in,new time_put_from_base<char>(base));
|
||||
tmp = std::locale(tmp,new utf8_numpunct(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct<true>(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct<false>(locale_name.c_str()));
|
||||
return std::locale(tmp,new util::base_num_format<char>());
|
||||
}
|
||||
else if(utf == utf8_native_with_wide) {
|
||||
std::locale base = std::locale(locale_name.c_str());
|
||||
|
||||
std::locale tmp = std::locale(in,new time_put_from_base<char>(base));
|
||||
tmp = std::locale(tmp,new utf8_numpunct_from_wide(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
|
||||
return std::locale(tmp,new util::base_num_format<char>());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::locale tmp = create_basic_formatting<char>(in,locale_name);
|
||||
tmp = std::locale(tmp,new util::base_num_format<char>());
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
case wchar_t_facet:
|
||||
{
|
||||
std::locale tmp = create_basic_formatting<wchar_t>(in,locale_name);
|
||||
tmp = std::locale(tmp,new util::base_num_format<wchar_t>());
|
||||
return tmp;
|
||||
}
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
case char16_t_facet:
|
||||
{
|
||||
std::locale tmp = create_basic_formatting<char16_t>(in,locale_name);
|
||||
tmp = std::locale(tmp,new util::base_num_format<char16_t>());
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
case char32_t_facet:
|
||||
{
|
||||
std::locale tmp = create_basic_formatting<char32_t>(in,locale_name);
|
||||
tmp = std::locale(tmp,new util::base_num_format<char32_t>());
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
std::locale create_parsing( std::locale const &in,
|
||||
std::string const &locale_name,
|
||||
character_facet_type type,
|
||||
utf8_support utf)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
{
|
||||
if(utf == utf8_from_wide ) {
|
||||
std::locale base = std::locale::classic();
|
||||
|
||||
base = std::locale(base,new std::numpunct_byname<wchar_t>(locale_name.c_str()));
|
||||
base = std::locale(base,new std::moneypunct_byname<wchar_t,true>(locale_name.c_str()));
|
||||
base = std::locale(base,new std::moneypunct_byname<wchar_t,false>(locale_name.c_str()));
|
||||
|
||||
std::locale tmp = std::locale(in,new utf8_numpunct_from_wide(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
|
||||
return std::locale(tmp,new util::base_num_parse<char>());
|
||||
}
|
||||
else if(utf == utf8_native) {
|
||||
std::locale tmp = std::locale(in,new utf8_numpunct(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct<true>(locale_name.c_str()));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct<false>(locale_name.c_str()));
|
||||
return std::locale(tmp,new util::base_num_parse<char>());
|
||||
}
|
||||
else if(utf == utf8_native_with_wide) {
|
||||
std::locale base = std::locale(locale_name.c_str());
|
||||
|
||||
std::locale tmp = std::locale(in,new utf8_numpunct_from_wide(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
|
||||
tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
|
||||
return std::locale(tmp,new util::base_num_parse<char>());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::locale tmp = create_basic_parsing<char>(in,locale_name);
|
||||
tmp = std::locale(in,new util::base_num_parse<char>());
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
case wchar_t_facet:
|
||||
{
|
||||
std::locale tmp = create_basic_parsing<wchar_t>(in,locale_name);
|
||||
tmp = std::locale(in,new util::base_num_parse<wchar_t>());
|
||||
return tmp;
|
||||
}
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
case char16_t_facet:
|
||||
{
|
||||
std::locale tmp = create_basic_parsing<char16_t>(in,locale_name);
|
||||
tmp = std::locale(in,new util::base_num_parse<char16_t>());
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
case char32_t_facet:
|
||||
{
|
||||
std::locale tmp = create_basic_parsing<char32_t>(in,locale_name);
|
||||
tmp = std::locale(in,new util::base_num_parse<char32_t>());
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
234
src/boost/libs/locale/src/std/std_backend.cpp
Normal file
234
src/boost/libs/locale/src/std/std_backend.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/locale/gnu_gettext.hpp>
|
||||
#include "all_generator.hpp"
|
||||
#include "../util/locale_data.hpp"
|
||||
#include "../util/gregorian.hpp"
|
||||
#include <boost/locale/util.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include "../encoding/conv.hpp"
|
||||
# include "../win32/lcid.hpp"
|
||||
#endif
|
||||
|
||||
#include "std_backend.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_std {
|
||||
|
||||
class std_localization_backend : public localization_backend {
|
||||
public:
|
||||
std_localization_backend() :
|
||||
invalid_(true),
|
||||
use_ansi_encoding_(false)
|
||||
{
|
||||
}
|
||||
std_localization_backend(std_localization_backend const &other) :
|
||||
localization_backend(),
|
||||
paths_(other.paths_),
|
||||
domains_(other.domains_),
|
||||
locale_id_(other.locale_id_),
|
||||
invalid_(true),
|
||||
use_ansi_encoding_(other.use_ansi_encoding_)
|
||||
{
|
||||
}
|
||||
virtual std_localization_backend *clone() const
|
||||
{
|
||||
return new std_localization_backend(*this);
|
||||
}
|
||||
|
||||
void set_option(std::string const &name,std::string const &value)
|
||||
{
|
||||
invalid_ = true;
|
||||
if(name=="locale")
|
||||
locale_id_ = value;
|
||||
else if(name=="message_path")
|
||||
paths_.push_back(value);
|
||||
else if(name=="message_application")
|
||||
domains_.push_back(value);
|
||||
else if(name=="use_ansi_encoding")
|
||||
use_ansi_encoding_ = value == "true";
|
||||
|
||||
}
|
||||
void clear_options()
|
||||
{
|
||||
invalid_ = true;
|
||||
use_ansi_encoding_ = false;
|
||||
locale_id_.clear();
|
||||
paths_.clear();
|
||||
domains_.clear();
|
||||
}
|
||||
|
||||
void prepare_data()
|
||||
{
|
||||
if(!invalid_)
|
||||
return;
|
||||
invalid_ = false;
|
||||
std::string lid=locale_id_;
|
||||
if(lid.empty()) {
|
||||
bool use_utf8 = ! use_ansi_encoding_;
|
||||
lid = util::get_system_locale(use_utf8);
|
||||
}
|
||||
in_use_id_ = lid;
|
||||
data_.parse(lid);
|
||||
name_ = "C";
|
||||
utf_mode_ = utf8_none;
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
std::pair<std::string,int> wl_inf = to_windows_name(lid);
|
||||
std::string win_name = wl_inf.first;
|
||||
int win_codepage = wl_inf.second;
|
||||
#endif
|
||||
|
||||
if(!data_.utf8) {
|
||||
if(loadable(lid)) {
|
||||
name_ = lid;
|
||||
utf_mode_ = utf8_none;
|
||||
}
|
||||
#if defined(BOOST_WINDOWS)
|
||||
else if(loadable(win_name)
|
||||
&& win_codepage == conv::impl::encoding_to_windows_codepage(data_.encoding.c_str()))
|
||||
{
|
||||
name_ = win_name;
|
||||
utf_mode_ = utf8_none;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if(loadable(lid)) {
|
||||
name_ = lid;
|
||||
utf_mode_ = utf8_native_with_wide;
|
||||
}
|
||||
#if defined(BOOST_WINDOWS)
|
||||
else if(loadable(win_name)) {
|
||||
name_ = win_name;
|
||||
utf_mode_ = utf8_from_wide;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
std::pair<std::string,int> to_windows_name(std::string const &l)
|
||||
{
|
||||
std::pair<std::string,int> res("C",0);
|
||||
unsigned lcid = impl_win::locale_to_lcid(l);
|
||||
char win_lang[256] = {0};
|
||||
char win_country[256] = {0};
|
||||
char win_codepage[10] = {0};
|
||||
if(GetLocaleInfoA(lcid,LOCALE_SENGLANGUAGE,win_lang,sizeof(win_lang))==0)
|
||||
return res;
|
||||
std::string lc_name = win_lang;
|
||||
if(GetLocaleInfoA(lcid,LOCALE_SENGCOUNTRY,win_country,sizeof(win_country))!=0) {
|
||||
lc_name += "_";
|
||||
lc_name += win_country;
|
||||
}
|
||||
|
||||
res.first = lc_name;
|
||||
|
||||
if(GetLocaleInfoA(lcid,LOCALE_IDEFAULTANSICODEPAGE,win_codepage,sizeof(win_codepage))!=0)
|
||||
res.second = atoi(win_codepage);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool loadable(std::string name)
|
||||
{
|
||||
try {
|
||||
std::locale l(name.c_str());
|
||||
return true;
|
||||
}
|
||||
catch(std::exception const &/*e*/) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::locale install(std::locale const &base,
|
||||
locale_category_type category,
|
||||
character_facet_type type = nochar_facet)
|
||||
{
|
||||
prepare_data();
|
||||
|
||||
switch(category) {
|
||||
case convert_facet:
|
||||
return create_convert(base,name_,type,utf_mode_);
|
||||
case collation_facet:
|
||||
return create_collate(base,name_,type,utf_mode_);
|
||||
case formatting_facet:
|
||||
return create_formatting(base,name_,type,utf_mode_);
|
||||
case parsing_facet:
|
||||
return create_parsing(base,name_,type,utf_mode_);
|
||||
case codepage_facet:
|
||||
return create_codecvt(base,name_,type,utf_mode_);
|
||||
case calendar_facet:
|
||||
return util::install_gregorian_calendar(base,data_.country);
|
||||
case message_facet:
|
||||
{
|
||||
gnu_gettext::messages_info minf;
|
||||
minf.language = data_.language;
|
||||
minf.country = data_.country;
|
||||
minf.variant = data_.variant;
|
||||
minf.encoding = data_.encoding;
|
||||
std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
|
||||
minf.paths = paths_;
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
|
||||
case wchar_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
|
||||
#ifdef BOOST_HAS_CHAR16_T
|
||||
case char16_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
|
||||
#endif
|
||||
#ifdef BOOST_HAS_CHAR32_T
|
||||
case char32_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
|
||||
#endif
|
||||
default:
|
||||
return base;
|
||||
}
|
||||
}
|
||||
case information_facet:
|
||||
return util::create_info(base,in_use_id_);
|
||||
default:
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::string> paths_;
|
||||
std::vector<std::string> domains_;
|
||||
std::string locale_id_;
|
||||
|
||||
util::locale_data data_;
|
||||
std::string name_;
|
||||
std::string in_use_id_;
|
||||
utf8_support utf_mode_;
|
||||
bool invalid_;
|
||||
bool use_ansi_encoding_;
|
||||
};
|
||||
|
||||
localization_backend *create_localization_backend()
|
||||
{
|
||||
return new std_localization_backend();
|
||||
}
|
||||
|
||||
} // impl icu
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
20
src/boost/libs/locale/src/std/std_backend.hpp
Normal file
20
src/boost/libs/locale/src/std/std_backend.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP
|
||||
#define BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
class localization_backend;
|
||||
namespace impl_std {
|
||||
localization_backend *create_localization_backend();
|
||||
} // impl_std
|
||||
} // locale
|
||||
} // boost
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
670
src/boost/libs/locale/src/util/codecvt_converter.cpp
Normal file
670
src/boost/libs/locale/src/util/codecvt_converter.cpp
Normal file
@@ -0,0 +1,670 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
|
||||
#include "../encoding/conv.hpp"
|
||||
|
||||
#include <boost/locale/util.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4244 4996) // loose data
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
//#define DEBUG_CODECVT
|
||||
|
||||
#ifdef DEBUG_CODECVT
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
|
||||
class utf8_converter : public base_converter {
|
||||
public:
|
||||
virtual int max_len() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual utf8_converter *clone() const
|
||||
{
|
||||
return new utf8_converter();
|
||||
}
|
||||
|
||||
bool is_thread_safe() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual uint32_t to_unicode(char const *&begin,char const *end)
|
||||
{
|
||||
char const *p=begin;
|
||||
|
||||
utf::code_point c = utf::utf_traits<char>::decode(p,end);
|
||||
|
||||
if(c==utf::illegal)
|
||||
return illegal;
|
||||
|
||||
if(c==utf::incomplete)
|
||||
return incomplete;
|
||||
|
||||
begin = p;
|
||||
return c;
|
||||
}
|
||||
|
||||
virtual uint32_t from_unicode(uint32_t u,char *begin,char const *end)
|
||||
{
|
||||
if(!utf::is_valid_codepoint(u))
|
||||
return illegal;
|
||||
int width = utf::utf_traits<char>::width(u);
|
||||
std::ptrdiff_t d=end-begin;
|
||||
if(d < width)
|
||||
return incomplete;
|
||||
utf::utf_traits<char>::encode(u,begin);
|
||||
return width;
|
||||
}
|
||||
}; // utf8_converter
|
||||
|
||||
class simple_converter : public base_converter {
|
||||
public:
|
||||
|
||||
virtual ~simple_converter()
|
||||
{
|
||||
}
|
||||
|
||||
simple_converter(std::string const &encoding)
|
||||
{
|
||||
for(unsigned i=0;i<128;i++)
|
||||
to_unicode_tbl_[i]=i;
|
||||
for(unsigned i=128;i<256;i++) {
|
||||
char buf[2] = { char(i) , 0 };
|
||||
try {
|
||||
std::wstring const tmp = conv::to_utf<wchar_t>(buf,buf+1,encoding,conv::stop);
|
||||
if(tmp.size() == 1) {
|
||||
to_unicode_tbl_[i] = tmp[0];
|
||||
}
|
||||
else {
|
||||
to_unicode_tbl_[i] = illegal;
|
||||
}
|
||||
}
|
||||
catch(conv::conversion_error const &/*e*/) {
|
||||
to_unicode_tbl_[i] = illegal;
|
||||
}
|
||||
}
|
||||
from_unicode_tbl_.resize(256);
|
||||
for(unsigned i=0;i<256;i++) {
|
||||
from_unicode_tbl_[to_unicode_tbl_[i] & 0xFF].push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
virtual int max_len() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual bool is_thread_safe() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual base_converter *clone() const
|
||||
{
|
||||
return new simple_converter(*this);
|
||||
}
|
||||
virtual uint32_t to_unicode(char const *&begin,char const *end)
|
||||
{
|
||||
if(begin==end)
|
||||
return incomplete;
|
||||
unsigned char c = *begin++;
|
||||
return to_unicode_tbl_[c];
|
||||
}
|
||||
virtual uint32_t from_unicode(uint32_t u,char *begin,char const *end)
|
||||
{
|
||||
if(begin==end)
|
||||
return incomplete;
|
||||
std::vector<unsigned char> const &tbl = from_unicode_tbl_[u & 0xFF];
|
||||
for(std::vector<unsigned char>::const_iterator p=tbl.begin();p!=tbl.end();++p) {
|
||||
if(to_unicode_tbl_[*p]==u) {
|
||||
*begin++ = *p;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return illegal;
|
||||
}
|
||||
private:
|
||||
uint32_t to_unicode_tbl_[256];
|
||||
std::vector<std::vector<unsigned char> > from_unicode_tbl_;
|
||||
};
|
||||
|
||||
namespace {
|
||||
char const *simple_encoding_table[] = {
|
||||
"cp1250",
|
||||
"cp1251",
|
||||
"cp1252",
|
||||
"cp1253",
|
||||
"cp1254",
|
||||
"cp1255",
|
||||
"cp1256",
|
||||
"cp1257",
|
||||
"iso88591",
|
||||
"iso885913",
|
||||
"iso885915",
|
||||
"iso88592",
|
||||
"iso88593",
|
||||
"iso88594",
|
||||
"iso88595",
|
||||
"iso88596",
|
||||
"iso88597",
|
||||
"iso88598",
|
||||
"iso88599",
|
||||
"koi8r",
|
||||
"koi8u",
|
||||
"usascii",
|
||||
"windows1250",
|
||||
"windows1251",
|
||||
"windows1252",
|
||||
"windows1253",
|
||||
"windows1254",
|
||||
"windows1255",
|
||||
"windows1256",
|
||||
"windows1257"
|
||||
};
|
||||
|
||||
bool compare_strings(char const *l,char const *r)
|
||||
{
|
||||
return strcmp(l,r) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::auto_ptr<base_converter> create_simple_converter(std::string const &encoding)
|
||||
{
|
||||
std::auto_ptr<base_converter> res;
|
||||
std::string norm = conv::impl::normalize_encoding(encoding.c_str());
|
||||
if(std::binary_search<char const **>( simple_encoding_table,
|
||||
simple_encoding_table + sizeof(simple_encoding_table)/sizeof(char const *),
|
||||
norm.c_str(),
|
||||
compare_strings))
|
||||
{
|
||||
res.reset(new simple_converter(encoding));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::auto_ptr<base_converter> create_utf8_converter()
|
||||
{
|
||||
std::auto_ptr<base_converter> res(new utf8_converter());
|
||||
return res;
|
||||
}
|
||||
|
||||
//
|
||||
// Traits for sizeof char
|
||||
//
|
||||
template<typename CharType,int n=sizeof(CharType)>
|
||||
struct uchar_traits;
|
||||
|
||||
template<typename CharType>
|
||||
struct uchar_traits<CharType,2> {
|
||||
typedef uint16_t uint_type;
|
||||
};
|
||||
template<typename CharType>
|
||||
struct uchar_traits<CharType,4> {
|
||||
typedef uint32_t uint_type;
|
||||
};
|
||||
|
||||
// Real codecvt
|
||||
|
||||
template<typename CharType>
|
||||
class code_converter : public std::codecvt<CharType,char,std::mbstate_t>
|
||||
{
|
||||
public:
|
||||
code_converter(std::auto_ptr<base_converter> cvt,size_t refs = 0) :
|
||||
std::codecvt<CharType,char,std::mbstate_t>(refs),
|
||||
cvt_(cvt)
|
||||
{
|
||||
max_len_ = cvt_->max_len();
|
||||
}
|
||||
protected:
|
||||
|
||||
typedef CharType uchar;
|
||||
|
||||
virtual std::codecvt_base::result do_unshift(std::mbstate_t &s,char *from,char * /*to*/,char *&next) const
|
||||
{
|
||||
uint16_t &state = *reinterpret_cast<uint16_t *>(&s);
|
||||
#ifdef DEBUG_CODECVT
|
||||
std::cout << "Entering unshift " << std::hex << state << std::dec << std::endl;
|
||||
#endif
|
||||
if(state != 0)
|
||||
return std::codecvt_base::error;
|
||||
next=from;
|
||||
return std::codecvt_base::ok;
|
||||
}
|
||||
virtual int do_encoding() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual int do_max_length() const throw()
|
||||
{
|
||||
return max_len_;
|
||||
}
|
||||
virtual bool do_always_noconv() const throw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::codecvt_base::result
|
||||
do_in( std::mbstate_t &state,
|
||||
char const *from,
|
||||
char const *from_end,
|
||||
char const *&from_next,
|
||||
uchar *uto,
|
||||
uchar *uto_end,
|
||||
uchar *&uto_next) const
|
||||
{
|
||||
typedef typename uchar_traits<uchar>::uint_type uint_type;
|
||||
uint_type *to=reinterpret_cast<uint_type *>(uto);
|
||||
uint_type *to_end=reinterpret_cast<uint_type *>(uto_end);
|
||||
uint_type *&to_next=reinterpret_cast<uint_type *&>(uto_next);
|
||||
return do_real_in(state,from,from_end,from_next,to,to_end,to_next);
|
||||
}
|
||||
|
||||
virtual int
|
||||
do_length( std::mbstate_t &state,
|
||||
char const *from,
|
||||
char const *from_end,
|
||||
size_t max) const
|
||||
{
|
||||
char const *from_next=from;
|
||||
std::vector<uchar> chrs(max+1);
|
||||
uchar *to=&chrs.front();
|
||||
uchar *to_end=to+max;
|
||||
uchar *to_next=to;
|
||||
do_in(state,from,from_end,from_next,to,to_end,to_next);
|
||||
return from_next-from;
|
||||
}
|
||||
|
||||
virtual std::codecvt_base::result
|
||||
do_out( std::mbstate_t &state,
|
||||
uchar const *ufrom,
|
||||
uchar const *ufrom_end,
|
||||
uchar const *&ufrom_next,
|
||||
char *to,
|
||||
char *to_end,
|
||||
char *&to_next) const
|
||||
{
|
||||
typedef typename uchar_traits<uchar>::uint_type uint_type;
|
||||
uint_type const *from=reinterpret_cast<uint_type const *>(ufrom);
|
||||
uint_type const *from_end=reinterpret_cast<uint_type const *>(ufrom_end);
|
||||
uint_type const *&from_next=reinterpret_cast<uint_type const *&>(ufrom_next);
|
||||
return do_real_out(state,from,from_end,from_next,to,to_end,to_next);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Implementation for UTF-32
|
||||
//
|
||||
std::codecvt_base::result
|
||||
do_real_in( std::mbstate_t &/*state*/,
|
||||
char const *from,
|
||||
char const *from_end,
|
||||
char const *&from_next,
|
||||
uint32_t *to,
|
||||
uint32_t *to_end,
|
||||
uint32_t *&to_next) const
|
||||
{
|
||||
std::auto_ptr<base_converter> cvtp;
|
||||
base_converter *cvt = 0;
|
||||
if(cvt_->is_thread_safe()) {
|
||||
cvt = cvt_.get();
|
||||
}
|
||||
else {
|
||||
cvtp.reset(cvt_->clone());
|
||||
cvt = cvtp.get();
|
||||
}
|
||||
std::codecvt_base::result r=std::codecvt_base::ok;
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
uint32_t ch=cvt->to_unicode(from,from_end);
|
||||
if(ch==base_converter::illegal) {
|
||||
r=std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
if(ch==base_converter::incomplete) {
|
||||
r=std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
*to++=ch;
|
||||
}
|
||||
from_next=from;
|
||||
to_next=to;
|
||||
if(r!=std::codecvt_base::ok)
|
||||
return r;
|
||||
if(from!=from_end)
|
||||
return std::codecvt_base::partial;
|
||||
return r;
|
||||
}
|
||||
|
||||
//
|
||||
// Implementation for UTF-32
|
||||
//
|
||||
std::codecvt_base::result
|
||||
do_real_out(std::mbstate_t &/*state*/, // state is not used there
|
||||
uint32_t const *from,
|
||||
uint32_t const *from_end,
|
||||
uint32_t const *&from_next,
|
||||
char *to,
|
||||
char *to_end,
|
||||
char *&to_next) const
|
||||
{
|
||||
std::auto_ptr<base_converter> cvtp;
|
||||
base_converter *cvt = 0;
|
||||
if(cvt_->is_thread_safe()) {
|
||||
cvt = cvt_.get();
|
||||
}
|
||||
else {
|
||||
cvtp.reset(cvt_->clone());
|
||||
cvt = cvtp.get();
|
||||
}
|
||||
|
||||
std::codecvt_base::result r=std::codecvt_base::ok;
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
uint32_t len=cvt->from_unicode(*from,to,to_end);
|
||||
if(len==base_converter::illegal) {
|
||||
r=std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
if(len==base_converter::incomplete) {
|
||||
r=std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
from++;
|
||||
to+=len;
|
||||
}
|
||||
from_next=from;
|
||||
to_next=to;
|
||||
if(r!=std::codecvt_base::ok)
|
||||
return r;
|
||||
if(from!=from_end)
|
||||
return std::codecvt_base::partial;
|
||||
return r;
|
||||
}
|
||||
|
||||
//
|
||||
// Implementation for UTF-16
|
||||
//
|
||||
std::codecvt_base::result
|
||||
do_real_in( std::mbstate_t &std_state,
|
||||
char const *from,
|
||||
char const *from_end,
|
||||
char const *&from_next,
|
||||
uint16_t *to,
|
||||
uint16_t *to_end,
|
||||
uint16_t *&to_next) const
|
||||
{
|
||||
std::auto_ptr<base_converter> cvtp;
|
||||
base_converter *cvt = 0;
|
||||
if(cvt_->is_thread_safe()) {
|
||||
cvt = cvt_.get();
|
||||
}
|
||||
else {
|
||||
cvtp.reset(cvt_->clone());
|
||||
cvt = cvtp.get();
|
||||
}
|
||||
std::codecvt_base::result r=std::codecvt_base::ok;
|
||||
// mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
|
||||
// according to standard. We use it to keed a flag 0/1 for surrogate pair writing
|
||||
//
|
||||
// if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd
|
||||
// and first pair is written, but no input consumed
|
||||
uint16_t &state = *reinterpret_cast<uint16_t *>(&std_state);
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
#ifdef DEBUG_CODECVT
|
||||
std::cout << "Entering IN--------------" << std::endl;
|
||||
std::cout << "State " << std::hex << state <<std::endl;
|
||||
std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
|
||||
#endif
|
||||
char const *from_saved = from;
|
||||
uint32_t ch=cvt->to_unicode(from,from_end);
|
||||
if(ch==base_converter::illegal) {
|
||||
r=std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
if(ch==base_converter::incomplete) {
|
||||
r=std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
// Normal codepoints go direcly to stream
|
||||
if(ch <= 0xFFFF) {
|
||||
*to++=ch;
|
||||
}
|
||||
else {
|
||||
// for other codepoints we do following
|
||||
//
|
||||
// 1. We can't consume our input as we may find ourselfs
|
||||
// in state where all input consumed but not all output written,i.e. only
|
||||
// 1st pair is written
|
||||
// 2. We only write first pair and mark this in the state, we also revert back
|
||||
// the from pointer in order to make sure this codepoint would be read
|
||||
// once again and then we would consume our input together with writing
|
||||
// second surrogate pair
|
||||
ch-=0x10000;
|
||||
uint16_t vh = ch >> 10;
|
||||
uint16_t vl = ch & 0x3FF;
|
||||
uint16_t w1 = vh + 0xD800;
|
||||
uint16_t w2 = vl + 0xDC00;
|
||||
if(state == 0) {
|
||||
from = from_saved;
|
||||
*to++ = w1;
|
||||
state = 1;
|
||||
}
|
||||
else {
|
||||
*to++ = w2;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
from_next=from;
|
||||
to_next=to;
|
||||
if(r == std::codecvt_base::ok && (from!=from_end || state!=0))
|
||||
r = std::codecvt_base::partial;
|
||||
#ifdef DEBUG_CODECVT
|
||||
std::cout << "Returning ";
|
||||
switch(r) {
|
||||
case std::codecvt_base::ok:
|
||||
std::cout << "ok" << std::endl;
|
||||
break;
|
||||
case std::codecvt_base::partial:
|
||||
std::cout << "partial" << std::endl;
|
||||
break;
|
||||
case std::codecvt_base::error:
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout << "other" << std::endl;
|
||||
break;
|
||||
}
|
||||
std::cout << "State " << std::hex << state <<std::endl;
|
||||
std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
//encoding// Implementation for UTF-16
|
||||
//
|
||||
std::codecvt_base::result
|
||||
do_real_out(std::mbstate_t &std_state,
|
||||
uint16_t const *from,
|
||||
uint16_t const *from_end,
|
||||
uint16_t const *&from_next,
|
||||
char *to,
|
||||
char *to_end,
|
||||
char *&to_next) const
|
||||
{
|
||||
std::auto_ptr<base_converter> cvtp;
|
||||
base_converter *cvt = 0;
|
||||
if(cvt_->is_thread_safe()) {
|
||||
cvt = cvt_.get();
|
||||
}
|
||||
else {
|
||||
cvtp.reset(cvt_->clone());
|
||||
cvt = cvtp.get();
|
||||
}
|
||||
std::codecvt_base::result r=std::codecvt_base::ok;
|
||||
// mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
|
||||
// according to standard. We assume that sizeof(mbstate_t) >=2 in order
|
||||
// to be able to store first observerd surrogate pair
|
||||
//
|
||||
// State: state!=0 - a first surrogate pair was observerd (state = first pair),
|
||||
// we expect the second one to come and then zero the state
|
||||
///
|
||||
uint16_t &state = *reinterpret_cast<uint16_t *>(&std_state);
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
#ifdef DEBUG_CODECVT
|
||||
std::cout << "Entering OUT --------------" << std::endl;
|
||||
std::cout << "State " << std::hex << state <<std::endl;
|
||||
std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
|
||||
#endif
|
||||
uint32_t ch=0;
|
||||
if(state != 0) {
|
||||
// if the state idecates that 1st surrogate pair was written
|
||||
// we should make sure that the second one that comes is actually
|
||||
// second surrogate
|
||||
uint16_t w1 = state;
|
||||
uint16_t w2 = *from;
|
||||
// we don't forward from as writing may fail to incomplete or
|
||||
// partial conversion
|
||||
if(0xDC00 <= w2 && w2<=0xDFFF) {
|
||||
uint16_t vh = w1 - 0xD800;
|
||||
uint16_t vl = w2 - 0xDC00;
|
||||
ch=((uint32_t(vh) << 10) | vl) + 0x10000;
|
||||
}
|
||||
else {
|
||||
// Invalid surrogate
|
||||
r=std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ch = *from;
|
||||
if(0xD800 <= ch && ch<=0xDBFF) {
|
||||
// if this is a first surrogate pair we put
|
||||
// it into the state and consume it, note we don't
|
||||
// go forward as it should be illegal so we increase
|
||||
// the from pointer manually
|
||||
state = ch;
|
||||
from++;
|
||||
continue;
|
||||
}
|
||||
else if(0xDC00 <= ch && ch<=0xDFFF) {
|
||||
// if we observe second surrogate pair and
|
||||
// first only may be expected we should break from the loop with error
|
||||
// as it is illegal input
|
||||
r=std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t len=cvt->from_unicode(ch,to,to_end);
|
||||
if(len==base_converter::illegal) {
|
||||
r=std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
if(len==base_converter::incomplete) {
|
||||
r=std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
state = 0;
|
||||
to+=len;
|
||||
from++;
|
||||
}
|
||||
from_next=from;
|
||||
to_next=to;
|
||||
if(r==std::codecvt_base::ok && from!=from_end)
|
||||
r = std::codecvt_base::partial;
|
||||
#ifdef DEBUG_CODECVT
|
||||
std::cout << "Returning ";
|
||||
switch(r) {
|
||||
case std::codecvt_base::ok:
|
||||
std::cout << "ok" << std::endl;
|
||||
break;
|
||||
case std::codecvt_base::partial:
|
||||
std::cout << "partial" << std::endl;
|
||||
break;
|
||||
case std::codecvt_base::error:
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout << "other" << std::endl;
|
||||
break;
|
||||
}
|
||||
std::cout << "State " << std::hex << state <<std::endl;
|
||||
std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
int max_len_;
|
||||
std::auto_ptr<base_converter> cvt_;
|
||||
|
||||
};
|
||||
|
||||
static const char ensure_mbstate_size_is_at_least_2[sizeof(std::mbstate_t) >= 2 ? 1 : -1] = {0};
|
||||
|
||||
template<>
|
||||
class code_converter<char> : public std::codecvt<char,char,std::mbstate_t>
|
||||
{
|
||||
public:
|
||||
code_converter(std::auto_ptr<base_converter> /*cvt*/,size_t refs = 0) :
|
||||
std::codecvt<char,char,std::mbstate_t>(refs)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
std::locale create_codecvt(std::locale const &in,std::auto_ptr<base_converter> cvt,character_facet_type type)
|
||||
{
|
||||
if(!cvt.get())
|
||||
cvt.reset(new base_converter());
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(in,new code_converter<char>(cvt));
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new code_converter<wchar_t>(cvt));
|
||||
#if defined(BOOST_HAS_CHAR16_T) && !defined(BOOST_NO_CHAR16_T_CODECVT)
|
||||
case char16_t_facet:
|
||||
return std::locale(in,new code_converter<char16_t>(cvt));
|
||||
#endif
|
||||
#if defined(BOOST_HAS_CHAR32_T) && !defined(BOOST_NO_CHAR32_T_CODECVT)
|
||||
case char32_t_facet:
|
||||
return std::locale(in,new code_converter<char32_t>(cvt));
|
||||
#endif
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
80
src/boost/libs/locale/src/util/default_locale.cpp
Normal file
80
src/boost/libs/locale/src/util/default_locale.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/util.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#define BOOST_LOCALE_USE_WIN32_API
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
std::string get_system_locale(bool use_utf8)
|
||||
{
|
||||
char const *lang = 0;
|
||||
if(!lang || !*lang)
|
||||
lang = getenv("LC_CTYPE");
|
||||
if(!lang || !*lang)
|
||||
lang = getenv("LC_ALL");
|
||||
if(!lang || !*lang)
|
||||
lang = getenv("LANG");
|
||||
#ifndef BOOST_LOCALE_USE_WIN32_API
|
||||
(void)use_utf8; // not relevant for non-windows
|
||||
if(!lang || !*lang)
|
||||
lang = "C";
|
||||
return lang;
|
||||
#else
|
||||
if(lang && *lang) {
|
||||
return lang;
|
||||
}
|
||||
char buf[10];
|
||||
if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_SISO639LANGNAME,buf,sizeof(buf))==0)
|
||||
return "C";
|
||||
std::string lc_name = buf;
|
||||
if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_SISO3166CTRYNAME,buf,sizeof(buf))!=0) {
|
||||
lc_name += "_";
|
||||
lc_name += buf;
|
||||
}
|
||||
if(!use_utf8) {
|
||||
if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_IDEFAULTANSICODEPAGE,buf,sizeof(buf))!=0) {
|
||||
if(atoi(buf)==0)
|
||||
lc_name+=".UTF-8";
|
||||
else {
|
||||
lc_name +=".windows-";
|
||||
lc_name +=buf;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lc_name += "UTF-8";
|
||||
}
|
||||
}
|
||||
else {
|
||||
lc_name += ".UTF-8";
|
||||
}
|
||||
return lc_name;
|
||||
|
||||
#endif
|
||||
}
|
||||
} // impl
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
855
src/boost/libs/locale/src/util/gregorian.cpp
Normal file
855
src/boost/libs/locale/src/util/gregorian.cpp
Normal file
@@ -0,0 +1,855 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/date_time_facet.hpp>
|
||||
#include <boost/locale/date_time.hpp>
|
||||
#include <stdlib.h>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "timezone.hpp"
|
||||
#include "gregorian.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
namespace {
|
||||
|
||||
int is_leap(int year)
|
||||
{
|
||||
if(year % 400 == 0)
|
||||
return 1;
|
||||
if(year % 100 == 0)
|
||||
return 0;
|
||||
if(year % 4 == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int days_in_month(int year,int month)
|
||||
{
|
||||
static const int tbl[2][12] = {
|
||||
{ 31,28,31,30,31,30,31,31,30,31,30,31 },
|
||||
{ 31,29,31,30,31,30,31,31,30,31,30,31 }
|
||||
};
|
||||
return tbl[is_leap(year)][month - 1];
|
||||
}
|
||||
|
||||
inline int days_from_0(int year)
|
||||
{
|
||||
year--;
|
||||
return 365 * year + (year / 400) - (year/100) + (year / 4);
|
||||
}
|
||||
|
||||
int days_from_1970(int year)
|
||||
{
|
||||
static const int days_from_0_to_1970 = days_from_0(1970);
|
||||
return days_from_0(year) - days_from_0_to_1970;
|
||||
}
|
||||
|
||||
int days_from_1jan(int year,int month,int day)
|
||||
{
|
||||
static const int days[2][12] = {
|
||||
{ 0,31,59,90,120,151,181,212,243,273,304,334 },
|
||||
{ 0,31,60,91,121,152,182,213,244,274,305,335 }
|
||||
};
|
||||
return days[is_leap(year)][month-1] + day - 1;
|
||||
}
|
||||
|
||||
std::time_t internal_timegm(std::tm const *t)
|
||||
{
|
||||
int year = t->tm_year + 1900;
|
||||
int month = t->tm_mon;
|
||||
if(month > 11) {
|
||||
year += month/12;
|
||||
month %= 12;
|
||||
}
|
||||
else if(month < 0) {
|
||||
int years_diff = (-month + 11)/12;
|
||||
year -= years_diff;
|
||||
month+=12 * years_diff;
|
||||
}
|
||||
month++;
|
||||
int day = t->tm_mday;
|
||||
int day_of_year = days_from_1jan(year,month,day);
|
||||
int days_since_epoch = days_from_1970(year) + day_of_year;
|
||||
|
||||
std::time_t seconds_in_day = 3600 * 24;
|
||||
std::time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // anon
|
||||
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// Locale dependent data
|
||||
|
||||
bool comparator(char const *left,char const *right)
|
||||
{
|
||||
return strcmp(left,right) < 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Ref: CLDR 1.9 common/supplemental/supplementalData.xml
|
||||
//
|
||||
// monday - default
|
||||
// fri - MV
|
||||
// sat - AE AF BH DJ DZ EG ER ET IQ IR JO KE KW LY MA OM QA SA SD SO SY TN YE
|
||||
// sun - AR AS AZ BW CA CN FO GE GL GU HK IL IN JM JP KG KR LA MH MN MO MP MT NZ PH PK SG TH TT TW UM US UZ VI ZW
|
||||
//
|
||||
|
||||
int first_day_of_week(char const *terr) {
|
||||
static char const * const sat[] = {
|
||||
"AE","AF","BH","DJ","DZ","EG","ER","ET","IQ","IR",
|
||||
"JO","KE","KW","LY","MA","OM","QA","SA","SD","SO",
|
||||
"SY","TN","YE"
|
||||
};
|
||||
// workaround for Sun Solaris !@#%@#$%@#$%234
|
||||
#ifdef sun
|
||||
#undef sun
|
||||
#endif
|
||||
static char const * const sun[] = {
|
||||
"AR","AS","AZ","BW","CA","CN","FO","GE","GL","GU",
|
||||
"HK","IL","IN","JM","JP","KG","KR","LA","MH","MN",
|
||||
"MO","MP","MT","NZ","PH","PK","SG","TH","TT","TW",
|
||||
"UM","US","UZ","VI","ZW"
|
||||
};
|
||||
if(strcmp(terr,"MV") == 0)
|
||||
return 5; // fri
|
||||
if(std::binary_search<char const * const *>(sat,sat+sizeof(sat)/(sizeof(sat[0])),terr,comparator))
|
||||
return 6; // sat
|
||||
if(std::binary_search<char const * const *>(sun,sun+sizeof(sun)/(sizeof(sun[0])),terr,comparator))
|
||||
return 0; // sun
|
||||
// default
|
||||
return 1; // mon
|
||||
}
|
||||
}
|
||||
|
||||
class gregorian_calendar : public abstract_calendar {
|
||||
public:
|
||||
|
||||
gregorian_calendar(std::string const &terr)
|
||||
{
|
||||
first_day_of_week_ = first_day_of_week(terr.c_str());
|
||||
time_ = std::time(0);
|
||||
is_local_ = true;
|
||||
tzoff_ = 0;
|
||||
from_time(time_);
|
||||
}
|
||||
|
||||
///
|
||||
/// Make a polymorphic copy of the calendar
|
||||
///
|
||||
virtual gregorian_calendar *clone() const
|
||||
{
|
||||
return new gregorian_calendar(*this);
|
||||
}
|
||||
|
||||
///
|
||||
/// Set specific \a value for period \a p, note not all values are settable.
|
||||
///
|
||||
virtual void set_value(period::marks::period_mark p,int value)
|
||||
{
|
||||
using namespace period::marks;
|
||||
switch(p) {
|
||||
case era: ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1]
|
||||
return;
|
||||
case year: ///< Year, it is calendar specific
|
||||
case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
|
||||
tm_updated_.tm_year = value - 1900;
|
||||
break;
|
||||
case month:
|
||||
tm_updated_.tm_mon = value;
|
||||
break;
|
||||
case day:
|
||||
tm_updated_.tm_mday = value;
|
||||
break;
|
||||
case hour: ///< 24 clock hour [0..23]
|
||||
tm_updated_.tm_hour = value;
|
||||
break;
|
||||
case hour_12: ///< 12 clock hour [0..11]
|
||||
tm_updated_.tm_hour = tm_updated_.tm_hour / 12 * 12 + value;
|
||||
break;
|
||||
case am_pm: ///< am or pm marker, [0..1]
|
||||
tm_updated_.tm_hour = 12 * value + tm_updated_.tm_hour % 12;
|
||||
break;
|
||||
case minute: ///< minute [0..59]
|
||||
tm_updated_.tm_min = value;
|
||||
break;
|
||||
case second:
|
||||
tm_updated_.tm_sec = value;
|
||||
break;
|
||||
case day_of_year:
|
||||
normalize();
|
||||
tm_updated_.tm_mday += (value - (tm_updated_.tm_yday + 1));
|
||||
break;
|
||||
case day_of_week: ///< Day of week, starting from Sunday, [1..7]
|
||||
if(value < 1) // make sure it is positive
|
||||
value += (-value / 7) * 7 + 7;
|
||||
// convert to local DOW
|
||||
value = (value - 1 - first_day_of_week_ + 14) % 7 + 1;
|
||||
// fall throght
|
||||
case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
|
||||
normalize();
|
||||
tm_updated_.tm_mday += (value - 1) - (tm_updated_.tm_wday - first_day_of_week_ + 7) % 7;
|
||||
break;
|
||||
case day_of_week_in_month: ///< Original number of the day of the week in month. (1st sunday, 2nd sunday etc)
|
||||
case week_of_year: ///< The week number in the year, 4 is the minimal number of days to be in month
|
||||
case week_of_month: ///< The week number withing current month
|
||||
{
|
||||
normalize();
|
||||
int current_week = get_value(p,current);
|
||||
int diff = 7 * (value - current_week);
|
||||
tm_updated_.tm_mday += diff;
|
||||
}
|
||||
break;
|
||||
case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
|
||||
default:
|
||||
return;
|
||||
}
|
||||
normalized_ = false;
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
if(!normalized_) {
|
||||
std::tm val = tm_updated_;
|
||||
val.tm_isdst = -1;
|
||||
val.tm_wday = -1; // indecator of error
|
||||
std::time_t point = -1;
|
||||
if(is_local_) {
|
||||
point = std::mktime(&val);
|
||||
if(point == static_cast<std::time_t>(-1)){
|
||||
#ifndef BOOST_WINDOWS
|
||||
// windows does not handle negative time_t, under other plaforms
|
||||
// it may be actually valid value in 1969-12-31 23:59:59
|
||||
// so we check that a filed was updated - does not happen in case of error
|
||||
if(val.tm_wday == -1)
|
||||
#endif
|
||||
{
|
||||
throw date_time_error("boost::locale::gregorian_calendar: invalid time");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
point = internal_timegm(&val);
|
||||
#ifdef BOOST_WINDOWS
|
||||
// Windows uses TLS, thread safe
|
||||
std::tm *revert_point = 0;
|
||||
if(point < 0 || (revert_point = gmtime(&point)) == 0)
|
||||
throw date_time_error("boost::locale::gregorian_calendar time is out of range");
|
||||
val = *revert_point;
|
||||
#else
|
||||
if(!gmtime_r(&point,&val))
|
||||
throw date_time_error("boost::locale::gregorian_calendar invalid time");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
time_ = point - tzoff_;
|
||||
tm_ = val;
|
||||
tm_updated_ = val;
|
||||
normalized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
int get_week_number(int day,int wday) const
|
||||
{
|
||||
///
|
||||
/// This is the number of days that are considered withing
|
||||
/// period such that the week belongs there
|
||||
///
|
||||
static const int days_in_full_week = 4;
|
||||
|
||||
|
||||
// Alaways use local week start
|
||||
int current_dow = (wday - first_day_of_week_ + 7) % 7;
|
||||
// Calculate local week day of Jan 1st.
|
||||
int first_week_day = (current_dow + 700 - day) % 7;
|
||||
// adding something big devidable by 7
|
||||
|
||||
int start_of_period_in_weeks;
|
||||
if(first_week_day < days_in_full_week) {
|
||||
start_of_period_in_weeks = - first_week_day;
|
||||
}
|
||||
else {
|
||||
start_of_period_in_weeks = 7 - first_week_day;
|
||||
}
|
||||
int week_number_in_days = day - start_of_period_in_weeks;
|
||||
if(week_number_in_days < 0)
|
||||
return -1;
|
||||
return week_number_in_days / 7 + 1;
|
||||
}
|
||||
|
||||
///
|
||||
/// Get specific value for period \a p according to a value_type \a v
|
||||
///
|
||||
virtual int get_value(period::marks::period_mark p,value_type v) const
|
||||
{
|
||||
using namespace period::marks;
|
||||
switch(p) {
|
||||
case era:
|
||||
return 1;
|
||||
case year:
|
||||
case extended_year:
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
#ifdef BOOST_WINDOWS
|
||||
return 1970; // Unix epoch windows can't handle negative time_t
|
||||
#else
|
||||
if(sizeof(std::time_t) == 4)
|
||||
return 1901; // minimal year with 32 bit time_t
|
||||
else
|
||||
return 1;
|
||||
#endif
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
if(sizeof(std::time_t) == 4)
|
||||
return 2038; // Y2K38 - maximal with 32 bit time_t
|
||||
else
|
||||
return std::numeric_limits<int>::max();
|
||||
case current:
|
||||
return tm_.tm_year + 1900;
|
||||
};
|
||||
break;
|
||||
case month:
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 0;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 11;
|
||||
case current:
|
||||
return tm_.tm_mon;
|
||||
};
|
||||
break;
|
||||
case day:
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
return 31;
|
||||
case least_maximum:
|
||||
return 28;
|
||||
case actual_maximum:
|
||||
return days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1);
|
||||
case current:
|
||||
return tm_.tm_mday;
|
||||
};
|
||||
break;
|
||||
case day_of_year: ///< The number of day in year, starting from 1
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
return 366;
|
||||
case least_maximum:
|
||||
return 365;
|
||||
case actual_maximum:
|
||||
return is_leap(tm_.tm_year + 1900) ? 366 : 365;
|
||||
case current:
|
||||
return tm_.tm_yday + 1;
|
||||
}
|
||||
break;
|
||||
case day_of_week: ///< Day of week, starting from Sunday, [1..7]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 7;
|
||||
case current:
|
||||
return tm_.tm_wday + 1;
|
||||
}
|
||||
break;
|
||||
case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 7;
|
||||
case current:
|
||||
return (tm_.tm_wday - first_day_of_week_ + 7) % 7 + 1;
|
||||
}
|
||||
break;
|
||||
case hour: ///< 24 clock hour [0..23]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 0;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 23;
|
||||
case current:
|
||||
return tm_.tm_hour;
|
||||
}
|
||||
break;
|
||||
case hour_12: ///< 12 clock hour [0..11]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 0;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 11;
|
||||
case current:
|
||||
return tm_.tm_hour % 12;
|
||||
}
|
||||
break;
|
||||
case am_pm: ///< am or pm marker, [0..1]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 0;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 1;
|
||||
case current:
|
||||
return tm_.tm_hour >= 12 ? 1 : 0;
|
||||
}
|
||||
break;
|
||||
case minute: ///< minute [0..59]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 0;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 59;
|
||||
case current:
|
||||
return tm_.tm_min;
|
||||
}
|
||||
break;
|
||||
case second: ///< second [0..59]
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 0;
|
||||
case absolute_maximum:
|
||||
case least_maximum:
|
||||
case actual_maximum:
|
||||
return 59;
|
||||
case current:
|
||||
return tm_.tm_sec;
|
||||
}
|
||||
break;
|
||||
case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
|
||||
return first_day_of_week_ + 1;
|
||||
|
||||
case week_of_year: ///< The week number in the year
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
return 53;
|
||||
case least_maximum:
|
||||
return 52;
|
||||
case actual_maximum:
|
||||
{
|
||||
int year = tm_.tm_year + 1900;
|
||||
int end_of_year_days = (is_leap(year) ? 366 : 365) - 1;
|
||||
int dow_of_end_of_year = (end_of_year_days - tm_.tm_yday + tm_.tm_wday) % 7;
|
||||
return get_week_number(end_of_year_days,dow_of_end_of_year);
|
||||
}
|
||||
case current:
|
||||
{
|
||||
int val = get_week_number(tm_.tm_yday,tm_.tm_wday);
|
||||
if(val < 0)
|
||||
return 53;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
case week_of_month: ///< The week number withing current month
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
return 5;
|
||||
case least_maximum:
|
||||
return 4;
|
||||
case actual_maximum:
|
||||
{
|
||||
int end_of_month_days = days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1);
|
||||
int dow_of_end_of_month = (end_of_month_days - tm_.tm_mday + tm_.tm_wday) % 7;
|
||||
return get_week_number(end_of_month_days,dow_of_end_of_month);
|
||||
}
|
||||
case current:
|
||||
{
|
||||
int val = get_week_number(tm_.tm_mday,tm_.tm_wday);
|
||||
if(val < 0)
|
||||
return 5;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
case day_of_week_in_month: ///< Original number of the day of the week in month.
|
||||
switch(v) {
|
||||
case absolute_minimum:
|
||||
case greatest_minimum:
|
||||
case actual_minimum:
|
||||
return 1;
|
||||
case absolute_maximum:
|
||||
return 5;
|
||||
case least_maximum:
|
||||
return 4;
|
||||
case actual_maximum:
|
||||
if(tm_.tm_mon == 1 && !is_leap(tm_.tm_year + 1900)) {
|
||||
// only in february in non leap year is 28 days, the rest
|
||||
// conver more then 4 weeks
|
||||
return 4;
|
||||
}
|
||||
return 5;
|
||||
case current:
|
||||
return (tm_.tm_mday - 1) / 7 + 1;
|
||||
default:
|
||||
;
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
///
|
||||
/// Set current time point
|
||||
///
|
||||
virtual void set_time(posix_time const &p)
|
||||
{
|
||||
from_time(static_cast<std::time_t>(p.seconds));
|
||||
}
|
||||
virtual posix_time get_time() const
|
||||
{
|
||||
posix_time pt = { time_, 0};
|
||||
return pt;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set option for calendar, for future use
|
||||
///
|
||||
virtual void set_option(calendar_option_type opt,int /*v*/)
|
||||
{
|
||||
switch(opt) {
|
||||
case is_gregorian:
|
||||
throw date_time_error("is_gregorian is not settable options for calendar");
|
||||
case is_dst:
|
||||
throw date_time_error("is_dst is not settable options for calendar");
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Get option for calendar, currently only check if it is Gregorian calendar
|
||||
///
|
||||
virtual int get_option(calendar_option_type opt) const
|
||||
{
|
||||
switch(opt) {
|
||||
case is_gregorian:
|
||||
return 1;
|
||||
case is_dst:
|
||||
return tm_.tm_isdst == 1;
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// Adjust period's \a p value by \a difference items using a update_type \a u.
|
||||
/// Note: not all values are adjustable
|
||||
///
|
||||
virtual void adjust_value(period::marks::period_mark p,update_type u,int difference)
|
||||
{
|
||||
switch(u) {
|
||||
case move:
|
||||
{
|
||||
using namespace period::marks;
|
||||
switch(p) {
|
||||
case year: ///< Year, it is calendar specific
|
||||
case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
|
||||
tm_updated_.tm_year +=difference;
|
||||
break;
|
||||
case month:
|
||||
tm_updated_.tm_mon +=difference;
|
||||
break;
|
||||
case day:
|
||||
case day_of_year:
|
||||
case day_of_week: ///< Day of week, starting from Sunday, [1..7]
|
||||
case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
|
||||
tm_updated_.tm_mday +=difference;
|
||||
break;
|
||||
case hour: ///< 24 clock hour [0..23]
|
||||
case hour_12: ///< 12 clock hour [0..11]
|
||||
tm_updated_.tm_hour += difference;
|
||||
break;
|
||||
case am_pm: ///< am or pm marker, [0..1]
|
||||
tm_updated_.tm_hour += 12 * difference;
|
||||
break;
|
||||
case minute: ///< minute [0..59]
|
||||
tm_updated_.tm_min += difference;
|
||||
break;
|
||||
case second:
|
||||
tm_updated_.tm_sec += difference;
|
||||
break;
|
||||
case week_of_year: ///< The week number in the year
|
||||
case week_of_month: ///< The week number withing current month
|
||||
case day_of_week_in_month: ///< Original number of the day of the week in month.
|
||||
tm_updated_.tm_mday +=difference * 7;
|
||||
break;
|
||||
default:
|
||||
; // Not all values are adjustable
|
||||
}
|
||||
normalized_ = false;
|
||||
normalize();
|
||||
}
|
||||
break;
|
||||
case roll:
|
||||
{ // roll
|
||||
int cur_min = get_value(p,actual_minimum);
|
||||
int cur_max = get_value(p,actual_maximum);
|
||||
int max_diff = cur_max - cur_min + 1;
|
||||
if(max_diff > 0) {
|
||||
int value = get_value(p,current);
|
||||
int addon = 0;
|
||||
if(difference < 0)
|
||||
addon = ((-difference/max_diff) + 1) * max_diff;
|
||||
value = (value - cur_min + difference + addon) % max_diff + cur_min;
|
||||
set_value(p,value);
|
||||
normalize();
|
||||
}
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
int get_diff(period::marks::period_mark p,int diff,gregorian_calendar const *other) const
|
||||
{
|
||||
if(diff == 0)
|
||||
return 0;
|
||||
std::auto_ptr<gregorian_calendar> self(clone());
|
||||
self->adjust_value(p,move,diff);
|
||||
if(diff > 0){
|
||||
if(self->time_ > other->time_)
|
||||
return diff - 1;
|
||||
else
|
||||
return diff;
|
||||
}
|
||||
else {
|
||||
if(self->time_ < other->time_)
|
||||
return diff + 1;
|
||||
else
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Calculate the difference between this calendar and \a other in \a p units
|
||||
///
|
||||
virtual int difference(abstract_calendar const *other_cal,period::marks::period_mark p) const
|
||||
{
|
||||
std::auto_ptr<gregorian_calendar> keeper;
|
||||
gregorian_calendar const *other = dynamic_cast<gregorian_calendar const *>(other_cal);
|
||||
if(!other) {
|
||||
keeper.reset(clone());
|
||||
keeper->set_time(other_cal->get_time());
|
||||
other = keeper.get();
|
||||
}
|
||||
|
||||
int factor = 1; // for weeks vs days handling
|
||||
|
||||
using namespace period::marks;
|
||||
switch(p) {
|
||||
case era:
|
||||
return 0;
|
||||
case year:
|
||||
case extended_year:
|
||||
{
|
||||
int diff = other->tm_.tm_year - tm_.tm_year;
|
||||
return get_diff(period::marks::year,diff,other);
|
||||
}
|
||||
case month:
|
||||
{
|
||||
int diff = 12 * (other->tm_.tm_year - tm_.tm_year)
|
||||
+ other->tm_.tm_mon - tm_.tm_mon;
|
||||
return get_diff(period::marks::month,diff,other);
|
||||
}
|
||||
case day_of_week_in_month:
|
||||
case week_of_month:
|
||||
case week_of_year:
|
||||
factor = 7;
|
||||
// fall
|
||||
case day:
|
||||
case day_of_year:
|
||||
case day_of_week:
|
||||
case day_of_week_local:
|
||||
{
|
||||
int diff = other->tm_.tm_yday - tm_.tm_yday;
|
||||
if(other->tm_.tm_year != tm_.tm_year) {
|
||||
diff += days_from_0(other->tm_.tm_year + 1900) -
|
||||
days_from_0(tm_.tm_year + 1900);
|
||||
}
|
||||
return get_diff(period::marks::day,diff,other) / factor;
|
||||
}
|
||||
case am_pm:
|
||||
return static_cast<int>( (other->time_ - time_) / (3600*12) );
|
||||
case hour:
|
||||
case hour_12:
|
||||
return static_cast<int>( (other->time_ - time_) / 3600 );
|
||||
case minute:
|
||||
return static_cast<int>( (other->time_ - time_) / 60 );
|
||||
case second:
|
||||
return static_cast<int>( other->time_ - time_ );
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// Set time zone, empty - use system
|
||||
///
|
||||
virtual void set_timezone(std::string const &tz)
|
||||
{
|
||||
if(tz.empty()) {
|
||||
is_local_ = true;
|
||||
tzoff_ = 0;
|
||||
}
|
||||
else {
|
||||
is_local_ = false;
|
||||
tzoff_ = parse_tz(tz);
|
||||
}
|
||||
from_time(time_);
|
||||
time_zone_name_ = tz;
|
||||
}
|
||||
virtual std::string get_timezone() const
|
||||
{
|
||||
return time_zone_name_;
|
||||
}
|
||||
|
||||
virtual bool same(abstract_calendar const *other) const
|
||||
{
|
||||
gregorian_calendar const *gcal = dynamic_cast<gregorian_calendar const *>(other);
|
||||
if(!gcal)
|
||||
return false;
|
||||
return
|
||||
gcal->tzoff_ == tzoff_
|
||||
&& gcal->is_local_ == is_local_
|
||||
&& gcal->first_day_of_week_ == first_day_of_week_;
|
||||
}
|
||||
|
||||
virtual ~gregorian_calendar()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void from_time(std::time_t point)
|
||||
{
|
||||
std::time_t real_point = point + tzoff_;
|
||||
std::tm *t = 0;
|
||||
#ifdef BOOST_WINDOWS
|
||||
// Windows uses TLS, thread safe
|
||||
t = is_local_ ? localtime(&real_point) : gmtime(&real_point);
|
||||
#else
|
||||
std::tm tmp_tm;
|
||||
t = is_local_ ? localtime_r(&real_point,&tmp_tm) : gmtime_r(&real_point,&tmp_tm);
|
||||
#endif
|
||||
if(!t) {
|
||||
throw date_time_error("boost::locale::gregorian_calendar: invalid time point");
|
||||
}
|
||||
tm_ = *t;
|
||||
tm_updated_ = *t;
|
||||
normalized_ = true;
|
||||
time_ = point;
|
||||
}
|
||||
int first_day_of_week_;
|
||||
std::time_t time_;
|
||||
std::tm tm_;
|
||||
std::tm tm_updated_;
|
||||
bool normalized_;
|
||||
bool is_local_;
|
||||
int tzoff_;
|
||||
std::string time_zone_name_;
|
||||
|
||||
};
|
||||
|
||||
abstract_calendar *create_gregorian_calendar(std::string const &terr)
|
||||
{
|
||||
return new gregorian_calendar(terr);
|
||||
}
|
||||
|
||||
class gregorian_facet : public calendar_facet {
|
||||
public:
|
||||
gregorian_facet(std::string const &terr,size_t refs = 0) :
|
||||
calendar_facet(refs),
|
||||
terr_(terr)
|
||||
{
|
||||
}
|
||||
virtual abstract_calendar *create_calendar() const
|
||||
{
|
||||
return create_gregorian_calendar(terr_);
|
||||
}
|
||||
private:
|
||||
std::string terr_;
|
||||
};
|
||||
|
||||
std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr)
|
||||
{
|
||||
return std::locale(in,new gregorian_facet(terr));
|
||||
}
|
||||
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
25
src/boost/libs/locale/src/util/gregorian.hpp
Normal file
25
src/boost/libs/locale/src/util/gregorian.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_SRC_UTIL_GREGORIAN_HPP
|
||||
#define BOOST_LOCALE_SRC_UTIL_GREGORIAN_HPP
|
||||
|
||||
#include <locale>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
|
||||
std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr);
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
37
src/boost/libs/locale/src/util/iconv.hpp
Normal file
37
src/boost/libs/locale/src/util/iconv.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_ICONV_FIXER_HPP
|
||||
#define BOOST_LOCALE_ICONV_FIXER_HPP
|
||||
|
||||
#include <iconv.h>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
extern "C" {
|
||||
typedef size_t (*gnu_iconv_ptr_type)(iconv_t d,char const **in,size_t *insize,char **out,size_t *outsize);
|
||||
typedef size_t (*posix_iconv_ptr_type)(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize);
|
||||
}
|
||||
inline size_t do_iconv(gnu_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
|
||||
{
|
||||
char const **rin = const_cast<char const **>(in);
|
||||
return ptr(d,rin,insize,out,outsize);
|
||||
}
|
||||
inline size_t do_iconv(posix_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
|
||||
{
|
||||
return ptr(d,in,insize,out,outsize);
|
||||
}
|
||||
inline size_t call_iconv(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
|
||||
{
|
||||
return do_iconv( iconv, d, in,insize,out,outsize);
|
||||
}
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
75
src/boost/libs/locale/src/util/info.cpp
Normal file
75
src/boost/libs/locale/src/util/info.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/info.hpp>
|
||||
#include <boost/locale/util.hpp>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "locale_data.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
class simple_info : public info {
|
||||
public:
|
||||
simple_info(std::string const &name,size_t refs = 0) :
|
||||
info(refs),
|
||||
name_(name)
|
||||
{
|
||||
d.parse(name);
|
||||
}
|
||||
virtual std::string get_string_property(string_propery v) const
|
||||
{
|
||||
switch(v) {
|
||||
case language_property:
|
||||
return d.language;
|
||||
case country_property:
|
||||
return d.country;
|
||||
case variant_property:
|
||||
return d.variant;
|
||||
case encoding_property:
|
||||
return d.encoding;
|
||||
case name_property:
|
||||
return name_;
|
||||
default:
|
||||
return "";
|
||||
};
|
||||
}
|
||||
|
||||
virtual int get_integer_property(integer_property v) const
|
||||
{
|
||||
switch(v) {
|
||||
case utf8_property:
|
||||
return d.utf8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
private:
|
||||
locale_data d;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
std::locale create_info(std::locale const &in,std::string const &name)
|
||||
{
|
||||
return std::locale(in,new simple_info(name));
|
||||
}
|
||||
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
113
src/boost/libs/locale/src/util/locale_data.cpp
Normal file
113
src/boost/libs/locale/src/util/locale_data.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include "locale_data.hpp"
|
||||
#include "../encoding/conv.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
void locale_data::parse(std::string const &locale_name)
|
||||
{
|
||||
language = "C";
|
||||
country.clear();
|
||||
variant.clear();
|
||||
encoding = "us-ascii";
|
||||
utf8=false;
|
||||
parse_from_lang(locale_name);
|
||||
}
|
||||
|
||||
void locale_data::parse_from_lang(std::string const &locale_name)
|
||||
{
|
||||
size_t end = locale_name.find_first_of("-_@.");
|
||||
std::string tmp = locale_name.substr(0,end);
|
||||
if(tmp.empty())
|
||||
return;
|
||||
for(unsigned i=0;i<tmp.size();i++) {
|
||||
if('A' <= tmp[i] && tmp[i]<='Z')
|
||||
tmp[i]=tmp[i]-'A'+'a';
|
||||
else if(tmp[i] < 'a' && 'z' < tmp[i])
|
||||
return;
|
||||
}
|
||||
language = tmp;
|
||||
if(end >= locale_name.size())
|
||||
return;
|
||||
|
||||
if(locale_name[end] == '-' || locale_name[end]=='_') {
|
||||
parse_from_country(locale_name.substr(end+1));
|
||||
}
|
||||
else if(locale_name[end] == '.') {
|
||||
parse_from_encoding(locale_name.substr(end+1));
|
||||
}
|
||||
else if(locale_name[end] == '@') {
|
||||
parse_from_variant(locale_name.substr(end+1));
|
||||
}
|
||||
}
|
||||
|
||||
void locale_data::parse_from_country(std::string const &locale_name)
|
||||
{
|
||||
size_t end = locale_name.find_first_of("@.");
|
||||
std::string tmp = locale_name.substr(0,end);
|
||||
if(tmp.empty())
|
||||
return;
|
||||
for(unsigned i=0;i<tmp.size();i++) {
|
||||
if('a' <= tmp[i] && tmp[i]<='a')
|
||||
tmp[i]=tmp[i]-'a'+'A';
|
||||
else if(tmp[i] < 'A' && 'Z' < tmp[i])
|
||||
return;
|
||||
}
|
||||
|
||||
country = tmp;
|
||||
|
||||
if(end >= locale_name.size())
|
||||
return;
|
||||
else if(locale_name[end] == '.') {
|
||||
parse_from_encoding(locale_name.substr(end+1));
|
||||
}
|
||||
else if(locale_name[end] == '@') {
|
||||
parse_from_variant(locale_name.substr(end+1));
|
||||
}
|
||||
}
|
||||
|
||||
void locale_data::parse_from_encoding(std::string const &locale_name)
|
||||
{
|
||||
size_t end = locale_name.find_first_of("@");
|
||||
std::string tmp = locale_name.substr(0,end);
|
||||
if(tmp.empty())
|
||||
return;
|
||||
for(unsigned i=0;i<tmp.size();i++) {
|
||||
if('A' <= tmp[i] && tmp[i]<='Z')
|
||||
tmp[i]=tmp[i]-'A'+'a';
|
||||
}
|
||||
encoding = tmp;
|
||||
|
||||
utf8 = conv::impl::normalize_encoding(encoding.c_str()) == "utf8";
|
||||
|
||||
if(end >= locale_name.size())
|
||||
return;
|
||||
|
||||
if(locale_name[end] == '@') {
|
||||
parse_from_variant(locale_name.substr(end+1));
|
||||
}
|
||||
}
|
||||
|
||||
void locale_data::parse_from_variant(std::string const &locale_name)
|
||||
{
|
||||
variant = locale_name;
|
||||
for(unsigned i=0;i<variant.size();i++) {
|
||||
if('A' <= variant[i] && variant[i]<='Z')
|
||||
variant[i]=variant[i]-'A'+'a';
|
||||
}
|
||||
}
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
47
src/boost/libs/locale/src/util/locale_data.hpp
Normal file
47
src/boost/libs/locale/src/util/locale_data.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_UTIL_LOCALE_DATA_HPP
|
||||
#define BOOST_LOCALE_IMPL_UTIL_LOCALE_DATA_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
|
||||
class locale_data {
|
||||
public:
|
||||
locale_data() :
|
||||
language("C"),
|
||||
encoding("us-ascii"),
|
||||
utf8(false)
|
||||
{
|
||||
}
|
||||
|
||||
std::string language;
|
||||
std::string country;
|
||||
std::string variant;
|
||||
std::string encoding;
|
||||
bool utf8;
|
||||
|
||||
void parse(std::string const &locale_name);
|
||||
|
||||
private:
|
||||
|
||||
void parse_from_lang(std::string const &locale_name);
|
||||
void parse_from_country(std::string const &locale_name);
|
||||
void parse_from_encoding(std::string const &locale_name);
|
||||
void parse_from_variant(std::string const &locale_name);
|
||||
};
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
393
src/boost/libs/locale/src/util/numeric.hpp
Normal file
393
src/boost/libs/locale/src/util/numeric.hpp
Normal file
@@ -0,0 +1,393 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_UTIL_NUMERIC_HPP
|
||||
#define BOOST_LOCALE_IMPL_UTIL_NUMERIC_HPP
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/locale/info.hpp>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "timezone.hpp"
|
||||
|
||||
// This is internal header so disable crappy "unsecure functions" for all
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
|
||||
template<typename CharType>
|
||||
struct formatting_size_traits {
|
||||
static size_t size(std::basic_string<CharType> const &s,std::locale const &/*l*/)
|
||||
{
|
||||
return s.size();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct formatting_size_traits<char> {
|
||||
static size_t size(std::string const &s,std::locale const &l)
|
||||
{
|
||||
if(!std::has_facet<info>(l))
|
||||
return s.size();
|
||||
if(!std::use_facet<info>(l).utf8())
|
||||
return s.size();
|
||||
// count code points, poor man's text size
|
||||
size_t res = 0;
|
||||
for(size_t i=0;i<s.size();i++) {
|
||||
unsigned char c = s[i];
|
||||
if(c <= 127)
|
||||
res ++;
|
||||
else if ((c & 0xC0) == 0xC0) { // first UTF-8 byte
|
||||
res ++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class base_num_format : public std::num_put<CharType>
|
||||
{
|
||||
public:
|
||||
typedef typename std::num_put<CharType>::iter_type iter_type;
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
typedef CharType char_type;
|
||||
|
||||
base_num_format(size_t refs = 0) :
|
||||
std::num_put<CharType>(refs)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long val) const
|
||||
{
|
||||
return do_real_put(out,ios,fill,val);
|
||||
}
|
||||
virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, unsigned long val) const
|
||||
{
|
||||
return do_real_put(out,ios,fill,val);
|
||||
}
|
||||
virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, double val) const
|
||||
{
|
||||
return do_real_put(out,ios,fill,val);
|
||||
}
|
||||
virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long double val) const
|
||||
{
|
||||
return do_real_put(out,ios,fill,val);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_LONG_LONG
|
||||
virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long long val) const
|
||||
{
|
||||
return do_real_put(out,ios,fill,val);
|
||||
}
|
||||
virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, unsigned long long val) const
|
||||
{
|
||||
return do_real_put(out,ios,fill,val);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
template<typename ValueType>
|
||||
iter_type do_real_put (iter_type out, std::ios_base &ios, char_type fill, ValueType val) const
|
||||
{
|
||||
typedef std::num_put<char_type> super;
|
||||
|
||||
ios_info &info=ios_info::get(ios);
|
||||
|
||||
switch(info.display_flags()) {
|
||||
case flags::posix:
|
||||
{
|
||||
typedef std::basic_ostringstream<char_type> sstream_type;
|
||||
sstream_type ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.flags(ios.flags());
|
||||
ss.precision(ios.precision());
|
||||
ss.width(ios.width());
|
||||
iter_type ret_ptr = super::do_put(out,ss,fill,val);
|
||||
ios.width(0);
|
||||
return ret_ptr;
|
||||
}
|
||||
case flags::date:
|
||||
return format_time(out,ios,fill,static_cast<std::time_t>(val),'x');
|
||||
case flags::time:
|
||||
return format_time(out,ios,fill,static_cast<std::time_t>(val),'X');
|
||||
case flags::datetime:
|
||||
return format_time(out,ios,fill,static_cast<std::time_t>(val),'c');
|
||||
case flags::strftime:
|
||||
return format_time(out,ios,fill,static_cast<std::time_t>(val),info.date_time_pattern<char_type>());
|
||||
case flags::currency:
|
||||
{
|
||||
bool nat = info.currency_flags()==flags::currency_default
|
||||
|| info.currency_flags() == flags::currency_national;
|
||||
bool intl = !nat;
|
||||
return do_format_currency(intl,out,ios,fill,static_cast<long double>(val));
|
||||
}
|
||||
|
||||
case flags::number:
|
||||
case flags::percent:
|
||||
case flags::spellout:
|
||||
case flags::ordinal:
|
||||
default:
|
||||
return super::do_put(out,ios,fill,val);
|
||||
}
|
||||
}
|
||||
|
||||
virtual iter_type do_format_currency(bool intl,iter_type out,std::ios_base &ios,char_type fill,long double val) const
|
||||
{
|
||||
if(intl)
|
||||
return format_currency<true>(out,ios,fill,val);
|
||||
else
|
||||
return format_currency<false>(out,ios,fill,val);
|
||||
}
|
||||
|
||||
template<bool intl>
|
||||
iter_type format_currency(iter_type out,std::ios_base &ios,char_type fill,long double val) const
|
||||
{
|
||||
std::locale loc = ios.getloc();
|
||||
int digits = std::use_facet<std::moneypunct<char_type,intl> >(loc).frac_digits();
|
||||
while(digits > 0) {
|
||||
val*=10;
|
||||
digits --;
|
||||
}
|
||||
std::ios_base::fmtflags f=ios.flags();
|
||||
ios.flags(f | std::ios_base::showbase);
|
||||
out = std::use_facet<std::money_put<char_type> >(loc).put(out,intl,ios,fill,val);
|
||||
ios.flags(f);
|
||||
return out;
|
||||
}
|
||||
|
||||
iter_type format_time(iter_type out,std::ios_base &ios,char_type fill,std::time_t time,char c) const
|
||||
{
|
||||
string_type fmt;
|
||||
fmt+=char_type('%');
|
||||
fmt+=char_type(c);
|
||||
return format_time(out,ios,fill,time,fmt);
|
||||
}
|
||||
|
||||
iter_type format_time(iter_type out,std::ios_base &ios,char_type fill,std::time_t time,string_type const &format) const
|
||||
{
|
||||
std::string tz = ios_info::get(ios).time_zone();
|
||||
std::tm tm;
|
||||
#if defined(__linux) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
std::vector<char> tmp_buf(tz.c_str(),tz.c_str()+tz.size()+1);
|
||||
#endif
|
||||
if(tz.empty()) {
|
||||
#ifdef BOOST_WINDOWS
|
||||
/// Windows uses TLS
|
||||
tm = *localtime(&time);
|
||||
#else
|
||||
localtime_r(&time,&tm);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
int gmtoff = parse_tz(tz);
|
||||
time+=gmtoff;
|
||||
#ifdef BOOST_WINDOWS
|
||||
/// Windows uses TLS
|
||||
tm = *gmtime(&time);
|
||||
#else
|
||||
gmtime_r(&time,&tm);
|
||||
#endif
|
||||
|
||||
#if defined(__linux) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
// These have extra fields to specify timezone
|
||||
if(gmtoff!=0) {
|
||||
// bsd and apple want tm_zone be non-const
|
||||
tm.tm_zone=&tmp_buf.front();
|
||||
tm.tm_gmtoff = gmtoff;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
std::basic_ostringstream<char_type> tmp_out;
|
||||
std::use_facet<std::time_put<char_type> >(ios.getloc()).put(tmp_out,tmp_out,fill,&tm,format.c_str(),format.c_str()+format.size());
|
||||
string_type str = tmp_out.str();
|
||||
std::streamsize on_left=0,on_right = 0;
|
||||
std::streamsize points =
|
||||
formatting_size_traits<char_type>::size(str,ios.getloc());
|
||||
if(points < ios.width()) {
|
||||
std::streamsize n = ios.width() - points;
|
||||
|
||||
std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield;
|
||||
|
||||
//
|
||||
// we do not really know internal point, so we assume that it does not
|
||||
// exist. so according to the standard field should be right aligned
|
||||
//
|
||||
if(flags != std::ios_base::left)
|
||||
on_left = n;
|
||||
on_right = n - on_left;
|
||||
}
|
||||
while(on_left > 0) {
|
||||
*out++ = fill;
|
||||
on_left--;
|
||||
}
|
||||
std::copy(str.begin(),str.end(),out);
|
||||
while(on_right > 0) {
|
||||
*out++ = fill;
|
||||
on_right--;
|
||||
}
|
||||
ios.width(0);
|
||||
return out;
|
||||
}
|
||||
|
||||
}; /// num_format
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class base_num_parse : public std::num_get<CharType>
|
||||
{
|
||||
public:
|
||||
base_num_parse(size_t refs = 0) :
|
||||
std::num_get<CharType>(refs)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
typedef typename std::num_get<CharType>::iter_type iter_type;
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
typedef CharType char_type;
|
||||
|
||||
virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned short &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned int &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,float &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,double &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long double &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_LONG_LONG
|
||||
virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long long &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long long &val) const
|
||||
{
|
||||
return do_real_get(in,end,ios,err,val);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
template<typename ValueType>
|
||||
iter_type do_real_get(iter_type in,iter_type end,std::ios_base &ios,std::ios_base::iostate &err,ValueType &val) const
|
||||
{
|
||||
typedef std::num_get<char_type> super;
|
||||
|
||||
ios_info &info=ios_info::get(ios);
|
||||
|
||||
switch(info.display_flags()) {
|
||||
case flags::posix:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.flags(ios.flags());
|
||||
ss.precision(ios.precision());
|
||||
return super::do_get(in,end,ss,err,val);
|
||||
}
|
||||
case flags::currency:
|
||||
{
|
||||
long double ret_val = 0;
|
||||
if(info.currency_flags()==flags::currency_default || info.currency_flags() == flags::currency_national)
|
||||
in = parse_currency<false>(in,end,ios,err,ret_val);
|
||||
else
|
||||
in = parse_currency<true>(in,end,ios,err,ret_val);
|
||||
if(!(err & std::ios_base::failbit))
|
||||
val = static_cast<ValueType>(ret_val);
|
||||
return in;
|
||||
}
|
||||
|
||||
// date-time parsing is not supported
|
||||
// due to buggy standard
|
||||
case flags::date:
|
||||
case flags::time:
|
||||
case flags::datetime:
|
||||
case flags::strftime:
|
||||
|
||||
case flags::number:
|
||||
case flags::percent:
|
||||
case flags::spellout:
|
||||
case flags::ordinal:
|
||||
default:
|
||||
return super::do_get(in,end,ios,err,val);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool intl>
|
||||
iter_type parse_currency(iter_type in,iter_type end,std::ios_base &ios,std::ios_base::iostate &err,long double &val) const
|
||||
{
|
||||
std::locale loc = ios.getloc();
|
||||
int digits = std::use_facet<std::moneypunct<char_type,intl> >(loc).frac_digits();
|
||||
long double rval;
|
||||
in = std::use_facet<std::money_get<char_type> >(loc).get(in,end,intl,ios,err,rval);
|
||||
if(!(err & std::ios::failbit)) {
|
||||
while(digits > 0) {
|
||||
rval/=10;
|
||||
digits --;
|
||||
}
|
||||
val = rval;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
53
src/boost/libs/locale/src/util/timezone.hpp
Normal file
53
src/boost/libs/locale/src/util/timezone.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_UTIL_TIMEZONE_HPP
|
||||
#define BOOST_LOCALE_IMPL_UTIL_TIMEZONE_HPP
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace util {
|
||||
inline int parse_tz(std::string const &tz)
|
||||
{
|
||||
int gmtoff = 0;
|
||||
std::string ltz;
|
||||
for(unsigned i=0;i<tz.size();i++) {
|
||||
if('a' <= tz[i] && tz[i] <= 'z')
|
||||
ltz += tz[i]-'a' + 'A';
|
||||
else if(tz[i]==' ')
|
||||
;
|
||||
else
|
||||
ltz+=tz[i];
|
||||
}
|
||||
if(ltz.compare(0,3,"GMT")!=0 && ltz.compare(0,3,"UTC")!=0)
|
||||
return 0;
|
||||
if(ltz.size()<=3)
|
||||
return 0;
|
||||
char const *begin = ltz.c_str()+3;
|
||||
char *end=0;
|
||||
int hours = strtol(begin,&end,10);
|
||||
if(end != begin) {
|
||||
gmtoff+=hours * 3600;
|
||||
}
|
||||
if(*end==':') {
|
||||
begin=end+1;
|
||||
int minutes = strtol(begin,&end,10);
|
||||
if(end!=begin)
|
||||
gmtoff+=minutes * 60;
|
||||
}
|
||||
return gmtoff;
|
||||
}
|
||||
|
||||
} // util
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
45
src/boost/libs/locale/src/win32/all_generator.hpp
Normal file
45
src/boost/libs/locale/src/win32/all_generator.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_WIN32_ALL_GENERATOR_HPP
|
||||
#define BOOST_LOCALE_IMPL_WIN32_ALL_GENERATOR_HPP
|
||||
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <vector>
|
||||
#include <locale.h>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
class winlocale;
|
||||
|
||||
std::locale create_convert( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_collate( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_formatting( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_parsing( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type);
|
||||
|
||||
std::locale create_codecvt( std::locale const &in,
|
||||
character_facet_type type);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
357
src/boost/libs/locale/src/win32/api.hpp
Normal file
357
src/boost/libs/locale/src/win32/api.hpp
Normal file
@@ -0,0 +1,357 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_WIN32_API_HPP
|
||||
#define BOOST_LOCALE_IMPL_WIN32_API_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <ctime>
|
||||
|
||||
#include "lcid.hpp"
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/collator.hpp>
|
||||
|
||||
#define BOOST_LOCALE_WINDOWS_2000_API
|
||||
|
||||
#if defined(_WIN32_NT) && _WIN32_NT >= 0x600 && !defined(BOOST_LOCALE_WINDOWS_2000_API)
|
||||
#define BOOST_LOCALE_WINDOWS_VISTA_API
|
||||
#else
|
||||
#define BOOST_LOCALE_WINDOWS_2000_API
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
struct numeric_info {
|
||||
std::wstring thousands_sep;
|
||||
std::wstring decimal_point;
|
||||
std::string grouping;
|
||||
};
|
||||
|
||||
inline DWORD collation_level_to_flag(collator_base::level_type level)
|
||||
{
|
||||
DWORD flags;
|
||||
switch(level) {
|
||||
case collator_base::primary:
|
||||
flags = NORM_IGNORESYMBOLS | NORM_IGNORECASE | NORM_IGNORENONSPACE;
|
||||
break;
|
||||
case collator_base::secondary:
|
||||
flags = NORM_IGNORESYMBOLS | NORM_IGNORECASE;
|
||||
break;
|
||||
case collator_base::tertiary:
|
||||
flags = NORM_IGNORESYMBOLS;
|
||||
break;
|
||||
default:
|
||||
flags = 0;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BOOST_LOCALE_WINDOWS_2000_API
|
||||
|
||||
class winlocale{
|
||||
public:
|
||||
winlocale() :
|
||||
lcid(0)
|
||||
{
|
||||
}
|
||||
|
||||
winlocale(std::string const &name)
|
||||
{
|
||||
lcid = locale_to_lcid(name);
|
||||
}
|
||||
|
||||
unsigned lcid;
|
||||
|
||||
bool is_c() const
|
||||
{
|
||||
return lcid == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Number Format
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline numeric_info wcsnumformat_l(winlocale const &l)
|
||||
{
|
||||
numeric_info res;
|
||||
res.decimal_point = L'.';
|
||||
unsigned lcid = l.lcid;
|
||||
|
||||
if(lcid == 0)
|
||||
return res;
|
||||
|
||||
// limits according to MSDN
|
||||
static const int th_size = 4;
|
||||
static const int de_size = 4;
|
||||
static const int gr_size = 10;
|
||||
|
||||
wchar_t th[th_size]={0};
|
||||
wchar_t de[de_size]={0};
|
||||
wchar_t gr[gr_size]={0};
|
||||
|
||||
if( GetLocaleInfoW(lcid,LOCALE_STHOUSAND,th,th_size)==0
|
||||
|| GetLocaleInfoW(lcid,LOCALE_SDECIMAL ,de,de_size)==0
|
||||
|| GetLocaleInfoW(lcid,LOCALE_SGROUPING,gr,gr_size)==0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
res.decimal_point = de;
|
||||
res.thousands_sep = th;
|
||||
bool inf_group = false;
|
||||
for(unsigned i=0;gr[i];i++) {
|
||||
if(gr[i]==L';')
|
||||
continue;
|
||||
if(L'1'<= gr[i] && gr[i]<=L'9') {
|
||||
res.grouping += char(gr[i]-L'0');
|
||||
}
|
||||
else if(gr[i]==L'0')
|
||||
inf_group = true;
|
||||
}
|
||||
if(!inf_group) {
|
||||
if(std::numeric_limits<char>::is_signed) {
|
||||
res.grouping+=std::numeric_limits<char>::min();
|
||||
}
|
||||
else {
|
||||
res.grouping+=std::numeric_limits<char>::max();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline std::wstring win_map_string_l(unsigned flags,wchar_t const *begin,wchar_t const *end,winlocale const &l)
|
||||
{
|
||||
std::wstring res;
|
||||
int len = LCMapStringW(l.lcid,flags,begin,end-begin,0,0);
|
||||
if(len == 0)
|
||||
return res;
|
||||
std::vector<wchar_t> buf(len+1);
|
||||
int l2 = LCMapStringW(l.lcid,flags,begin,end-begin,&buf.front(),buf.size());
|
||||
res.assign(&buf.front(),l2);
|
||||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Collation
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
inline int wcscoll_l( collator_base::level_type level,
|
||||
wchar_t const *lb,wchar_t const *le,
|
||||
wchar_t const *rb,wchar_t const *re,
|
||||
winlocale const &l)
|
||||
{
|
||||
return CompareStringW(l.lcid,collation_level_to_flag(level),lb,le-lb,rb,re-rb) - 2;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Money Format
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::wstring wcsfmon_l(double value,winlocale const &l)
|
||||
{
|
||||
std::wostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
|
||||
ss << std::setprecision(std::numeric_limits<double>::digits10+1) << value;
|
||||
std::wstring sval = ss.str();
|
||||
int len = GetCurrencyFormatW(l.lcid,0,sval.c_str(),0,0,0);
|
||||
std::vector<wchar_t> buf(len+1);
|
||||
GetCurrencyFormatW(l.lcid,0,sval.c_str(),0,&buf.front(),len);
|
||||
return &buf.front();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Time Format
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
inline std::wstring wcs_format_date_l(wchar_t const *format,SYSTEMTIME const *tm,winlocale const &l)
|
||||
{
|
||||
int len = GetDateFormatW(l.lcid,0,tm,format,0,0);
|
||||
std::vector<wchar_t> buf(len+1);
|
||||
GetDateFormatW(l.lcid,0,tm,format,&buf.front(),len);
|
||||
return &buf.front();
|
||||
}
|
||||
|
||||
inline std::wstring wcs_format_time_l(wchar_t const *format,SYSTEMTIME const *tm,winlocale const &l)
|
||||
{
|
||||
int len = GetTimeFormatW(l.lcid,0,tm,format,0,0);
|
||||
std::vector<wchar_t> buf(len+1);
|
||||
GetTimeFormatW(l.lcid,0,tm,format,&buf.front(),len);
|
||||
return &buf.front();
|
||||
}
|
||||
|
||||
inline std::wstring wcsfold(wchar_t const *begin,wchar_t const *end)
|
||||
{
|
||||
winlocale l;
|
||||
l.lcid = 0x0409; // en-US
|
||||
return win_map_string_l(LCMAP_LOWERCASE,begin,end,l);
|
||||
}
|
||||
|
||||
inline std::wstring wcsnormalize(norm_type norm,wchar_t const *begin,wchar_t const *end)
|
||||
{
|
||||
// We use FoldString, under Vista it actually does normalization;
|
||||
// under XP and below it does something similar, half job, better then nothing
|
||||
unsigned flags = 0;
|
||||
switch(norm) {
|
||||
case norm_nfd:
|
||||
flags = MAP_COMPOSITE;
|
||||
break;
|
||||
case norm_nfc:
|
||||
flags = MAP_PRECOMPOSED;
|
||||
break;
|
||||
case norm_nfkd:
|
||||
flags = MAP_FOLDCZONE;
|
||||
break;
|
||||
case norm_nfkc:
|
||||
flags = MAP_FOLDCZONE | MAP_COMPOSITE;
|
||||
break;
|
||||
default:
|
||||
flags = MAP_PRECOMPOSED;
|
||||
}
|
||||
|
||||
int len = FoldStringW(flags,begin,end-begin,0,0);
|
||||
if(len == 0)
|
||||
return std::wstring();
|
||||
std::vector<wchar_t> v(len+1);
|
||||
len = FoldStringW(flags,begin,end-begin,&v.front(),len+1);
|
||||
return std::wstring(&v.front(),len);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
inline std::wstring wcsxfrm_l(collator_base::level_type level,wchar_t const *begin,wchar_t const *end,winlocale const &l)
|
||||
{
|
||||
int flag = LCMAP_SORTKEY | collation_level_to_flag(level);
|
||||
|
||||
return win_map_string_l(flag,begin,end,l);
|
||||
}
|
||||
|
||||
inline std::wstring towupper_l(wchar_t const *begin,wchar_t const *end,winlocale const &l)
|
||||
{
|
||||
return win_map_string_l(LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING,begin,end,l);
|
||||
}
|
||||
|
||||
inline std::wstring towlower_l(wchar_t const *begin,wchar_t const *end,winlocale const &l)
|
||||
{
|
||||
return win_map_string_l(LCMAP_LOWERCASE | LCMAP_LINGUISTIC_CASING,begin,end,l);
|
||||
}
|
||||
|
||||
inline std::wstring wcsftime_l(char c,std::tm const *tm,winlocale const &l)
|
||||
{
|
||||
SYSTEMTIME wtm=SYSTEMTIME();
|
||||
wtm.wYear = tm->tm_year + 1900;
|
||||
wtm.wMonth = tm->tm_mon+1;
|
||||
wtm.wDayOfWeek = tm->tm_wday;
|
||||
wtm.wDay = tm->tm_mday;
|
||||
wtm.wHour = tm->tm_hour;
|
||||
wtm.wMinute = tm->tm_min;
|
||||
wtm.wSecond = tm->tm_sec;
|
||||
switch(c) {
|
||||
case 'a': // Abbr Weekday
|
||||
return wcs_format_date_l(L"ddd",&wtm,l);
|
||||
case 'A': // Full Weekday
|
||||
return wcs_format_date_l(L"dddd",&wtm,l);
|
||||
case 'b': // Abbr Month
|
||||
return wcs_format_date_l(L"MMM",&wtm,l);
|
||||
case 'B': // Full Month
|
||||
return wcs_format_date_l(L"MMMM",&wtm,l);
|
||||
case 'c': // DateTile Full
|
||||
return wcs_format_date_l(0,&wtm,l) + L" " + wcs_format_time_l(0,&wtm,l);
|
||||
// not supported by WIN ;(
|
||||
// case 'C': // Century -> 1980 -> 19
|
||||
// retur
|
||||
case 'd': // Day of Month [01,31]
|
||||
return wcs_format_date_l(L"dd",&wtm,l);
|
||||
case 'D': // %m/%d/%y
|
||||
return wcs_format_date_l(L"MM/dd/yy",&wtm,l);
|
||||
case 'e': // Day of Month [1,31]
|
||||
return wcs_format_date_l(L"d",&wtm,l);
|
||||
case 'h': // == b
|
||||
return wcs_format_date_l(L"MMM",&wtm,l);
|
||||
case 'H': // 24 clock hour 00,23
|
||||
return wcs_format_time_l(L"HH",&wtm,l);
|
||||
case 'I': // 12 clock hour 01,12
|
||||
return wcs_format_time_l(L"hh",&wtm,l);
|
||||
/*
|
||||
case 'j': // day of year 001,366
|
||||
return "D";*/
|
||||
case 'm': // month as [01,12]
|
||||
return wcs_format_date_l(L"MM",&wtm,l);
|
||||
case 'M': // minute [00,59]
|
||||
return wcs_format_time_l(L"mm",&wtm,l);
|
||||
case 'n': // \n
|
||||
return L"\n";
|
||||
case 'p': // am-pm
|
||||
return wcs_format_time_l(L"tt",&wtm,l);
|
||||
case 'r': // time with AM/PM %I:%M:%S %p
|
||||
return wcs_format_time_l(L"hh:mm:ss tt",&wtm,l);
|
||||
case 'R': // %H:%M
|
||||
return wcs_format_time_l(L"HH:mm",&wtm,l);
|
||||
case 'S': // second [00,61]
|
||||
return wcs_format_time_l(L"ss",&wtm,l);
|
||||
case 't': // \t
|
||||
return L"\t";
|
||||
case 'T': // %H:%M:%S
|
||||
return wcs_format_time_l(L"HH:mm:ss",&wtm,l);
|
||||
/* case 'u': // weekday 1,7 1=Monday
|
||||
case 'U': // week number of year [00,53] Sunday first
|
||||
case 'V': // week number of year [01,53] Moday first
|
||||
case 'w': // weekday 0,7 0=Sunday
|
||||
case 'W': // week number of year [00,53] Moday first, */
|
||||
case 'x': // Date
|
||||
return wcs_format_date_l(0,&wtm,l);
|
||||
case 'X': // Time
|
||||
return wcs_format_time_l(0,&wtm,l);
|
||||
case 'y': // Year [00-99]
|
||||
return wcs_format_date_l(L"yy",&wtm,l);
|
||||
case 'Y': // Year 1998
|
||||
return wcs_format_date_l(L"yyyy",&wtm,l);
|
||||
case '%': // %
|
||||
return L"%";
|
||||
default:
|
||||
return L"";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // win
|
||||
} // locale
|
||||
} // boost
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
127
src/boost/libs/locale/src/win32/collate.cpp
Normal file
127
src/boost/libs/locale/src/win32/collate.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include "api.hpp"
|
||||
#include "../shared/mo_hash.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
class utf8_collator : public collator<char> {
|
||||
public:
|
||||
utf8_collator(winlocale lc,size_t refs = 0) :
|
||||
collator<char>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual int do_compare(collator_base::level_type level,char const *lb,char const *le,char const *rb,char const *re) const
|
||||
{
|
||||
std::wstring l=conv::to_utf<wchar_t>(lb,le,"UTF-8");
|
||||
std::wstring r=conv::to_utf<wchar_t>(rb,re,"UTF-8");
|
||||
return wcscoll_l(level,l.c_str(),l.c_str()+l.size(),r.c_str(),r.c_str()+r.size(),lc_);
|
||||
}
|
||||
virtual long do_hash(collator_base::level_type level,char const *b,char const *e) const
|
||||
{
|
||||
std::string key = do_transform(level,b,e);
|
||||
return gnu_gettext::pj_winberger_hash_function(key.c_str(),key.c_str() + key.size());
|
||||
}
|
||||
virtual std::string do_transform(collator_base::level_type level,char const *b,char const *e) const
|
||||
{
|
||||
std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
|
||||
std::wstring wkey = wcsxfrm_l(level,tmp.c_str(),tmp.c_str()+tmp.size(),lc_);
|
||||
std::string key;
|
||||
if(sizeof(wchar_t)==2)
|
||||
key.reserve(wkey.size()*2);
|
||||
else
|
||||
key.reserve(wkey.size()*3);
|
||||
for(unsigned i=0;i<wkey.size();i++) {
|
||||
if(sizeof(wchar_t)==2) {
|
||||
uint16_t tv = static_cast<uint16_t>(wkey[i]);
|
||||
key += char(tv >> 8);
|
||||
key += char(tv & 0xFF);
|
||||
}
|
||||
else { // 4
|
||||
uint32_t tv = static_cast<uint32_t>(wkey[i]);
|
||||
// 21 bit
|
||||
key += char((tv >> 16) & 0xFF);
|
||||
key += char((tv >> 8) & 0xFF);
|
||||
key += char(tv & 0xFF);
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
private:
|
||||
winlocale lc_;
|
||||
};
|
||||
|
||||
|
||||
class utf16_collator : public collator<wchar_t> {
|
||||
public:
|
||||
typedef std::collate<wchar_t> wfacet;
|
||||
utf16_collator(winlocale lc,size_t refs = 0) :
|
||||
collator<wchar_t>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual int do_compare(collator_base::level_type level,wchar_t const *lb,wchar_t const *le,wchar_t const *rb,wchar_t const *re) const
|
||||
{
|
||||
return wcscoll_l(level,lb,le,rb,re,lc_);
|
||||
}
|
||||
virtual long do_hash(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const
|
||||
{
|
||||
std::wstring key = do_transform(level,b,e);
|
||||
char const *begin = reinterpret_cast<char const *>(key.c_str());
|
||||
char const *end = begin + key.size()*sizeof(wchar_t);
|
||||
return gnu_gettext::pj_winberger_hash_function(begin,end);
|
||||
}
|
||||
virtual std::wstring do_transform(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const
|
||||
{
|
||||
return wcsxfrm_l(level,b,e,lc_);
|
||||
}
|
||||
private:
|
||||
winlocale lc_;
|
||||
};
|
||||
|
||||
|
||||
std::locale create_collate( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
if(lc.is_c()) {
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(in,new std::collate_byname<char>("C"));
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new std::collate_byname<wchar_t>("C"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(in,new utf8_collator(lc));
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new utf16_collator(lc));
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
106
src/boost/libs/locale/src/win32/converter.cpp
Normal file
106
src/boost/libs/locale/src/win32/converter.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include "api.hpp"
|
||||
#include "all_generator.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
class utf16_converter : public converter<wchar_t>
|
||||
{
|
||||
public:
|
||||
utf16_converter(winlocale const &lc,size_t refs = 0) :
|
||||
converter<wchar_t>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual std::wstring convert(converter_base::conversion_type how,wchar_t const *begin,wchar_t const *end,int flags = 0) const
|
||||
{
|
||||
switch(how) {
|
||||
case converter_base::upper_case:
|
||||
return towupper_l(begin,end,lc_);
|
||||
case converter_base::lower_case:
|
||||
return towlower_l(begin,end,lc_);
|
||||
case converter_base::case_folding:
|
||||
return wcsfold(begin,end);
|
||||
case converter_base::normalization:
|
||||
return wcsnormalize(static_cast<norm_type>(flags),begin,end);
|
||||
default:
|
||||
return std::wstring(begin,end-begin);
|
||||
}
|
||||
}
|
||||
private:
|
||||
winlocale lc_;
|
||||
};
|
||||
|
||||
class utf8_converter : public converter<char> {
|
||||
public:
|
||||
utf8_converter(winlocale const &lc,size_t refs = 0) :
|
||||
converter<char>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int flags = 0) const
|
||||
{
|
||||
std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
|
||||
wchar_t const *wb=tmp.c_str();
|
||||
wchar_t const *we=wb+tmp.size();
|
||||
|
||||
std::wstring res;
|
||||
|
||||
switch(how) {
|
||||
case upper_case:
|
||||
res = towupper_l(wb,we,lc_);
|
||||
break;
|
||||
case lower_case:
|
||||
res = towlower_l(wb,we,lc_);
|
||||
break;
|
||||
case case_folding:
|
||||
res = wcsfold(wb,we);
|
||||
break;
|
||||
case normalization:
|
||||
res = wcsnormalize(static_cast<norm_type>(flags),wb,we);
|
||||
break;
|
||||
default:
|
||||
res = tmp; // make gcc happy
|
||||
}
|
||||
return conv::from_utf(res,"UTF-8");
|
||||
}
|
||||
private:
|
||||
winlocale lc_;
|
||||
};
|
||||
|
||||
std::locale create_convert( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(in,new utf8_converter(lc));
|
||||
case wchar_t_facet:
|
||||
return std::locale(in,new utf16_converter(lc));
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace impl_win32
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
127
src/boost/libs/locale/src/win32/lcid.cpp
Normal file
127
src/boost/libs/locale/src/win32/lcid.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include "lcid.hpp"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include "../util/locale_data.hpp"
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
typedef std::map<std::string,unsigned> table_type;
|
||||
|
||||
static table_type * volatile table = 0;
|
||||
|
||||
boost::mutex &lcid_table_mutex()
|
||||
{
|
||||
static boost::mutex m;
|
||||
return m;
|
||||
}
|
||||
|
||||
table_type &real_lcid_table()
|
||||
{
|
||||
static table_type table;
|
||||
return table;
|
||||
}
|
||||
|
||||
BOOL CALLBACK proc(char *s)
|
||||
{
|
||||
table_type &tbl = real_lcid_table();
|
||||
try {
|
||||
std::istringstream ss;
|
||||
ss.str(s);
|
||||
ss >> std::hex;
|
||||
|
||||
unsigned lcid ;
|
||||
ss >>lcid;
|
||||
if(ss.fail() || !ss.eof()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char iso_639_lang[16];
|
||||
char iso_3166_country[16];
|
||||
if(GetLocaleInfoA(lcid,LOCALE_SISO639LANGNAME,iso_639_lang,sizeof(iso_639_lang))==0)
|
||||
return FALSE;
|
||||
std::string lc_name = iso_639_lang;
|
||||
if(GetLocaleInfoA(lcid,LOCALE_SISO3166CTRYNAME,iso_3166_country,sizeof(iso_3166_country))!=0) {
|
||||
lc_name += "_";
|
||||
lc_name += iso_3166_country;
|
||||
}
|
||||
table_type::iterator p = tbl.find(lc_name);
|
||||
if(p!=tbl.end()) {
|
||||
if(p->second > lcid)
|
||||
p->second = lcid;
|
||||
}
|
||||
else {
|
||||
tbl[lc_name]=lcid;
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
tbl.clear();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
table_type const &get_ready_lcid_table()
|
||||
{
|
||||
if(table)
|
||||
return *table;
|
||||
else {
|
||||
boost::unique_lock<boost::mutex> lock(lcid_table_mutex());
|
||||
if(table)
|
||||
return *table;
|
||||
EnumSystemLocalesA(proc,LCID_INSTALLED);
|
||||
table = &real_lcid_table();
|
||||
return *table;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned locale_to_lcid(std::string const &locale_name)
|
||||
{
|
||||
if(locale_name.empty()) {
|
||||
return LOCALE_USER_DEFAULT;
|
||||
}
|
||||
boost::locale::util::locale_data d;
|
||||
d.parse(locale_name);
|
||||
std::string id = d.language;
|
||||
|
||||
if(!d.country.empty()) {
|
||||
id+="_"+d.country;
|
||||
}
|
||||
if(!d.variant.empty()) {
|
||||
id+="@" + d.variant;
|
||||
}
|
||||
|
||||
table_type const &tbl = get_ready_lcid_table();
|
||||
table_type::const_iterator p = tbl.find(id);
|
||||
|
||||
unsigned lcid = 0;
|
||||
if(p!=tbl.end())
|
||||
lcid = p->second;
|
||||
return lcid;
|
||||
}
|
||||
|
||||
|
||||
} // impl_win
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
25
src/boost/libs/locale/src/win32/lcid.hpp
Normal file
25
src/boost/libs/locale/src/win32/lcid.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_WIN32_LCID_HPP
|
||||
#define BOOST_LOCALE_IMPL_WIN32_LCID_HPP
|
||||
|
||||
#include <string>
|
||||
#include <boost/locale/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
BOOST_LOCALE_DECL unsigned locale_to_lcid(std::string const &locale_name);
|
||||
|
||||
} // impl_win
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
245
src/boost/libs/locale/src/win32/numeric.cpp
Normal file
245
src/boost/libs/locale/src/win32/numeric.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <wctype.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "all_generator.hpp"
|
||||
#include "api.hpp"
|
||||
#include "../util/numeric.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
namespace {
|
||||
|
||||
std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,std::wstring const &s)
|
||||
{
|
||||
for(size_t i=0;i<s.size();i++)
|
||||
*out++ = s[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,std::wstring const &s)
|
||||
{
|
||||
std::string tmp = conv::from_utf(s,"UTF-8");
|
||||
for(size_t i=0;i<tmp.size();i++)
|
||||
*out++ = tmp[i];
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class num_format : public util::base_num_format<CharType>
|
||||
{
|
||||
public:
|
||||
typedef typename std::num_put<CharType>::iter_type iter_type;
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
typedef CharType char_type;
|
||||
|
||||
num_format(winlocale const &lc,size_t refs = 0) :
|
||||
util::base_num_format<CharType>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
private:
|
||||
|
||||
virtual
|
||||
iter_type do_format_currency(bool /*intl*/,iter_type out,std::ios_base &ios,char_type fill,long double val) const
|
||||
{
|
||||
if(lc_.is_c()) {
|
||||
std::locale loc = ios.getloc();
|
||||
int digits = std::use_facet<std::moneypunct<char_type> >(loc).frac_digits();
|
||||
while(digits > 0) {
|
||||
val*=10;
|
||||
digits --;
|
||||
}
|
||||
std::ios_base::fmtflags f=ios.flags();
|
||||
ios.flags(f | std::ios_base::showbase);
|
||||
out = std::use_facet<std::money_put<char_type> >(loc).put(out,false,ios,fill,val);
|
||||
ios.flags(f);
|
||||
return out;
|
||||
}
|
||||
else {
|
||||
std::wstring cur = wcsfmon_l(val,lc_);
|
||||
return write_it(out,cur);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
winlocale lc_;
|
||||
|
||||
}; /// num_format
|
||||
|
||||
template<typename CharType>
|
||||
class time_put_win : public std::time_put<CharType> {
|
||||
public:
|
||||
time_put_win(winlocale const &lc, size_t refs = 0) :
|
||||
std::time_put<CharType>(refs),
|
||||
lc_(lc)
|
||||
{
|
||||
}
|
||||
virtual ~time_put_win()
|
||||
{
|
||||
}
|
||||
typedef typename std::time_put<CharType>::iter_type iter_type;
|
||||
typedef CharType char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
virtual iter_type do_put( iter_type out,
|
||||
std::ios_base &/*ios*/,
|
||||
CharType /*fill*/,
|
||||
std::tm const *tm,
|
||||
char format,
|
||||
char /*modifier*/) const
|
||||
{
|
||||
return write_it(out,wcsftime_l(format,tm,lc_));
|
||||
}
|
||||
|
||||
private:
|
||||
winlocale lc_;
|
||||
};
|
||||
|
||||
|
||||
template<typename CharType>
|
||||
class num_punct_win : public std::numpunct<CharType> {
|
||||
public:
|
||||
typedef std::basic_string<CharType> string_type;
|
||||
num_punct_win(winlocale const &lc,size_t refs = 0) :
|
||||
std::numpunct<CharType>(refs)
|
||||
{
|
||||
numeric_info np = wcsnumformat_l(lc) ;
|
||||
if(sizeof(CharType) == 1 && np.thousands_sep == L"\xA0")
|
||||
np.thousands_sep=L" ";
|
||||
|
||||
to_str(np.thousands_sep,thousands_sep_);
|
||||
to_str(np.decimal_point,decimal_point_);
|
||||
grouping_ = np.grouping;
|
||||
if(thousands_sep_.size() > 1)
|
||||
grouping_ = std::string();
|
||||
if(decimal_point_.size() > 1)
|
||||
decimal_point_ = CharType('.');
|
||||
}
|
||||
|
||||
void to_str(std::wstring &s1,std::wstring &s2)
|
||||
{
|
||||
s2.swap(s1);
|
||||
}
|
||||
|
||||
void to_str(std::wstring &s1,std::string &s2)
|
||||
{
|
||||
s2=conv::from_utf(s1,"UTF-8");
|
||||
}
|
||||
virtual CharType do_decimal_point() const
|
||||
{
|
||||
return *decimal_point_.c_str();
|
||||
}
|
||||
virtual CharType do_thousands_sep() const
|
||||
{
|
||||
return *thousands_sep_.c_str();
|
||||
}
|
||||
virtual std::string do_grouping() const
|
||||
{
|
||||
return grouping_;
|
||||
}
|
||||
virtual string_type do_truename() const
|
||||
{
|
||||
static const char t[]="true";
|
||||
return string_type(t,t+sizeof(t)-1);
|
||||
}
|
||||
virtual string_type do_falsename() const
|
||||
{
|
||||
static const char t[]="false";
|
||||
return string_type(t,t+sizeof(t)-1);
|
||||
}
|
||||
private:
|
||||
string_type decimal_point_;
|
||||
string_type thousands_sep_;
|
||||
std::string grouping_;
|
||||
};
|
||||
|
||||
template<typename CharType>
|
||||
std::locale create_formatting_impl(std::locale const &in,winlocale const &lc)
|
||||
{
|
||||
if(lc.is_c()) {
|
||||
std::locale tmp(in,new std::numpunct_byname<CharType>("C"));
|
||||
tmp=std::locale(tmp,new std::time_put_byname<CharType>("C"));
|
||||
tmp = std::locale(tmp,new num_format<CharType>(lc));
|
||||
return tmp;
|
||||
}
|
||||
else {
|
||||
std::locale tmp(in,new num_punct_win<CharType>(lc));
|
||||
tmp = std::locale(tmp,new time_put_win<CharType>(lc));
|
||||
tmp = std::locale(tmp,new num_format<CharType>(lc));
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CharType>
|
||||
std::locale create_parsing_impl(std::locale const &in,winlocale const &lc)
|
||||
{
|
||||
std::numpunct<CharType> *np = 0;
|
||||
if(lc.is_c())
|
||||
np = new std::numpunct_byname<CharType>("C");
|
||||
else
|
||||
np = new num_punct_win<CharType>(lc);
|
||||
std::locale tmp(in,np);
|
||||
tmp = std::locale(tmp,new util::base_num_parse<CharType>());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
std::locale create_formatting( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return create_formatting_impl<char>(in,lc);
|
||||
case wchar_t_facet:
|
||||
return create_formatting_impl<wchar_t>(in,lc);
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
std::locale create_parsing( std::locale const &in,
|
||||
winlocale const &lc,
|
||||
character_facet_type type)
|
||||
{
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return create_parsing_impl<char>(in,lc);
|
||||
case wchar_t_facet:
|
||||
return create_parsing_impl<wchar_t>(in,lc);
|
||||
default:
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // impl_std
|
||||
} // locale
|
||||
} //boost
|
||||
|
||||
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
153
src/boost/libs/locale/src/win32/win_backend.cpp
Normal file
153
src/boost/libs/locale/src/win32/win_backend.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#define BOOST_LOCALE_SOURCE
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/locale/gnu_gettext.hpp>
|
||||
#include <boost/locale/info.hpp>
|
||||
#include "all_generator.hpp"
|
||||
#include "win_backend.hpp"
|
||||
#include <boost/locale/util.hpp>
|
||||
#include "../util/gregorian.hpp"
|
||||
#include "../util/locale_data.hpp"
|
||||
#include "api.hpp"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace impl_win {
|
||||
|
||||
class winapi_localization_backend : public localization_backend {
|
||||
public:
|
||||
winapi_localization_backend() :
|
||||
invalid_(true)
|
||||
{
|
||||
}
|
||||
winapi_localization_backend(winapi_localization_backend const &other) :
|
||||
localization_backend(),
|
||||
paths_(other.paths_),
|
||||
domains_(other.domains_),
|
||||
locale_id_(other.locale_id_),
|
||||
invalid_(true)
|
||||
{
|
||||
}
|
||||
virtual winapi_localization_backend *clone() const
|
||||
{
|
||||
return new winapi_localization_backend(*this);
|
||||
}
|
||||
|
||||
void set_option(std::string const &name,std::string const &value)
|
||||
{
|
||||
invalid_ = true;
|
||||
if(name=="locale")
|
||||
locale_id_ = value;
|
||||
else if(name=="message_path")
|
||||
paths_.push_back(value);
|
||||
else if(name=="message_application")
|
||||
domains_.push_back(value);
|
||||
|
||||
}
|
||||
void clear_options()
|
||||
{
|
||||
invalid_ = true;
|
||||
locale_id_.clear();
|
||||
paths_.clear();
|
||||
domains_.clear();
|
||||
}
|
||||
|
||||
void prepare_data()
|
||||
{
|
||||
if(!invalid_)
|
||||
return;
|
||||
invalid_ = false;
|
||||
if(locale_id_.empty()) {
|
||||
real_id_ = util::get_system_locale(true); // always UTF-8
|
||||
lc_ = winlocale(real_id_);
|
||||
}
|
||||
else {
|
||||
lc_=winlocale(locale_id_);
|
||||
real_id_ = locale_id_;
|
||||
}
|
||||
util::locale_data d;
|
||||
d.parse(real_id_);
|
||||
if(!d.utf8) {
|
||||
lc_ = winlocale();
|
||||
// Make it C as non-UTF8 locales are not supported
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::locale install(std::locale const &base,
|
||||
locale_category_type category,
|
||||
character_facet_type type = nochar_facet)
|
||||
{
|
||||
prepare_data();
|
||||
|
||||
switch(category) {
|
||||
case convert_facet:
|
||||
return create_convert(base,lc_,type);
|
||||
case collation_facet:
|
||||
return create_collate(base,lc_,type);
|
||||
case formatting_facet:
|
||||
return create_formatting(base,lc_,type);
|
||||
case parsing_facet:
|
||||
return create_parsing(base,lc_,type);
|
||||
case calendar_facet:
|
||||
{
|
||||
util::locale_data inf;
|
||||
inf.parse(real_id_);
|
||||
return util::install_gregorian_calendar(base,inf.country);
|
||||
}
|
||||
case message_facet:
|
||||
{
|
||||
gnu_gettext::messages_info minf;
|
||||
std::locale tmp=util::create_info(std::locale::classic(),real_id_);
|
||||
boost::locale::info const &inf=std::use_facet<boost::locale::info>(tmp);
|
||||
minf.language = inf.language();
|
||||
minf.country = inf.country();
|
||||
minf.variant = inf.variant();
|
||||
minf.encoding = inf.encoding();
|
||||
std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
|
||||
minf.paths = paths_;
|
||||
switch(type) {
|
||||
case char_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
|
||||
case wchar_t_facet:
|
||||
return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
|
||||
default:
|
||||
return base;
|
||||
}
|
||||
}
|
||||
case information_facet:
|
||||
return util::create_info(base,real_id_);
|
||||
case codepage_facet:
|
||||
return util::create_codecvt(base,util::create_utf8_converter(),type);
|
||||
default:
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::string> paths_;
|
||||
std::vector<std::string> domains_;
|
||||
std::string locale_id_;
|
||||
std::string real_id_;
|
||||
|
||||
bool invalid_;
|
||||
winlocale lc_;
|
||||
};
|
||||
|
||||
localization_backend *create_localization_backend()
|
||||
{
|
||||
return new winapi_localization_backend();
|
||||
}
|
||||
|
||||
} // impl win
|
||||
} // locale
|
||||
} // boost
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
20
src/boost/libs/locale/src/win32/win_backend.hpp
Normal file
20
src/boost/libs/locale/src/win32/win_backend.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP
|
||||
#define BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
class localization_backend;
|
||||
namespace impl_win {
|
||||
localization_backend *create_localization_backend();
|
||||
} // impl_win
|
||||
} // locale
|
||||
} // boost
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
10
src/boost/libs/system/src/SConscript
Normal file
10
src/boost/libs/system/src/SConscript
Normal file
@@ -0,0 +1,10 @@
|
||||
Import('dev source_path')
|
||||
|
||||
env, target, sources = dev.prepare_build(source_path, 'aboost_system', '*.cpp')
|
||||
|
||||
if '-fvisibility=hidden' in env['CCFLAGS']:
|
||||
env['CCFLAGS'].remove('-fvisibility=hidden')
|
||||
|
||||
ret = env.SharedLibrary(target, sources)
|
||||
|
||||
Return('ret')
|
||||
430
src/boost/libs/system/src/error_code.cpp
Normal file
430
src/boost/libs/system/src/error_code.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
// error_code support implementation file ----------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2002, 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See library home page at http://www.boost.org/libs/system
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/config/warning_disable.hpp>
|
||||
|
||||
// define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows
|
||||
// the library is being built (possibly exporting rather than importing code)
|
||||
#define BOOST_SYSTEM_SOURCE
|
||||
|
||||
#include <boost/system/config.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/cerrno.hpp>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
using namespace boost::system;
|
||||
using namespace boost::system::errc;
|
||||
|
||||
#include <cstring> // for strerror/strerror_r
|
||||
|
||||
# if defined( BOOST_WINDOWS_API )
|
||||
# include <windows.h>
|
||||
# include "local_free_on_destruction.hpp"
|
||||
# ifndef ERROR_INCORRECT_SIZE
|
||||
# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
|
||||
# endif
|
||||
# endif
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined(__PGI)
|
||||
using boost::system::errc::invalid_argument;
|
||||
#endif
|
||||
// standard error categories ---------------------------------------------//
|
||||
|
||||
class generic_error_category : public error_category
|
||||
{
|
||||
public:
|
||||
generic_error_category(){}
|
||||
const char * name() const;
|
||||
std::string message( int ev ) const;
|
||||
};
|
||||
|
||||
class system_error_category : public error_category
|
||||
{
|
||||
public:
|
||||
system_error_category(){}
|
||||
const char * name() const;
|
||||
std::string message( int ev ) const;
|
||||
error_condition default_error_condition( int ev ) const;
|
||||
};
|
||||
|
||||
// generic_error_category implementation ---------------------------------//
|
||||
|
||||
const char * generic_error_category::name() const
|
||||
{
|
||||
return "generic";
|
||||
}
|
||||
|
||||
std::string generic_error_category::message( int ev ) const
|
||||
{
|
||||
static std::string unknown_err( "Unknown error" );
|
||||
// strerror_r is preferred because it is always thread safe,
|
||||
// however, we fallback to strerror in certain cases because:
|
||||
// -- Windows doesn't provide strerror_r.
|
||||
// -- HP and Sun do provide strerror_r on newer systems, but there is
|
||||
// no way to tell if is available at runtime and in any case their
|
||||
// versions of strerror are thread safe anyhow.
|
||||
// -- Linux only sometimes provides strerror_r.
|
||||
// -- Tru64 provides strerror_r only when compiled -pthread.
|
||||
// -- VMS doesn't provide strerror_r, but on this platform, strerror is
|
||||
// thread safe.
|
||||
# if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
|
||||
|| (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\
|
||||
|| (defined(__osf__) && !defined(_REENTRANT))\
|
||||
|| (defined(__INTEGRITY))\
|
||||
|| (defined(__vms))\
|
||||
|| (defined(__QNXNTO__))
|
||||
const char * c_str = std::strerror( ev );
|
||||
return c_str
|
||||
? std::string( c_str )
|
||||
: unknown_err;
|
||||
# else // use strerror_r
|
||||
char buf[64];
|
||||
char * bp = buf;
|
||||
std::size_t sz = sizeof(buf);
|
||||
# if defined(__CYGWIN__) || defined(__USE_GNU)
|
||||
// Oddball version of strerror_r
|
||||
const char * c_str = strerror_r( ev, bp, sz );
|
||||
return c_str
|
||||
? std::string( c_str )
|
||||
: unknown_err;
|
||||
# else
|
||||
// POSIX version of strerror_r
|
||||
int result;
|
||||
for (;;)
|
||||
{
|
||||
// strerror_r returns 0 on success, otherwise ERANGE if buffer too small,
|
||||
// invalid_argument if ev not a valid error number
|
||||
# if defined (__sgi)
|
||||
const char * c_str = strerror( ev );
|
||||
result = 0;
|
||||
return c_str
|
||||
? std::string( c_str )
|
||||
: unknown_err;
|
||||
# else
|
||||
result = strerror_r( ev, bp, sz );
|
||||
# endif
|
||||
if (result == 0 )
|
||||
break;
|
||||
else
|
||||
{
|
||||
# if defined(__linux)
|
||||
// Linux strerror_r returns -1 on error, with error number in errno
|
||||
result = errno;
|
||||
# endif
|
||||
if ( result != ERANGE ) break;
|
||||
if ( sz > sizeof(buf) ) std::free( bp );
|
||||
sz *= 2;
|
||||
if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
|
||||
return std::string( "ENOMEM" );
|
||||
}
|
||||
}
|
||||
std::string msg;
|
||||
try
|
||||
{
|
||||
msg = ( ( result == invalid_argument ) ? "Unknown error" : bp );
|
||||
}
|
||||
|
||||
# ifndef BOOST_NO_EXCEPTIONS
|
||||
// See ticket #2098
|
||||
catch(...)
|
||||
{
|
||||
// just eat the exception
|
||||
}
|
||||
# endif
|
||||
|
||||
if ( sz > sizeof(buf) ) std::free( bp );
|
||||
sz = 0;
|
||||
return msg;
|
||||
# endif // else POSIX version of strerror_r
|
||||
# endif // else use strerror_r
|
||||
}
|
||||
// system_error_category implementation --------------------------------//
|
||||
|
||||
const char * system_error_category::name() const
|
||||
{
|
||||
return "system";
|
||||
}
|
||||
|
||||
error_condition system_error_category::default_error_condition( int ev ) const
|
||||
{
|
||||
switch ( ev )
|
||||
{
|
||||
case 0: return make_error_condition( success );
|
||||
# if defined(BOOST_POSIX_API)
|
||||
// POSIX-like O/S -> posix_errno decode table ---------------------------//
|
||||
case E2BIG: return make_error_condition( argument_list_too_long );
|
||||
case EACCES: return make_error_condition( permission_denied );
|
||||
case EADDRINUSE: return make_error_condition( address_in_use );
|
||||
case EADDRNOTAVAIL: return make_error_condition( address_not_available );
|
||||
case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
|
||||
case EAGAIN: return make_error_condition( resource_unavailable_try_again );
|
||||
# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino
|
||||
case EALREADY: return make_error_condition( connection_already_in_progress );
|
||||
# endif
|
||||
case EBADF: return make_error_condition( bad_file_descriptor );
|
||||
case EBADMSG: return make_error_condition( bad_message );
|
||||
case EBUSY: return make_error_condition( device_or_resource_busy );
|
||||
case ECANCELED: return make_error_condition( operation_canceled );
|
||||
case ECHILD: return make_error_condition( no_child_process );
|
||||
case ECONNABORTED: return make_error_condition( connection_aborted );
|
||||
case ECONNREFUSED: return make_error_condition( connection_refused );
|
||||
case ECONNRESET: return make_error_condition( connection_reset );
|
||||
case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
|
||||
case EDESTADDRREQ: return make_error_condition( destination_address_required );
|
||||
case EDOM: return make_error_condition( argument_out_of_domain );
|
||||
case EEXIST: return make_error_condition( file_exists );
|
||||
case EFAULT: return make_error_condition( bad_address );
|
||||
case EFBIG: return make_error_condition( file_too_large );
|
||||
case EHOSTUNREACH: return make_error_condition( host_unreachable );
|
||||
case EIDRM: return make_error_condition( identifier_removed );
|
||||
case EILSEQ: return make_error_condition( illegal_byte_sequence );
|
||||
case EINPROGRESS: return make_error_condition( operation_in_progress );
|
||||
case EINTR: return make_error_condition( interrupted );
|
||||
case EINVAL: return make_error_condition( invalid_argument );
|
||||
case EIO: return make_error_condition( io_error );
|
||||
case EISCONN: return make_error_condition( already_connected );
|
||||
case EISDIR: return make_error_condition( is_a_directory );
|
||||
case ELOOP: return make_error_condition( too_many_symbolic_link_levels );
|
||||
case EMFILE: return make_error_condition( too_many_files_open );
|
||||
case EMLINK: return make_error_condition( too_many_links );
|
||||
case EMSGSIZE: return make_error_condition( message_size );
|
||||
case ENAMETOOLONG: return make_error_condition( filename_too_long );
|
||||
case ENETDOWN: return make_error_condition( network_down );
|
||||
case ENETRESET: return make_error_condition( network_reset );
|
||||
case ENETUNREACH: return make_error_condition( network_unreachable );
|
||||
case ENFILE: return make_error_condition( too_many_files_open_in_system );
|
||||
case ENOBUFS: return make_error_condition( no_buffer_space );
|
||||
case ENODATA: return make_error_condition( no_message_available );
|
||||
case ENODEV: return make_error_condition( no_such_device );
|
||||
case ENOENT: return make_error_condition( no_such_file_or_directory );
|
||||
case ENOEXEC: return make_error_condition( executable_format_error );
|
||||
case ENOLCK: return make_error_condition( no_lock_available );
|
||||
case ENOLINK: return make_error_condition( no_link );
|
||||
case ENOMEM: return make_error_condition( not_enough_memory );
|
||||
case ENOMSG: return make_error_condition( no_message );
|
||||
case ENOPROTOOPT: return make_error_condition( no_protocol_option );
|
||||
case ENOSPC: return make_error_condition( no_space_on_device );
|
||||
case ENOSR: return make_error_condition( no_stream_resources );
|
||||
case ENOSTR: return make_error_condition( not_a_stream );
|
||||
case ENOSYS: return make_error_condition( function_not_supported );
|
||||
case ENOTCONN: return make_error_condition( not_connected );
|
||||
case ENOTDIR: return make_error_condition( not_a_directory );
|
||||
# if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
|
||||
case ENOTEMPTY: return make_error_condition( directory_not_empty );
|
||||
# endif // ENOTEMPTY != EEXIST
|
||||
# if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips
|
||||
case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
|
||||
# endif // ENOTRECOVERABLE != ECONNRESET
|
||||
case ENOTSOCK: return make_error_condition( not_a_socket );
|
||||
case ENOTSUP: return make_error_condition( not_supported );
|
||||
case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
|
||||
case ENXIO: return make_error_condition( no_such_device_or_address );
|
||||
# if EOPNOTSUPP != ENOTSUP
|
||||
case EOPNOTSUPP: return make_error_condition( operation_not_supported );
|
||||
# endif // EOPNOTSUPP != ENOTSUP
|
||||
case EOVERFLOW: return make_error_condition( value_too_large );
|
||||
# if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips
|
||||
case EOWNERDEAD: return make_error_condition( owner_dead );
|
||||
# endif // EOWNERDEAD != ECONNABORTED
|
||||
case EPERM: return make_error_condition( operation_not_permitted );
|
||||
case EPIPE: return make_error_condition( broken_pipe );
|
||||
case EPROTO: return make_error_condition( protocol_error );
|
||||
case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
|
||||
case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
|
||||
case ERANGE: return make_error_condition( result_out_of_range );
|
||||
case EROFS: return make_error_condition( read_only_file_system );
|
||||
case ESPIPE: return make_error_condition( invalid_seek );
|
||||
case ESRCH: return make_error_condition( no_such_process );
|
||||
case ETIME: return make_error_condition( stream_timeout );
|
||||
case ETIMEDOUT: return make_error_condition( timed_out );
|
||||
case ETXTBSY: return make_error_condition( text_file_busy );
|
||||
# if EAGAIN != EWOULDBLOCK
|
||||
case EWOULDBLOCK: return make_error_condition( operation_would_block );
|
||||
# endif // EAGAIN != EWOULDBLOCK
|
||||
case EXDEV: return make_error_condition( cross_device_link );
|
||||
#else
|
||||
// Windows system -> posix_errno decode table ---------------------------//
|
||||
// see WinError.h comments for descriptions of errors
|
||||
case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied );
|
||||
case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists );
|
||||
case ERROR_BAD_UNIT: return make_error_condition( no_such_device );
|
||||
case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long );
|
||||
case ERROR_BUSY: return make_error_condition( device_or_resource_busy );
|
||||
case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy );
|
||||
case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied );
|
||||
case ERROR_CANTOPEN: return make_error_condition( io_error );
|
||||
case ERROR_CANTREAD: return make_error_condition( io_error );
|
||||
case ERROR_CANTWRITE: return make_error_condition( io_error );
|
||||
case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied );
|
||||
case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device );
|
||||
case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy );
|
||||
case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty );
|
||||
case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid"
|
||||
case ERROR_DISK_FULL: return make_error_condition( no_space_on_device );
|
||||
case ERROR_FILE_EXISTS: return make_error_condition( file_exists );
|
||||
case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
|
||||
case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device );
|
||||
case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied );
|
||||
case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device );
|
||||
case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported );
|
||||
case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument );
|
||||
case ERROR_INVALID_NAME: return make_error_condition( invalid_argument );
|
||||
case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available );
|
||||
case ERROR_LOCKED: return make_error_condition( no_lock_available );
|
||||
case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument );
|
||||
case ERROR_NOACCESS: return make_error_condition( permission_denied );
|
||||
case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory );
|
||||
case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again );
|
||||
case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link );
|
||||
case ERROR_OPEN_FAILED: return make_error_condition( io_error );
|
||||
case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy );
|
||||
case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled );
|
||||
case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory );
|
||||
case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
|
||||
case ERROR_READ_FAULT: return make_error_condition( io_error );
|
||||
case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again );
|
||||
case ERROR_SEEK: return make_error_condition( io_error );
|
||||
case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied );
|
||||
case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open );
|
||||
case ERROR_WRITE_FAULT: return make_error_condition( io_error );
|
||||
case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied );
|
||||
case WSAEACCES: return make_error_condition( permission_denied );
|
||||
case WSAEADDRINUSE: return make_error_condition( address_in_use );
|
||||
case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available );
|
||||
case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported );
|
||||
case WSAEALREADY: return make_error_condition( connection_already_in_progress );
|
||||
case WSAEBADF: return make_error_condition( bad_file_descriptor );
|
||||
case WSAECONNABORTED: return make_error_condition( connection_aborted );
|
||||
case WSAECONNREFUSED: return make_error_condition( connection_refused );
|
||||
case WSAECONNRESET: return make_error_condition( connection_reset );
|
||||
case WSAEDESTADDRREQ: return make_error_condition( destination_address_required );
|
||||
case WSAEFAULT: return make_error_condition( bad_address );
|
||||
case WSAEHOSTUNREACH: return make_error_condition( host_unreachable );
|
||||
case WSAEINPROGRESS: return make_error_condition( operation_in_progress );
|
||||
case WSAEINTR: return make_error_condition( interrupted );
|
||||
case WSAEINVAL: return make_error_condition( invalid_argument );
|
||||
case WSAEISCONN: return make_error_condition( already_connected );
|
||||
case WSAEMFILE: return make_error_condition( too_many_files_open );
|
||||
case WSAEMSGSIZE: return make_error_condition( message_size );
|
||||
case WSAENAMETOOLONG: return make_error_condition( filename_too_long );
|
||||
case WSAENETDOWN: return make_error_condition( network_down );
|
||||
case WSAENETRESET: return make_error_condition( network_reset );
|
||||
case WSAENETUNREACH: return make_error_condition( network_unreachable );
|
||||
case WSAENOBUFS: return make_error_condition( no_buffer_space );
|
||||
case WSAENOPROTOOPT: return make_error_condition( no_protocol_option );
|
||||
case WSAENOTCONN: return make_error_condition( not_connected );
|
||||
case WSAENOTSOCK: return make_error_condition( not_a_socket );
|
||||
case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported );
|
||||
case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
|
||||
case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type );
|
||||
case WSAETIMEDOUT: return make_error_condition( timed_out );
|
||||
case WSAEWOULDBLOCK: return make_error_condition( operation_would_block );
|
||||
#endif
|
||||
default: return error_condition( ev, system_category() );
|
||||
}
|
||||
}
|
||||
|
||||
# if !defined( BOOST_WINDOWS_API )
|
||||
|
||||
std::string system_error_category::message( int ev ) const
|
||||
{
|
||||
return generic_category().message( ev );
|
||||
}
|
||||
# else
|
||||
|
||||
std::string system_error_category::message( int ev ) const
|
||||
{
|
||||
# ifndef BOOST_NO_ANSI_APIS
|
||||
LPVOID lpMsgBuf = 0;
|
||||
DWORD retval = ::FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
ev,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
detail::local_free_on_destruction lfod(lpMsgBuf);
|
||||
if (retval == 0)
|
||||
return std::string("Unknown error");
|
||||
|
||||
std::string str( static_cast<LPCSTR>(lpMsgBuf) );
|
||||
# else // WinCE workaround
|
||||
LPVOID lpMsgBuf = 0;
|
||||
DWORD retval = ::FormatMessageW(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
ev,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPWSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
detail::local_free_on_destruction lfod(lpMsgBuf);
|
||||
if (retval == 0)
|
||||
return std::string("Unknown error");
|
||||
|
||||
int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2;
|
||||
LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
|
||||
if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
|
||||
return std::string("Unknown error");
|
||||
|
||||
std::string str( narrow_buffer );
|
||||
# endif
|
||||
while ( str.size()
|
||||
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
|
||||
str.erase( str.size()-1 );
|
||||
if ( str.size() && str[str.size()-1] == '.' )
|
||||
{ str.erase( str.size()-1 ); }
|
||||
return str;
|
||||
}
|
||||
# endif
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
|
||||
# ifndef BOOST_SYSTEM_NO_DEPRECATED
|
||||
BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code;
|
||||
// note that it doesn't matter if this
|
||||
// isn't initialized before use since
|
||||
// the only use is to take its
|
||||
// address for comparison purposes
|
||||
# endif
|
||||
|
||||
BOOST_SYSTEM_DECL const error_category & system_category()
|
||||
{
|
||||
static const system_error_category system_category_const;
|
||||
return system_category_const;
|
||||
}
|
||||
|
||||
BOOST_SYSTEM_DECL const error_category & generic_category()
|
||||
{
|
||||
static const generic_error_category generic_category_const;
|
||||
return generic_category_const;
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
40
src/boost/libs/system/src/local_free_on_destruction.hpp
Normal file
40
src/boost/libs/system/src/local_free_on_destruction.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// local_free_on_exit.hpp ------------------------------------------------------------//
|
||||
|
||||
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2010 Beman Dawes
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid
|
||||
// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out.
|
||||
|
||||
#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
|
||||
#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace system {
|
||||
namespace detail {
|
||||
|
||||
class local_free_on_destruction
|
||||
{
|
||||
public:
|
||||
explicit local_free_on_destruction(void* p)
|
||||
: p_(p) {}
|
||||
|
||||
~local_free_on_destruction()
|
||||
{
|
||||
::LocalFree(p_);
|
||||
}
|
||||
|
||||
private:
|
||||
void* p_;
|
||||
local_free_on_destruction(const local_free_on_destruction&); // = deleted
|
||||
local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
|
||||
Reference in New Issue
Block a user