Текущий раздел:

Описания RDS

Приложения

Приложение А. Функции, константы и структуры RDS

А.1. Типы параметров

А.1.3. Строковые поля в служебных структурах

# Приложения

## Приложение А. Функции, константы и структуры RDS

### А.1. Типы параметров

#### А.1.3. Строковые поля в служебных структурах

В отличие от первой версии RDS, где все строки хранились в кодировке CP1251, во второй версии везде используется кодировка UTF8. Однако, в функциях и структурах Windows API применяется кодировка UTF16, поэтому во всех служебных структурах RDS с именами вида RDS_*, содержащих поля-указатели на строки, эти поля удвоены: поле с суффиксом «A» содержит указатель на строку в UTF8, а поле с суффиксом «W» – на строку в UTF16. Таким образом, программист может выбрать, с какой кодировкой ему удобнее работать.

Рассмотрим условную структуру с полем-строкой «sField». Если бы не необходимость в двойной кодировке, она выглядела бы следующим образом:

      typedef struct
      { int iField;             // Целое поле
        const char *sField;     // Строка
      } RDS_STRINGSTRUCT;

Если сейчас не рассматривать анонимные объединения для выравнивания полей, то в RDS эта структура будет выглядеть так:

      typedef struct
      { int iField;             // Целое поле
        const char *sFieldA;    // Строка в UTF8
        const wchar_t *sFieldW; // Строка в UTF16
      } RDS_STRINGSTRUCT;

Строковое поле «sField» заменено двумя: «sFieldA» для строки в UTF8 и «sFieldW» для строки в UTF16 (в программах для Windows тип wchar_t* описывает строку в UTF16). Принцип работы с этими новыми полями следующий:

- если структура заполняется в RDS и передается в модель блока при вызове (например, RDS_BLOCKDATA, RDS_NETCONNDATA и т.п.), то в переданной структуре всегда будут заполнены оба поля (они будут содержать указатели на одну и ту же строку в разных кодировках), и программист модели может считывать любое из них;
- если указатель на пустую структуру передается в RDS для ее заполнения какими-либо описаниями (например, RDS_BLOCKDESCRIPTION, RDS_CONNDESCRIPTION и т.п.), то в структуре тоже всегда будут заполнены оба поля;
- если структура заполняется какими-либо данными в модели, а потом вызывается сервисная функция для передачи этих данных в RDS (например, для этого может использоваться структура RDS_SERVFONTPARAMS), то программист модели перед вызовом должен заполнить в структуре поля, соответствующие суффиксу вызываемой функции (как и функции с параметрами-строками, функции с параметрами-структурами тоже могут иметь суффиксы «A» и «W», если в этих структурах есть «двойные» строковые поля).

Таким образом, на стороне RDS в структурах всегда заполняются оба поля, а на стороне модели следует заполнять поле, соответствующее версии вызываемой функции.

Для сохранения совместимости с первой версией RDS, где строковые поля не имели суффиксов, а также для того, чтобы, при желании, можно было использовать имя поля и без суффикса для доступа к строке с кодировкой по умолчанию, для строковых полей структур введены псевдонимы, совпадающие с названиями соответствующих полей в структурах версии RDS 1.x. Псевдонимы введены через анонимные объединения (union), в которые, в зависимости от наличия описаний констант RDS_NO_UTFALIASES и RDS_UTF16DEFAULT, вводятся дополнительные поля со старым именем. В объединениях все поля находятся по одному и тому же адресу, поэтому, если объединение содержит два поля одного и того же типа, их имена полностью взаимозаменяемы.

Рассмотренная выше условная структура RDS_STRINGSTRUCT с псевдонимом для поля sField выглядит примерно так (реальное описание отличается наличием дополнительных служебных полей для выравнивания):

      typedef struct
      { int iField;                 // Целое поле
        union
          { const char *sFieldA;    // Строка в UTF8
            #if (!defined(RDS_NO_UTFALIASES)) && (!defined(RDS_UTF16DEFAULT))
              const char *sField;   // Псевдоним
            #endif
          };
        union
          { const wchar_t *sFieldW; // Строка в UTF16
            #if (!defined(RDS_NO_UTFALIASES)) && defined(RDS_UTF16DEFAULT)
              const wchar_t *sField;// Псевдоним
            #endif
          };
      } RDS_STRINGSTRUCT;

Макроопределения констант RDS_NO_UTFALIASES и RDS_UTF16DEFAULT управляют описанием «псевдонимов» для полей структур и функций с параметрами-строками. Команды #define для них следует помещать в исходный текст модели перед включением файлов «RdsDef.h» и «RdsFunc.h».

Если программист хочет по имени без суффикса «sField» обращаться к полю, содержащему строку в кодировке UTF8, то перед включением заголовков RDS никаких констант описывать не нужно:

      #include <RdsDef.h>
      #include <RdsFunc.h>
      …
      RDS_STRINGSTRUCT a;
      a.sField="1234";

Если программист хочет, чтобы имя «sField» давало доступ к строке в кодировке UTF16, то перед включением заголовков RDS сдедует описать константу RDS_UTF16DEFAULT:

      #define RDS_UTF16DEFAULT
      #include <RdsDef.h>
      #include <RdsFunc.h>
      …
      RDS_STRINGSTRUCT a;
      a.sField=L"1234";

(здесь префикс «L» перед строкой в кавычках указывает на то, что это строка в «расширенной» кодировке, т.е. в UTF16 при компиляции для Windows).

Если же программист вообще не хочет использовать псевдонимы полей, то перед включением заголовков RDS следует описать константу RDS_NO_UTFALIASES:

      #define RDS_NO_UTFALIASES
      #include <RdsDef.h>
      #include <RdsFunc.h>
      …
      RDS_STRINGSTRUCT a;
      a.sFieldA="1234";
      a.sFieldW=L"1234";

Разумеется, имена полей с суффиксами «A» и «W» доступны всегда, независимо от описаний RDS_NO_UTFALIASES и RDS_UTF16DEFAULT.