#ifndef LTEDSAPI_BASE_H_
#define LTEDSAPI_BASE_H_

#include "ltrapitypes.h"

#ifdef __cplusplus
extern "C" {                                 // only need to export C interface if
                                             // used by C++ source code
#endif

#ifdef _WIN32
    #ifdef LTEDSAPI_EXPORTS
      #define LTEDSAPI_DllExport(type) __declspec(dllexport) type APIENTRY
    #else
      #define LTEDSAPI_DllExport(type) __declspec(dllimport) type APIENTRY
    #endif
#elif defined __GNUC__
    #define LTEDSAPI_DllExport(type) __attribute__ ((visibility("default"))) type
#else
    #define LTEDSAPI_DllExport(type)  type
#endif

#pragma pack(4)

/***************************************************************************//**
  @addtogroup base_types Общие определения и типы
  @{
  *****************************************************************************/


/** Размер блока в байтах, защищаемого контрольной суммой, в данных от TEDS */
#define LTEDS_CHECKSUM_BLOCK_LEN  32
/** Минимальный год, который может быть закодирован в поле типа Date в TEDS */
#define LTEDS_DATE_MIN_YEAR  1998
/** Значение, указывающее, что свойство типа UnInt не используется в TEDS */
#define LTEDS_UNINT_VAL_NOT_USED 0xFFFFFFFF


/** @brief Коды ошибок

   Коды ошибок, которые могут возвращать функции данной библиотеки */
typedef enum {
    LTEDS_OK = 0,
    LTEDS_ERROR_INSUF_SIZE = -12000, /**< Недостаточно места в данных TEDS для выполнения операции */
    LTEDS_ERROR_CHECKSUM = -12001, /**< Неверное значение контрольной суммы в данных TEDS */
    LTEDS_ERROR_INVALID_BITSIZE = -12002, /**< Неверно задан битовый размер данных TEDS */
    LTEDS_ERROR_UNSUPPORTED_FORMAT = -12003, /**< Не поддерживается указанный формат данных TEDS */
    LTEDS_ERROR_ENCODE_VALUE = -12004, /**< Неверно указано значение для кодирования в TEDS */
    LTEDS_ERROR_UNKNOWN_SEL_CASE = -12005 /**< Неизвестный вариант выбора ветвления данных TEDS */
} e_LTEDS_ERRORS;




/** Набор флагов, определяющих свойства данных TEDS */
typedef enum {
    /** Признак наличия байтов контрольной суммы в данных TEDS.
       По умолчанию библиотека обрабатывает данные TEDS, из которых уже 
       удалены байты контрольной суммы. 
       Если указан флаг, то библиотека считает, что каждый блок из 
       #LTEDS_CHECKSUM_BLOCK_LEN байт содержит первым байтом контрольную 
       сумму и сама извлекает и  проверяет ее при разборе данных.
       Поддерживается только при разборе данных TEDS. */
    LTEDS_DATA_FLAG_HAS_CHECKSUM = (0x1 << 0)
} e_LTEDS_DATA_FLAGS;

/** @brief Коды селекторов TEDS
 *
    Данное перечисление описывает возможные значения селектора.
    Селектор определяет, как интерпретировать данные каждого блока в области TEDS,
    идущей после  [базовой информации](@ref TLTEDS_INFO_BASIC).
    Каждый последующий блок данных содержит вначале селектор, значение которого
    можно получить с помощью LTEDS_GetSelector() */
typedef enum {
    /** Указывает, что далее идет стандартный шаблон, описанный в 
        [IEEE 1451.4](https://www.iso.org/standard/54368.html).
        После селектора следует идентификатор стандартного шаблона из 8 бит,
        который можно получить через LTEDS_GetStdTemplateID(). */
    LTEDS_SEL_STANDARD     = 0,
    /** Указывает, что далее идут данные, определенные шаблоном производителя,
        идентификатор которого был указан в [базовой информации](@ref TLTEDS_INFO_BASIC).
        Размер идущего далее поля идентификатора шаблона зависит от производителя 
        и может отличаться от стандартного.        
        Данная библиотека сама не разбирает данные шаблонов производителей 
        (за исключением шаблонов производителя "Л Кард"), однако
        их разбор можно реализовать с помощью [низкоуровневых функций](@ref dec_func_ll)
        в соответствии с описанием этих шаблонов */
    LTEDS_SEL_MANUFACTURER = 1,

    /** Указывает, что далее идут данные, определенные шаблоном производителя,
        отличного от того, идентификатор которого был указан в 
        [базовой информации](@ref TLTEDS_INFO_BASIC).
        После селектора идет 14-битный идентификатор производителя, с которым
        связан шаблон, описывающий данные блока, после чего формат аналогичен
        селектору #LTEDS_SEL_MANUFACTURER. */
    LTEDS_SEL_OTHER_MANUFACTURER = 2,
    /** Данный селектор указывает окончание данных TEDS, описываемых шаблонами.
        После него идет расширение завершающего шаблона, имеющее значение
        из перечисления #e_LTEDS_EXTSEL_TYPE и определяющее в каком формате
        идут далее пользовательские данные. */
    LTEDS_SEL_END          = 3,
} e_LTEDS_SEL_TYPE;


/** @brief Коды расширения завершающего селектора.

  Расширение завершающего селектора дополняет селектор типа #LTEDS_SEL_END и
  определяет, в каком формате идут далее возможные пользовательские данные.
  Значение может быть получено с помощью LTEDS_GetEndExtendedSelector(). */
typedef  enum {
    /** Данное значение указывает, что далее идут пользовательские данные
     *  в произвольном формате */
    LTEDS_EXTSEL_FREE_FORM = 0,
    /** Данное значение указывает, что далее идут пользовательские данные
     * в виде ASCII-строки */
    LTEDS_EXTSEL_ASCII = 1
} e_LTEDS_EXTSEL_TYPE;

/** @brief Стандартные идентификаторы шаблонов

   Идентификатор шаблона вместе с идентификатором производителя
   позволяет однозначно идентифицировать шаблон, описывающий 
   структуру данных в блоке TEDS.
   
   Данное перечисление определяет идентификаторы стандартных шаблонов,
   не связанных с производителем. Идентификатор стандартного шаблона
   идет за селектором типа #LTEDS_SEL_STANDARD и может быть получен с
   помощью LTEDS_GetStdTemplateID().
   
   Для некоторых стандартных шаблонов в библиотеке определена своя структура для
   сохранения информации и своя функция для извлечения и кодирования этой
   информации. Эти типы и функции описаны в подразделах, посвященных
   соответствующему шаблону.

   Для остальных стандартных шаблонов соответствующие функции и структуры могут
   быть добавлены по запросу.
*/
typedef enum {
    /** Шаблон для акселерометра или датчика силы
        (раздел @ref std_tmpl_25). */
    LTEDS_STD_TEMPLATE_ID_ACCFORCE              = 25,
    /** Шаблон для усилителя заряда c
        подключенным пьезоэлектрическим акселерометром. */
    LTEDS_STD_TEMPLATE_ID_CHARGE_APLIFIER       = 26,
    /** Шаблон для микрофона с встроенным
     *  предусилителем. */
    LTEDS_STD_TEMPLATE_ID_MICROPHONE            = 27,
    /** Шаблон для предусилителя микрофона c
        опциями для подключенного микрофона. */
    LTEDS_STD_TEMPLATE_ID_PREAM_MICROPHONE      = 28,
    /** Шаблон для конденсаторного микрофона. */
    LTEDS_STD_TEMPLATE_ID_CAPACITIVE_MICROPHONE = 29,
    /** Шаблон для линейного датчика общего назначения
        с выходом по напряжению (раздел @ref std_tmpl_hlvout). */
    LTEDS_STD_TEMPLATE_ID_HL_VOLTAGE_OUTPUT     = 30,
    /** Шаблон для линейного датчика общего назначения
        с выходом по току. */
    LTEDS_STD_TEMPLATE_ID_CURRENT_LOOP_OUTPUT   = 31,
    /** Шаблон для датчика с резистивным выходом. */
    LTEDS_STD_TEMPLATE_ID_RESISTANCE_SENSOR     = 32,
    /** Шаблон для датчика с выходом в виде моста сопротивлений
        (раздел @ref std_tmpl_bridge). */
    LTEDS_STD_TEMPLATE_ID_BRIDGE_SENSOR         = 33,
    /** Шаблон для дифференциального трансформатора
        для измерения линейных (LVDT) / вращательных (RVDT) перемещений. */
    LTEDS_STD_TEMPLATE_ID_LVDT_RVDT             = 34,
    /** Шаблон для тензодатчика в мостовых схемах */
    LTEDS_STD_TEMPLATE_ID_STRAIN_GAGE           = 35,
    /** Шаблон для термопары. */
    LTEDS_STD_TEMPLATE_ID_THERMOCOUPLE          = 36,
    /** Шаблон для термосопротивления. */
    LTEDS_STD_TEMPLATE_ID_RTD                   = 37,
    /** Шаблон для термисторов с характеристикой, соответствующей
        уравнению Стейнхарта. */
    LTEDS_STD_TEMPLATE_ID_THERMISTOR            = 38,
    /** Шаблон для потенциометрического делителя напряжения */
    LTEDS_STD_TEMPLATE_ID_POTENTIOMETRIC_VDIV   = 39,
    /** Шаблон для определения калибровочной таблицы, задающей
     *  отклонения передаточной функции датчика от номинальной линейной
     *  в указанных точках (раздел @ref std_tmpl_caltbl). */
    LTEDS_STD_TEMPLATE_ID_CAL_TABLE             = 40,
    /** Шаблон для задания передаточной функции в виде фрагментов,
     *  каждый из которых задается полиномом */
    LTEDS_STD_TEMPLATE_ID_CAL_CURVE             = 41,
    /** Шаблон для задания зависимости отклонения амплитуды от частоты
     *  сигнала (АЧХ) */
    LTEDS_STD_TEMPLATE_ID_FREQ_RESP_TABLE       = 42,
    /** Шаблон для усилителя заряда с подключенным пьезоэлектрическим
     *  датчиком силы */
    LTEDS_STD_TEMPLATE_ID_CHARGE_AMPL_FORCE     = 43,
} e_LTEDS_STD_TEMPLATE_ID;




/** @brief Базовая информация TEDS

    Структура содержит данные из базовой информации TEDS (Basic TEDS).
    Базовая информация всегда содержится в начале данных TEDS
    в фиксированном виде и содержит информацию для идентификации преобразователя,
    включая производителя, модель, версию и серийный номер преобразователя.
    Данная информация извлекается из данных TEDS самой первой с помощью
    функции LTEDS_GetBasicInfo().
 */
typedef struct {
    WORD ManufacturerID; /**< Уникальный идентификатор производителя. */
    WORD ModelNumber;    /**< Номер модели, определяющий тип преобразователя. */
    CHAR VersionLetter;  /**< Буквенная версия преобразователя. */
    BYTE VersionNumber;  /**< Численная версия преобразователя. */
    DWORD SerialNumber;  /**< Серийный номер данного экземпляра преобразователя. */
} TLTEDS_INFO_BASIC;


/** @brief Информация о дате

   Структура содержит информацию о дате, полученной из данных TEDS.
   Все поля равные 0 соответствуют недействительной дате. */
typedef struct {
    BYTE Day; /**< Число (день месяца от 1 до 31) */
    BYTE Month; /**< Месяц (от 1 до 12) */
    WORD Year; /**< Год. Минимальное значение, которое может быть закодировано
                    в TEDS определено константой #LTEDS_DATE_MIN_YEAR */
} TLTEDS_INFO_DATE;

/** @} */

/***************************************************************************//**
    @addtogroup dec_types Типы данных для декодирования TEDS
    @{
*******************************************************************************/


/** @brief Контекст разбора данных TEDS.

   Данная структура содержит информацию о текущем состоянии разбора данных
   в формате TEDS, включая ссылку на массив данных и текущую позицию разбора.

   Данная структура должна быть проинциализирована с помощью LTEDS_DecodeInit()
   перед началом работы.

   Функции извлечения информации из закодированных TEDS данных принимают данную
   структуру первым параметром, извлекают данные и обновляют текущую позицию разбора.

   Как правило пользователю не требуется обращаться к полям данной
   структуры напрямую, т.к. их изменяют и используют сами функции разбора данных TEDS.
   Однако они могут быть использованы для отладочных целей или
   при написании разбора блока данных в пользовательском формате. */
typedef struct {
    const BYTE *Data; /**< Указатель на начало массива разбираемых TEDS данных. */
    DWORD DataLen; /**< Размер массива Data в байтах. */
    DWORD ProcBitPos; /**< Текущая позиция обработки данных в битах от начала массива. */
    DWORD Flags; /**< Флаги из #e_LTEDS_DATA_FLAGS, управляющие обработкой. */
    DWORD Reserved[5]; /**< Резерв. */
} TLTEDS_DECODE_CONTEXT;

/** @} */

/***************************************************************************//**
    @addtogroup dec_func Функции декодирования TEDS
    @{
*******************************************************************************/

/***************************************************************************//**
    @brief Инициализация контекста разбора данных TEDS

    Данная функция вызывается перед остальными функциями разбора данных TEDS,
    чтобы проинициализровать контекст разбора.

    В ней задается буфер, в котором уже должны находится прочитанные данные TEDS
    преобразователя и флаги обработки.
    Переданный буфер должен оставаться действительным в течение всего времени обработки.

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

    @param[out] ctx     Структура контекста разбора данных TEDS, которая будет проинициализрована.
    @param[in]  data    Массив с данными из TEDS размером в len-байт.
    @param[in]  dataLen Размер массива data в байтах.
    @param[in]  flags   Набор флагов из #e_LTEDS_DATA_FLAGS, управляющих обработкой
                        данных.
    @return             Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_DecodeInit(TLTEDS_DECODE_CONTEXT *ctx, const BYTE *data,
                                      DWORD dataLen, DWORD flags);

/***************************************************************************//**
    @brief Извлечение базовой информации из данных TEDS 

    Данная функция извлекает базовую информацию о преобразователе (Basic TEDS). Эта
    информация должна присутствовать в начале TEDS любого преобразователя.
    Таким образом, эта функция как правило вызывается первой один раз при начале разбора
    данных TEDS.
    @param[in] ctx   Контекст разбора данных TEDS.
    @param[out] info Структура, которая будет заполнена базовой информацией о преобразователе.
    @return          Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetBasicInfo(TLTEDS_DECODE_CONTEXT *ctx, TLTEDS_INFO_BASIC *info);

/***************************************************************************//**
    @brief Извлечение селектора из данных TEDS 

    Данная функция позволяет получить из данных TEDS  селектор, который определяет,
    что за данные идут дальше. Действительные значения селектора определяются
    перечислением #e_LTEDS_SEL_TYPE.

    Данные за базовой информацией хранятся блоками, каждый из которых начинается
    с селектора, определяющего, что за информация хранится в блоке.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[out]  selector Полученный код селектора. Значение из #e_LTEDS_SEL_TYPE.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetSelector(TLTEDS_DECODE_CONTEXT *ctx, BYTE *selector);

/***************************************************************************//**
    @brief Извлечение расширения завершающего селектора из данных TEDS

    Данная функция позволяет получить из данных TEDS расширение завершающего селектора.
    Расширение идет за селектором типа #LTEDS_SEL_END и определяет, в какой форме
    идут оставшиеся данные.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[out]  extsel   Полученный код расширения селектора. Значение из #e_LTEDS_EXTSEL_TYPE.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetEndExtendedSelector(TLTEDS_DECODE_CONTEXT *ctx, BYTE *extsel);



/***************************************************************************//**
    @brief Извлечение идентификатора стандартного шаблона из данных TEDS

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

    Стандартные значения идентификаторов определены перечислением #e_LTEDS_STD_TEMPLATE_ID.

    Идентификатор находится в данных TEDS после селектора типа #LTEDS_SEL_STANDARD.

    Данная функция предполагает, что идентификатор кодируется с помощью 8 бит,
    что справедливо для всех стандартных шаблонов.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[out]  id       Полученный идентификатор шаблона. Значение из #e_LTEDS_STD_TEMPLATE_ID.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetStdTemplateID(TLTEDS_DECODE_CONTEXT *ctx, BYTE *id);


/***************************************************************************//**
    @brief Извлечение идентификатора шаблона производителя из данных TEDS

    Данная функция позволяет получить из данных TEDS идентификатор шаблона,
    связанного с каким-либо производителем, который вместе с идентификатором производителя
    определяет, каким образом закодированы оставшиеся данные  текущего блока.

    В отличие от идентификатора стандартного шаблона, идентификатор шаблона производителя может
    иметь размер отличный от стандартного. Размер определяется идентификатором
    производителя. Данная функция предполагает, что идентификатор шаблона всегда
    укладывается в 32 бита.

    Идентификатор шаблона производителя идет сразу за селектором типа
    #LTEDS_SEL_MANUFACTURER  или за идентификатором производителя после
    селектора типа #LTEDS_SEL_OTHER_MANUFACTURER.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Размер идентификатора в битах для данного производителя.
    @param[out]  id       Полученный идентификатор шаблона.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetManufacturerTemplateID(TLTEDS_DECODE_CONTEXT *ctx,
                                                        DWORD bitsize, DWORD *id);



/***************************************************************************//**
    @brief Извлечение идентификатора производителя из TEDS данных

    Данная функция предназначена для получения из данных TEDS идентификатора
    производителя. Используется при разборе блока данных с селектором
    #LTEDS_SEL_OTHER_MANUFACTURER сразу после чтения селектора, чтобы получить
    информацию, шаблон какого производителя используется для кодирования
    данных блока и определить размер идентификатора шаблона.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[out]  id       Полученный идентификатор производителя.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetManufacturerID(TLTEDS_DECODE_CONTEXT *ctx, WORD *id);


/***************************************************************************//**
    @brief Проверка, является ли значение даты действительным значением

    Функция проверяет, является ли указанная информация о дате, полученной из
    данных TEDS, действительной.

    @param[in]   date     Информация о дате, которую надо проверить.
    @return               TRUE если поля структуры соответствуют действительной дате, 
                                   FALSE --- иначе.
    ****************************************************************************/
LTEDSAPI_DllExport(BOOLEAN) LTEDS_DateIsValid(const TLTEDS_INFO_DATE *date);

/** @} */

/***************************************************************************//**
    @addtogroup dec_func_ll Низкоуровневые функции декодирования базовых типов
    @{
*******************************************************************************/

/***************************************************************************//**
    @brief Извлечение заданного количества бит из данных TEDS

    Данная функция извлекает заданное количество бит, начиная с текущей позиции
    контекста декодирования данных TEDS, и передвигает текущую позицию на количество
    извлеченных бит.

    Биты складываются в выходной массив. Первый извлеченный бит помещается
    в младший разряд байта с младшим адресом переданного массива.

    Данная функция является базовой для реализации всех остальных функций
    декодирования данных TEDS.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое необходимо извлечь из данных TEDS.
    @param[out]  result   Массив, в который будут помещены извлеченные данные.
                          Должен быть размером не менее чем на \f$ (bitsize + 7)/8 \f$ байт.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetBits(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, void *result);


/***************************************************************************//**
    @brief Извлечение информации о дате из данных TEDS

    Данная функция извлекает и разбирает данные TEDS, содержащие дату в виде
    целого числа числа заданного размера, соответствующего количеству дней,
    с #LTEDS_DATE_MIN_YEAR года.

    Функция предназначена для получения значения свойства с типом Date.

    Если свойство имеет значение "не используется", то будет возвращена
    недействительная дата со всеми нулевыми полями.
    Проверить действительность даты можно с помощью функции LTEDS_DateIsValid().

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
    @param[out]  date     Полученное значение даты.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetDate(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, TLTEDS_INFO_DATE *date);

/***************************************************************************//**
    @brief Извлечение целого числа из данных TEDS.

    Данная функция извлекает целое число из данных TEDS.

    Функция предназначена для получения значения свойства с типом UnInt.

    Возвращает значение #LTEDS_UNINT_VAL_NOT_USED, если свойство имеет
    значение "не используется".

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
    @param[out]  val      Полученное значение.
    @return               Код ошибки
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetUnInt(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, DWORD *val);

/***************************************************************************//**
    @brief Извлечение 5-битных символов из данных TEDS

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

    Функция предназначена для получения значения свойства типа Chr5.
    Количество символов определяется по размеру, который занимает значение в
    данных TEDS.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
                          Должно быть кратно 5.
    @param[out]  str      Массив, в которой сохраняется прочитанная ASCII строка
                          с завершающим нулевым символом. Должен содержать места
                          не менее чем на \f$ bitsize/5 + 1 \f$ байт.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetChr5(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, CHAR *str);

/***************************************************************************//**
    @brief Извлечение 7-битных ASCII символов из данных TEDS

    Данная функция извлекает фиксированное количество ASCII-символов из данных TEDS,
    и сохраняет их в виде ASCII строки, добавляя завершающий нулевой символ.

    Функция предназначена для получения значения свойства типа ASCII.
    Количество символов определяется по размеру, который занимает значение в
    данных TEDS.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
                          Должно быть кратно 7.
    @param[out]  str      Массив, в которой сохраняется прочитанная ASCII строка
                          с завершающим нулевым символом. Должен содержать места
                          не менее чем на \f$ bitsize/5 + 1 \f$ байт.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetASCII(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, CHAR *str);



/***************************************************************************//**
    @brief Извлечение  вещественного числа с плавающей точкой из данных TEDS

    Данная функция извлекает из данных TEDS вещественное число, закодированное
    в виде числа с плавающей запятой в 32-битном формате..

    Предназначена для получения значения свойства типа SINGLE.

    @param[in]  ctx   Контекст разбора данных TEDS.
    @param[out] val   Полученное число.
    @return           Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetSingle(TLTEDS_DECODE_CONTEXT *ctx, double *val);

/***************************************************************************//**
    @brief Извлечение  вещественного числа с постоянным разрешением из данных TEDS

    Данная функция извлекает из данных TEDS вещественное число, закодированное
    целым числом с линейным соответствием кода и результата на заданном интервале.
    Результат равен \f$ start\_value + tolerance * teds\_value \f$,
    где teds_value --- извлеченное целое число из данных TEDS,
    а start_value и tolerance явно передаются и соответствуют значениям, заданным
    в описании шаблона.

    Функция возвращает значение NAN, если обнаружен код, соответствующий
    недействительному значению.

    Функция предназначена для получения значения свойства с типом ConRes.

    @param[in]  ctx         Контекст разбора данных TEDS.
    @param[in]  bitsize     Количество бит, которое занимает значение в TEDS.
    @param[in]  start_value Начало интервала, к которому приводится результат.
    @param[in]  tolerance   Шаг изменения результирующего значения.
    @param[out] val         Полученное число.
    @return                 Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetConRes(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize,
                                        double start_value, double tolerance, double *val);


/***************************************************************************//**
    @brief Извлечение вещественного числа с относительным разрешением из данных TEDS

    Данная функция извлекает из данных TEDS  вещественное число, закодированное
    целым числом с логарифмическим соответствием кода и результата на заданном
    интервале.
    Результат равен \f$ start\_value * (1 + 2*tolerance)^{teds\_value} \f$,
    где teds_value --- извлеченное целое число из данных TEDS, а start_value и tolerance
    явно передаются и соответствуют значениям, заданным в описании шаблона.

    Функция возвращает значение NAN, если обнаружен код, соответствующий
    недействительному значению.

    Функция предназначена для получения значения свойства с типом ConRelRes.

    @param[in]  ctx         Контекст разбора данных TEDS.
    @param[in]  bitsize     Количество бит, которое занимает значение в TEDS.
    @param[in]  start_value Начало интервала, к которому приводится результат.
    @param[in]  tolerance   Шаг изменения результирующего значения в логарифмическом 
                                                  масштабе..
    @param[out] val         Полученное число.
    @return                 Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetConRelRes(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize,
                                            double start_value, double tolerance, double *val);



/***************************************************************************//**
    @brief Извлечение значения перечисления из данных TEDS

    Данная функция извлекает из данных TEDS целое число, соответствующее
    значению перечисления.

    Функция предназначена для получения значения свойства с типом Enum.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
    @param[out]  val      Полученное значение.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetEnumVal(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, DWORD *val);


/***************************************************************************//**
    @brief Извлечение кода, определяющего вариант ветвления, из данных TEDS

    Данная функция извлекает из данных TEDS целое число, соответствующее
    коду выбора варианта обработки шаблона из конструкции SelectCase.

    @param[in]   ctx      Контекст разбора данных TEDS
    @param[in]   bitsize  Количество бит, которое занимает значение.
    @param[out]  val      Полученный код выбора варианта ветвления.
    @return               Код ошибки
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetSelectCase(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, DWORD *val);

/***************************************************************************//**
    @brief Извлечение размера массива из данных TEDS

    Данная функция извлекает из данных TEDS целое число, соответствующее
    размеру массива, соответствующего конструкции StructArray.

    @param[in]   ctx      Контекст разбора данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение.
    @param[out]  val      Полученный размер массива.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_GetStructArraySize(TLTEDS_DECODE_CONTEXT *ctx, DWORD bitsize, DWORD *val);

/***************************************************************************//**
    @brief Проверка контрольной суммы блока данных TEDS

    Данная функция проверяет контрольную сумму в блоке данных TEDS, который
    начинается с указанного байта от начала массива и занимает
    #LTEDS_CHECKSUM_BLOCK_LEN байт. Первый байт этого блока должен быть равен
    сумме остальных.

    Данная функция автоматически вызывается функциями разбора данных TEDS при вызове
    LTEDS_GetBits() в случае перехода границы блока, если в контексте разбора
    был указан флаг #LTEDS_DATA_FLAG_HAS_CHECKSUM, поэтому как правило не требует
    явного вызова.

    Сама функция не обновляет текущей позиции в контексте.

    @param[in]  ctx            Контекст разбора данных TEDS
    @param[in]  start_bytepos  Позиция начала проверяемого блока в байтах
                               от начала данных TEDS .
    @return                    Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_CheckBlockSum(TLTEDS_DECODE_CONTEXT *ctx, DWORD start_bytepos);

/** @} */




/***************************************************************************//**
    @addtogroup enc_types Типы для кодирования данных TEDS
    @{
*******************************************************************************/

/** @brief Контекст кодирования данных TEDS.

   Данная структура содержит информацию о текущем состоянии кодирования данных
   в формат TEDS, включая ссылку на массив данных и текущую позицию записи..

   Данная структура должна быть проинциализирована с помощью LTEDS_EncodeInit()
   перед началом работы.

   Функции кодирования данных в TEDS принимают данную структуру первым параметром,
   сохраняют переданные значения в массив данных TEDS, начиная с текущей позиции записи
   и обновляют текущую позицию.

   Как правило пользователю не требуется обращаться к полям данной
   структуры напрямую, т.к. их изменяют и используют сами функции кодирования.
  Однако они могут быть использованы для отладочных целей или
   при написании кодирования блока данных в пользовательском формате.  */
typedef struct {
    BYTE *Data; /**< Указатель на начало массива, в который будут сохранены данные TEDS */
    DWORD DataLen; /**< Размер массива Data в байтах */
    DWORD ProcBitPos; /**< Текущая позиция записи данных в битах от начала массива */
    DWORD Flags; /**< Флаги из #e_LTEDS_DATA_FLAGS, управляющие обработкой. */
    DWORD Reserved[5]; /**< Резерв */
} TLTEDS_ENCODE_CONTEXT;
/** @} */


/***************************************************************************//**
    @addtogroup enc_func Функции кодирования данных TEDS
    @{
*******************************************************************************/


/***************************************************************************//**
    @brief Инициализация контекста кодирования данных TEDS

    Данная функция вызывается перед остальными функциями кодирования данных TEDS,
    чтобы проинициализровать контекст.

    В ней задается уже выделенный буфер для сохранения данных в формате TEDS, его
    размер и флаги.
    Переданный буфер должен оставаться действительным в течение всего времени
    кодирования данных.

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

    @param[out] ctx     Структура контекста кодирования данных TEDS,
                        которая должна быть проинициализрована.
    @param[in]  data    Массив для сохранения данных TEDS.
    @param[in]  dataLen Размер массива data в байтах.
    @param[in]  flags   Набор флагов из #e_LTEDS_DATA_FLAGS, управляющих обработкой
                        данных. В текущей версии нет поддерживаемых флагов для
                        кодирования.
    @return             Код ошибки
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_EncodeInit(TLTEDS_ENCODE_CONTEXT *ctx, BYTE *data, DWORD dataLen, DWORD flags);



/***************************************************************************//**
    @brief Запись базовой информации в данные TEDS

    Данная функция записывает базовую информацию о преобразователе (Basic TEDS) в 
    данные TEDS. 
    
    Эта   информация должна присутствовать в начале данных TEDS любого преобразователя.
    Таким образом, эта функция как правило вызывается первой один раз при начале
    кодирования данных TEDS.

    @param[in] ctx   Контекст кодирования данных TEDS.
    @param[in] info  Структура с базовой информацией о преобразователе.
    @return          Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutBasicInfo(TLTEDS_ENCODE_CONTEXT *ctx,
                                           const TLTEDS_INFO_BASIC *info);



/***************************************************************************//**
    @brief Запись селектора в данные TEDS.

    Функция используется в тех же случаях, что и LTEDS_GetSelector() при разборе.

    @param[in]  ctx      Контекст кодирования данных TEDS.
    @param[in]  selector Записываемый код селектора. Значение из #e_LTEDS_SEL_TYPE.
    @return              Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutSelector(TLTEDS_ENCODE_CONTEXT *ctx, BYTE selector);

/***************************************************************************//**
    @brief Запись расширения завершающего селектора  в TEDS данные.

    Функция используется в тех же случаях, что и LTEDS_GetEndExtendedSelector() при разборе.

    @param[in]   ctx      Контекст кодирования данных TEDS
    @param[in]   extsel   Записываемый код расширения селектора. Значение из #e_LTEDS_EXTSEL_TYPE.
    @return               Код ошибки
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutEndExtendedSelector(TLTEDS_ENCODE_CONTEXT *ctx, BYTE extsel);


/***************************************************************************//**
    @brief Запись идентификатора стандартного шаблона в данные TEDS

    Функция используется в тех же случаях, что и LTEDS_GetStdTemplateID() при разборе.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   id       Записываемый идентификатор шаблона. Значение из #e_LTEDS_STD_TEMPLATE_ID.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutStdTemplateID(TLTEDS_ENCODE_CONTEXT *ctx, BYTE id);


/***************************************************************************//**
    @brief Запись идентификатора шаблона производителя в данные TEDS

    Функция используется в тех же случаях, что и LTEDS_GetManufacturerTemplateID()
    при разборе.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   bitsize  Размер идентификатора в битах для данного производителя.
    @param[in]   id       Записываемый идентификатор шаблона.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutManufacturerTemplateID(TLTEDS_ENCODE_CONTEXT *ctx,
                                                        DWORD bitsize, DWORD id);


/***************************************************************************//**
    @brief Запись идентификатора производителя в данные TEDS

    Данная функция предназначена для записи в TEDS данных идентификатора
    производителя. Используется в тех же случаях, что и LTEDS_GetManufacturerID()
    при разборе данных.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   id       Записываемый идентификатор производителя.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutManufacturerID(TLTEDS_ENCODE_CONTEXT *ctx, WORD id);


/** @} */

/***************************************************************************//**
    @addtogroup enc_func_ll Низкоуровневые функции кодирования базовых типов
    @{
*******************************************************************************/

/***************************************************************************//**
    @brief Запись заданного количества бит в данные TEDS

    Данная функция записывает заданное количество бит, начиная с текущей позиции
    контекста кодирования данных TEDS и передвигает данную позицию на
    записанное количество бит.

    Биты извлекаются из входного массива начиная с младшего бита байта с младшим
    адресом.

    Данная функция является базовой для реализации всех остальных функций
    записи данных TEDS.

    @param[in] ctx      Контекст кодирования данных TEDS.
    @param[in] bitsize  Количество бит, которое необходимо записать в данные TEDS.
    @param[in] val      Массив с данными, которые должны быть записаны в TEDS.
                        Должен содержать не менее \f$ (bitsize + 7)/8 \f$ байт.
    @return             Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutBits(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, const void *val);

/***************************************************************************//**
    @brief Запись информации о дате в данные TEDS

    Данная функция записывает данные о дате в TEDS в виде целого числа заданного
    размера, содержащего количество дней  с начала #LTEDS_DATE_MIN_YEAR года.

    Функция предназначена для записи значений свойств с типом Date.

    Передача даты с нулевыми значениями всех полей означает, что свойство не используется,
    и будет записан соответствующий код в TEDS.

    @param[in] ctx      Контекст кодирования данных TEDS.
    @param[in] bitsize  Количество бит, которое занимает значение в TEDS.
    @param[in] date     Записываемое значение даты.
    @return             Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutDate(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize,  const TLTEDS_INFO_DATE *date);

/***************************************************************************//**
    @brief Запись целого числа в данные TEDS

    Данная функция записывает целое число в данные TEDS.

    Функция предназначена для записи значения свойства с типом UnInt.

    При передаче значения #LTEDS_UNINT_VAL_NOT_USED в поле записывается код,
    указывающий, что свойство не используется.

    @param[in]  ctx      Контекст кодирования данных TEDS.
    @param[in]  bitsize  Количество бит, которое занимает значение в TEDS.
    @param[in]  val      Значение для записи.
    @return              Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutUnInt(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, DWORD val);

/***************************************************************************//**
    @brief Запись строки из 5-битных символов в данные TEDS

    Данная функция помещает фиксированное количество символов из входной строки
    в TEDS данные в виде закодированных специальным пятибитным кодом символов.
    На вход передается ASCII-строка минимум из требуемого количества символов,
    которая может содержать только заглавные английские буквы ('A' - 'Z'), пробел или
    символы , . / _ \@.

    В случае, если во входной строке обнаружен символ с кодом 0 до записи всех
    указанных символов, анализ входной строки прекращается и поле до указанного
    размера будет заполнено пробелами.

    Функция предназначена для записи значения свойства типа Chr5.
    Количество символов определяется по размеру, который занимает значение в
    данных TEDS.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
                          Должно быть кратно 5.
    @param[in]   str      Массив из \f$ bitsize/5 \f$ ASCII символов из допустимого
                          набора, которые должны быть записаны в TEDS данные.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutChr5(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, const CHAR *str);

/***************************************************************************//**
    @brief Запись строки из ASCII-символов  в данные TEDS

    Данная функция помещает фиксированное количество ASCII-символов из входной строки
    в TEDS данные. Входная строка может содержать только символы с 7-битными кодами
    (0-127).

    В случае, если во входной строке обнаружен символ с кодом 0 до записи всех
    указанных символов, анализ входной строки прекращается и поле до указанного
    размера будет заполнено нулевыми символами.

    Функция предназначена для записи значения свойства типа ASCII.
    Количество символов определяется по размеру, который занимает значение в
    данных TEDS.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
                          Должно быть кратно 7.
    @param[in]   str      Массив из \f$ bitsize/7 \f$ ASCII символов и, которые
                          должны быть записаны в TEDS данные.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutASCII(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, const CHAR *str);
/***************************************************************************//**
    @brief Запись вещественного числа с плавающей точкой в данные TEDS

    Данная функция помещает в данные TEDS вещественное число, закодированное
    в виде числа с плавающей запятой в 32-битном формате.

    Функция предназначена для записи значения свойства типа SINGLE.

    @param[in]  ctx   Контекст кодирования данных TEDS.
    @param[in]  val   Записываемое число.
    @return           Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutSingle(TLTEDS_ENCODE_CONTEXT *ctx, double val);

/***************************************************************************//**
    @brief Запись вещественного числа с постоянным разрешением  в данные TEDS

    Данная функция записывает в TEDS вещественное число, закодированное
    целым числом с линейным соответствием кода и результата на заданном интервале,
    как указано в описании функции LTEDS_GetConRes().

    Функция предназначена для записи значения свойства типа ConRes.

    @param[in]  ctx         Контекст кодирования данных TEDS.
    @param[in]  bitsize     Количество бит, которое занимает значение в TEDS.
    @param[in]  start_value Начало интервала кодируемого значения.
    @param[in]  tolerance   Шаг изменения кодируемого значения.
    @param[in]  val         Записываемое значение.
    @return                 Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutConRes(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize,
                                        double start_value, double tolerance, double val);

/***************************************************************************//**
    @brief Запись вещественного числа с относительным разрешением в данные TEDS

    Данная функция записывает в TEDS вещественное число, закодированное
    целым числом с логарифмическим соответствием кода и результата на заданном
    интервале, как указано в описании функции LTEDS_GetConRelRes().

    Функция предназначена для записи значения свойства с типом ConRelRes.

    @param[in]  ctx         Контекст кодирования данных TEDS.
    @param[in]  bitsize     Количество бит, которое занимает значение в TEDS.
    @param[in]  start_value Начало интервала кодируемого значения.
    @param[in]  tolerance   Шаг изменения кодируемого значения в логарифмическом
                                                  масштабе.
    @param[in]  val         Записываемое значение.
    @return                 Код ошибки
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutConRelRes(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize,
                                            double start_value, double tolerance, double val);


/***************************************************************************//**
    @brief Запись  значения перечисления в данные TEDS

    Данная функция записывает в данные TEDS целое число заданного размера,
    соответствующее значению перечисления.

    Функция предназначена для записи значения свойства с типом Enum.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение в TEDS.
    @param[in]   val      Записываемое значение.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutEnumVal(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, DWORD val);


/***************************************************************************//**
    @brief Запись кода, определяющего вариант ветвления,  в данные TEDS

    Данная функция записывает в данные TEDS целое число заданного размера,
    соответствующее коду варианта обработки шаблона из конструкции SelectCase.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение.
    @param[in]   val      Записываемый код выбора варианта ветвления.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutSelectCase(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, DWORD val);

/***************************************************************************//**
    @brief Запись  размера массива в данные TEDS.

    Данная функция записывает в данные TEDS целое число, соответствующее
    размеру массива для конструкции StructArray.

    @param[in]   ctx      Контекст кодирования данных TEDS.
    @param[in]   bitsize  Количество бит, которое занимает значение.
    @param[in]   val      Записываемый размер массива.
    @return               Код ошибки.
    ****************************************************************************/
LTEDSAPI_DllExport(INT) LTEDS_PutStructArraySize(TLTEDS_ENCODE_CONTEXT *ctx, DWORD bitsize, DWORD val);

/** @} */


/***************************************************************************//**
    @addtogroup func_misc Функции вспомогательного характера
    @{
*******************************************************************************/

/***************************************************************************//**
   @brief Получение сообщения об ошибке.

   Функция возвращает строку, соответствующую переданному коду ошибки из #e_LTEDS_ERRORS
   в кодировке CP1251 для ОС Windows или UTF-8 для ОС Linux.

   @param[in] err       Код ошибки.
   @return              Указатель на строку, содержащую сообщение об ошибке.
 ******************************************************************************/
LTEDSAPI_DllExport(LPCSTR) LTEDS_GetErrorString(INT err);

/** @} */

#pragma pack()

#ifdef __cplusplus
}
#endif

#endif                      /* #ifndef LTEDSAPI_H_ */

