Как я могу избежать кодирования смешивания строк в C / C ++ API? - PullRequest
4 голосов
/ 21 мая 2010

Я работаю над реализацией различных API на C и C ++ и спрашиваю себя, какие методы доступны, чтобы избежать неправильного кодирования клиентами при получении строк из фреймворка или их передаче обратно. Например, представьте себе простой API плагинов в C ++, который клиенты могут реализовать для влияния на переводы. Это может иметь такую ​​функцию:

const char *getTranslatedWord( const char *englishWord );

Теперь, допустим, я бы хотел, чтобы все строки передавались как UTF-8. Конечно, я бы задокументировал это требование, но я бы хотел, чтобы компилятор обеспечил правильное кодирование, возможно, с помощью выделенных типов. Например, что-то вроде этого:

class Word {
public:
  static Word fromUtf8( const char *data ) { return Word( data ); }
  const char *toUtf8() { return m_data; }

private:
  Word( const char *data ) : m_data( data ) { }

  const char *m_data;
};

Теперь я могу использовать этот специализированный тип в API:

Word getTranslatedWord( const Word &englishWord );

К сожалению, это легко сделать очень неэффективным. В классе Word отсутствуют надлежащие конструкторы копирования, операторы присваивания и т. Д., И я бы хотел как можно больше избегать ненужного копирования данных. Кроме того, я вижу опасность того, что Word расширяется с помощью все большего количества служебных функций (например, length или fromLatin1 или substr и т. Д.), И я бы предпочел не писать еще один класс String. Я просто хочу маленький контейнер, чтобы избежать случайных кодировок.

Интересно, есть ли у кого-нибудь еще опыт с этим и может ли он поделиться некоторыми полезными приемами?

РЕДАКТИРОВАТЬ: В моем конкретном случае API используется в Windows и Linux с использованием MSVC 6 - MSVC 10 в Windows и gcc 3 & 4 в Linux.

Ответы [ 3 ]

4 голосов
/ 21 мая 2010

Вы можете передавать arround std :: pair вместо char *:

struct utf8_tag_t{} utf8_tag;
std::pair<const char*,utf8_tag_t> getTranslatedWord(std::pair<const char*,utf8_tag_t> englishWord);

Сгенерированный машинный код должен быть идентичен приличному современному компилятору, который использует пустую оптимизацию базового класса для std :: pair.


Хотя я не беспокоюсь об этом. Я бы просто использовал char * s и задокументировал, что ввод должен быть utf8. Если данные могут поступать из ненадежного источника, вам все равно придется проверять кодировку во время выполнения.

1 голос
/ 21 мая 2010

Я предлагаю вам использовать std::wstring.

Проверьте этот другой вопрос для деталей.

0 голосов
/ 21 мая 2010

Проект ICU предоставляет библиотеку поддержки Unicode для C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...