Шаблонний клас std::codecvt являється стандартним класом facet-властивості локалі (похідний від класу std::locale::facet), і призначений для перетворень між двома наборами кодування символів. Оголошення класу приблизно виглядає наступним чином:
template <class internT, 
          class externT, 
          class stateT> class codecvt ;
Параметр шаблону internT призначений для позначення внутрішнього типу символів, зазвичай він являється розширеним типом символів, на подобі wchar_t. Параметр шаблону externT, призначений для вказування зовнішнього типу збереження символів. Параметр шаблону stateT призначений для вказування типу, який буде зберігати стан перетворення, зазвичай це mbstate_t. Клас std::codecvt містить захищений деструктор - програми повинні конструювати об'єкти класів, які являються похідними від даного, або використовувати об'єкти, які присутні у об'єктах класу locale (через функцію std::use_facet). Усі стандартні об'єкти класу locale підтримують наступні ініціалізовані об'єкти:
  • codecvt<char, char, mbstate_t> не виконує перетворення;
  • codecvt<wchar_t, char, mbstate_t> перетворює символи з рідного розширеного типу у звичайне кодування.

Поля, методи і внутрішні типи

Внутрішні типи

typedef internT intern_type ;
Перший параметр шаблону (internT). Внутрішній тип символів.
typedef externT extern_type ;
Другий параметр шаблону (externT). Зовнішній тип збереження символів.
typedef stateT state_type ;
Третій параметр шаблону (stateT). Тип стану перетворення.
typedef codecvt_base::result result ;
Даний тип успадкований від codecvt_base, і використовується методами in, out, i unshift.

Внутрішні константи

Наступні константи успадковані даним класом від codecvt_base і використовуються методами класу у якості повернутого значення.
codecvt_base::result ok ;
Константа означає успішне перетворення.
codecvt_base::result partial ;
Константа означає часткове перетворення.
codecvt_base::result error ;
Дане значення означає помилку під час перетворення.
codecvt_base::result noconv ;
Дана константа означає відсутнє перетворення.
static locale::id id ;
Унікально ідентифікує аспект локалі.

Методи

explicit codecvt (size_t refs = 0) ;
Конструктор. Конструює новий об'єкт класу.  Параметр refs вказує на: 0 - коли об'єкт повинен бути автоматично видаленим, коли останній об'єкт locale, який містить даний об'єкт повинен бути видалений; 1 - об'єкт автоматично не видаляється.
result in (state_type& state, 
           const extern_type* from, /* вказівник на перший символ послідовності */
           const extern_type* from_end, /* вказівник на останній символ послідовності */
           const extern_type*& from_next, /* вказівник, який може вказувати на послідовність */
           intern_type* to, /* початок послідовності збереження */
           intern_type* to_limit, /* кінець послідовності збереження */
           intern_type*& to_next) /* вказівник, який може вказувати на елемент послідовність */
       const ;
Метод перетворює символи з проміжку [from, from_end) і поміщає їх у послідовність, яка починається з to. Метод не намагається зберегти більше символів ніж це дозволяє параметр to_limit. Параметри from_next i to_next, призначені для збереження вказівника на елемент відповідної послідовності, який розміщується після останнього успішного перетвореного символу. Параметр state призначений для ініціалізації аспекту локалі. Зазвичай він являється об'єктом типу mbstate_t, який може зберігати просування процесу перетворення. Метод зупиняється перетворювати символи коли виникає помилка перетворення символу, або метод досягнув межу перетворення from_end і усі символи успішно збережено. Повернене значення, разом з значеннями параметрів from_next i to_next після виклику методу можуть бути використаними для обрахунку успішності перетворення символів. Даний метод насправді являється делегатом і викликає віртуальний захищений (protected)  метод do_in, який реалізовується в похідних класах.
result out (state_type& state, 
            const intern_type* from, 
            const intern_type* from_end, 
            const intern_type*& from_next,
            extern_type* to, 
            extern_type* to_limit, 
            extern_type*& to_next) 
       const ;
Перетворює закодовані символи у послідовності [from, from_end) і розміщує їх у послідовність [to, to_limit). Вказівники from_next i to_next повинні мати здатність вказувати на елементи своїх послідовностей. Параметр state утримує стан просування процесу перетворення. Метод зупиняється перетворювати коди символів коли натрапляє на перший символ, який він не в змозі перетворити, або коли усі символи успішно перетворено і збережено в послідовність [to, to_limit). Повернене значення, разом з значеннями параметрів from_next i to_next після виклику методу, можуть бути використаними для визначення успішності результату перетворення.
int always_noconv () const throw () ;
Повертає значення яке вказує на те, чи перетворення між внутрішнім і зовнішнім типами у двох напрямках, завжди виконує копіювання без будь-якого перетворення. Якщо даний метод повертає true для конкретного типу codecvt, тоді його методи codecvt::in i codecvt::out завжди повертають codecvt_base::noconv (тобто копіюють дані без будь-якого перетворення).
int encoding () const throw () ;
Повертає ширину внутрішніх символів у кількостях зовнішніх комірок для зберігання, якщо його це значення є фіксованим. Якщо ж дане значення змінюється від символа до символа, повертає 0 (нуль). Якщо кодування зовнішнього типу символів являється залежним від стану, повертає -1. Даний метод викликає віртуальний метод do_encoding, який реалізовується в дочірніх класах.
int length (state_type& state, 
            const extern_type* from,
            const extern_type* from_end, 
            size_t max) 
     const ;
Повертає довжину зовнішньої послідовності з проміжку [from, from_end), яка може бути перетвореною у максимальну кількість комірок, відносно кількості max внутрішніх символів. Після виклику даного методу стан state змінюється, як після виклику методу codecvt::in.
int max_length () const throw () ;
Повертає максимальну кількість необхідних внутрішніх символів, які потрібні для зовнішніх символів.
result unshift (state_type& state, 
                extern_type* to, 
                extern_type* to_limit, 
                extern_type*& to_next) 
       const ;
Змінює стан перетворення. Під час перетворення кодування символів (наприклад, методом codecvt::out) стан у state може бути зміненим, коли цільова послідовність не може абсорбувати усі символи, які згенеровані перетворенням. Викликаючи даний метод, з додатковим місцем для збереження, останні символи, які повинні бути збереженими, поміщаються у послідовність [to, to_limit), і стан state повертається до свого необхідного значення (або зміщується до кількості (to_limit-to)). Після того, як функція виконує свою роботу, вказівник to_next вказує на елемент, який знаходиться за останнім успішно записаним елементом. Метод повертає один з значень типу codecvt_base::result (ok, partial, error, noconv).

Приклад

Розглянемо простий приклад перетворення рядка символів у зовнішній тип за допомогою codecvt.
#include <locale>
#include <string.h>
#include <string>
#include <iostream>
using namespace std ;

int main (int argc, char** argv)
{
  /* створюємо об'єкт для бажаної локалі 
  ** в моєму випадку це uk_UA.UTF-8 */
  locale u8loc ("") ;
  
  /* підготовлюємо цільовий буфер */
  const unsigned int rlen = 256 ; /* довжина цільового буферу */
  char cstr [rlen] ; /* цільовий буфер */
  char* cptr = NULL ; /* вказівник не елемент */
  
  /* підготовлюємо джерельний буфер */
  const wchar_t warray [] = L"Рядок на українській." ;
  const wchar_t* ptr = NULL ; /* вказівник на елемент джерельного буферу */
  int wlen = sizeof (warray)/sizeof (warray[0]) ; /* розмір джерельного буферу */
  
  /* об'єкт стану перетворення*/
  codecvt<wchar_t, char, mbstate_t>::state_type state ;
  
  /* отримуємо facet-аспект перекладач локалі */
  const codecvt<wchar_t, char, mbstate_t>& cvt = use_facet < codecvt<wchar_t, char, mbstate_t> > (u8loc) ;

  /* виконуємо перетворення з розширеного буферу у звичайний */
  codecvt<wchar_t, char, mbstate_t>::result res = cvt.out (state, warray, warray + wlen, ptr,
                                                           cstr, cstr+rlen, cptr) ;

  /* перевіряємо результат і виводимо повідомлення */
  if (res==cvt.ok)
  {
    /* cstr тепер містить UTF-8 послідовність байтів 
    ** які представляють рядок warray */
    cout << "Успішне транслювання: " 
         << cstr /* УВАГА! це може не спрацювати у терміналі!!! */
         << endl ; 
         
    cout << "Розмір джерельного буферу: " << wlen
         << "; розмір цільового буферу: " << strlen (cstr) << endl ;
  }
  else
  {
    cout << "Помилка транслювання" << endl ;
  }  
  
  return 0 ;
}
Вивід програми наступний: cpp_std_codecvt_sample1-cxx
Категорії: