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

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

extern L_BYTE *MakeBYTEValue(int, int, L_BYTE*); // Генерирует байтовый вид
 значения

#define MAX_BUF_LEN 2048
#define FILTER_DESC_LEN 10

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

  if (pcurValue == NULL) // Указывает, что это NULL-значение
  {
    totalLength = -1; // При NULL-значении пишем только длину, равную -1
    memcpy(outAdr, &totalLength, sizeof(totalLength));
    outAdr += sizeof(totalLength);
    *outSize += sizeof(totalLength);
    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);

    totalLength = curLen + sizeof(L_WORD); // Длина с учетом поля длины
    memcpy(outAdr, &totalLength, sizeof(totalLength));
    outAdr += sizeof(totalLength);
    *outSize += sizeof(totalLength);
  }

  if (typ == DT_EXTFILE)
  {
    curLen = strlen((const char*)pcurValue);

    totalLength = FILTER_DESC_LEN + 512;
    memcpy(outAdr, &totalLength, sizeof(totalLength));
    outAdr += sizeof(totalLength);
    *outSize += sizeof(totalLength);

    memset(outAdr, 0 , totalLength);
    outAdr += FILTER_DESC_LEN;
    *outSize += FILTER_DESC_LEN;

    memcpy(outAdr, pcurValue, curLen);
    outAdr += 512;
    *outSize += 512;
  }
  else
  {
    memcpy(outAdr, &curLen, sizeof(curLen));
    outAdr += sizeof(curLen);
    *outSize += sizeof(curLen);

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

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 = fillByteBuffer(ansDesc[i].Length, ansDesc[i].Type, CurAdr,
 &curSize);
  for (i = 0; i <  ColumnCount; i++)
    CurAdr = fillByteBuffer(ansDesc[i].Length, ansDesc[i].Type, CurAdr,
 &curSize);

  printf("PUTM AS BYTE");
  Err = LinterNotSelect(
    &CBLconnect,
    "start append into TEST byte(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