Обработка пакета

#include < stdio.h >
#include < stdlib.h >
#include "decimals.h"
#include "inter.h"
#include "tick.h"
#include "exlib.h"

extern L_BYTE* MakeCHARValue(int, int, L_BYTE*); // Генерирует значение

#define MAX_BUF_LEN 2048

L_BYTE *fillCharBuffer(L_WORD Len, L_WORD typ, L_BYTE *outAdr, L_WORD *outSize)
{
  L_WORD curLen = Len;
  L_BYTE curValue[64] = {0};  // Буфер под самое длинное значение
  L_BYTE *pcurValue = MakeCHARValue(typ, Len, curValue);

  if (pcurValue == NULL) // Указывает, что это NULL-значение
  {
    curLen = -1; // При NULL-значении  пишем только длину, равную -1
    memcpy(outAdr, &curLen, sizeof(curLen));
    outAdr += sizeof(curLen);
    *outSize += sizeof(curLen);
    return outAdr;
  }

  if (typ == DT_VARCHAR || typ == DT_VARBYTE || typ == DT_NVARCHAR)
  {
    if (typ == DT_NVARCHAR)
      curLen = wcslen((wchar_t *)pcurValue) * sizeof(wchar_t);
    else
      curLen = strlen((const char*)pcurValue);
  }

  if (typ == DT_REAL || typ == DT_DECIMAL || typ == DT_DATE ||
      typ == DT_BOOL || typ == DT_EXTFILE)
    curLen = strlen((const char*)pcurValue);

  memcpy(outAdr, &curLen, sizeof(curLen));
  outAdr += sizeof(curLen);
  *outSize += sizeof(curLen);

  memcpy(outAdr, pcurValue, curLen);
  outAdr += curLen;
  *outSize += curLen;
  return outAdr;
} // fillCharBuffer

int main()
{
  TCBL CBLconnect = {0};
  L_CHAR Name_Pass[] = "SYSTEM/MANAGER8";
  L_CHAR Node[] = "    ";
  L_WORD Priority = 0;
  L_LONG PrzExe = M_EXCLUSIVE | Q_ENCODE | M_BINARY;
  L_LONG Err = NORMAL;
  L_CHAR Query[] = "select * from test;";

  L_LONG i;
  L_WORD curSize = sizeof(L_WORD);
  L_BYTE Buf[MAX_BUF_LEN];

  L_WORD recCnt = 2; // Число записей в одной порции пакета
  L_WORD ColumnCount; // Число столбцов в выборке данных
  GETA_OUT* ansDesc = NULL; // Описатель столбцов выборки данных
  L_BYTE PackBuf[MAX_BUF_LEN] = {0}; // Буфер для размещения добавляемой порции пакета
  L_BYTE *CurAdr = PackBuf + sizeof(recCnt);

  *((L_WORD *)PackBuf) = recCnt; // Первым пишем число записей в порции пакета

  Err = LinterOPEN(&CBLconnect, Name_Pass, Node, Priority, PrzExe);
  if (Err != NORMAL)
    PrintError(&CBLconnect); /* Если ошибка, то всегда exit(1)! */
  printf("Connect to RDBMS Linter\n");

  // Создадим таблицу с использованием всех типов данных СУБД ЛИНТЕР:
  Err = LinterNotSelect(
    &CBLconnect,
    "create or replace table TEST(INT_COLUMN int,"
                      "SMALLINT_COLUMN smallint,"
                      "BIGINT_COLUMN bigint,"
                      "CHAR_COLUMN char(5),"
                      "VARCHAR_COLUMN varchar(10),"
                      "BYTE_COLUMN byte(4),"
                      "VARBYTE_COLUMN varbyte(5),"
                      "NCHAR_COLUMN nchar(5),"
                      "NCHAR_VARYING_COLUMN nchar varying(10),"
                      "DATE_COLUMN date,"
                      "REAL_COLUMN real,"
                      "DOUBLE_COLUMN Double,"
                      "DEC_COLUMN decimal,"
                      "BOOL_COLUMN boolean,"
                      "EXTFILE_COLUMN extfile);");
  if (Err != NORMAL)
    PrintError(&CBLconnect);

  Err = LinterSLCT(&CBLconnect, PrzExe, Query, Buf, sizeof(Buf), NULL);
  Err = LinterAnsColNum(&CBLconnect, &ColumnCount);
  if (Err != NORMAL)
    PrintError(&CBLconnect);

  ansDesc = (GETA_OUT*)calloc(ColumnCount, sizeof(GETA_OUT));
  if (ansDesc == NULL)
  {
    printf("Error: not memory\n"); exit(1);
  }

  // Получаем полные описания столбцов, но нам потребуется только тип и длина:
  Err = LinterGETA(&CBLconnect, 0, ansDesc, ColumnCount*sizeof(GETA_OUT));
  if (Err != NORMAL)
    PrintError(&CBLconnect);

  for (i = 0; i <  ColumnCount; i++)
    CurAdr = fillCharBuffer(ansDesc[i].Length, ansDesc[i].Type, CurAdr, &curSize);
  for (i = 0; i <  ColumnCount; i++)
    CurAdr = fillCharBuffer(ansDesc[i].Length, ansDesc[i].Type, CurAdr, &curSize);

  printf("PUTM AS CHAR");
  Err = LinterNotSelect(
    &CBLconnect,
    "start append into TEST char(INT_COLUMN, SMALLINT_COLUMN, BIGINT_COLUMN, "
                                "CHAR_COLUMN, VARCHAR_COLUMN, "
                                "BYTE_COLUMN, VARBYTE_COLUMN, "
                                "NCHAR_COLUMN, NCHAR_VARYING_COLUMN, "
                                "DATE_COLUMN, "
                                "REAL_COLUMN, DOUBLE_COLUMN, DEC_COLUMN, "
                                "BOOL_COLUMN, "
                                "EXTFILE_COLUMN);");
  if (Err != NORMAL)
    PrintError(&CBLconnect);

  Err = LinterPUTM(&CBLconnect, PackBuf, curSize);
  if (Err != NORMAL)
    PrintError(&CBLconnect);

  if (LinterNotSelect(&CBLconnect, "end append into TEST;") != NORMAL)
    PrintError(&CBLconnect);
  printf(" - OK\n");
  free(ansDesc);
  Err = LinterCLOS(&CBLconnect);
  if (Err != NORMAL)
    PrintError(&CBLconnect);
  return 0;
} // Main