blob: efe2997562a4afbf849279f54fc1390fc6abcb39 [file] [log] [blame]
// Definitions for <text_encoding> -*- C++ -*-
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <text_encoding>
#include <locale>
#ifdef _GLIBCXX_USE_NL_LANGINFO_L
#include <locale.h>
#if __has_include(<xlocale.h>)
# include <xlocale.h>
#endif
#include <langinfo.h>
#if __CHAR_BIT__ == 8
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace
{
// Attempt to determine the text_encoding used by the named locale.
text_encoding
__locale_encoding(const char* name)
{
text_encoding enc;
if (locale_t loc = ::newlocale(LC_CTYPE_MASK, name, (locale_t)0))
{
if (const char* codeset = ::nl_langinfo_l(CODESET, loc))
{
string_view s(codeset);
if (s.size() < text_encoding::max_name_length)
enc = text_encoding(s);
}
::freelocale(loc);
}
return enc;
}
} // namespace
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
std::text_encoding
std::text_encoding::environment()
{
return std::__locale_encoding("");
}
bool
std::text_encoding::_M_is_environment() const
{
bool matched = false;
if (locale_t loc = ::newlocale(LC_CTYPE_MASK, "", (locale_t)0))
{
if (const char* codeset = ::nl_langinfo_l(CODESET, loc))
{
string_view sv(codeset);
for (auto alias : aliases())
if (__unicode::__charset_alias_match(alias, sv))
{
matched = true;
break;
}
}
::freelocale(loc);
}
return matched;
}
std::text_encoding
std::locale::encoding() const
{
string name = this->name();
if (name.length() == 1)
{
if (name[0] == 'C')
return text_encoding(text_encoding::ASCII);
if (name[0] == '*')
return {};
}
return __locale_encoding(name.c_str());
}
#endif // CHAR_BIT == 8
#endif // _GLIBCXX_USE_NL_LANGINFO_L