📄 isaclient.cpp
字号:
// ISAClient.cpp: implementation of the ISAClient class.
//
//////////////////////////////////////////////////////////////////////
#include <SQLAPI.h>
#include "ISAClient.h"
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h> // memcpy
#include "errmsg.h"
#define SA_Align16(x) (((x+15) >> 4) << 4)
//////////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////////
// Character sets conversion helpers
// returns number of chars written
int SAMultiByteToWideChar(
wchar_t *pchDataTgt,
const char *lpch, int nLength)
{
wchar_t *pchData = pchDataTgt;
const char *mbchar = lpch;
size_t count = (size_t)nLength;
while(count > 0)
{
int nLen = mbtowc(pchData, mbchar, count);
if(nLen == -1) // object that mbchar points to does not form a valid multibyte character within the first count characters
break; // stop conversion
if(nLen == 0) // mbchar is NULL or the object that it points to is a null character
{
// 1 = length of multi-byte '\0'
++mbchar;
--count;
}
else
{
// nLen = length of last multi-byte character
mbchar += nLen;
count -= nLen;
}
++pchData;
}
return pchData - pchDataTgt;
}
// returns number of chars written
// if pchDataTgt is NULL, function simply counts
int SAWideCharToMultiByte(
char *pchDataTgt,
const wchar_t *lpch, int nLength)
{
int nWritten = 0;
for(int i = 0; i < nLength; ++i)
{
int nLen;
if(pchDataTgt)
nLen = wctomb(pchDataTgt + nWritten, lpch[i]);
else
{
char sTemp[128];
nLen = wctomb(sTemp, lpch[i]);
}
if(nLen == -1) // the conversion is not possible in the current locale
{
if(pchDataTgt)
pchDataTgt[nWritten] = '?';
++nWritten;
}
else
nWritten += nLen;
}
return nWritten;
}
//////////////////////////////////////////////////////////////////////
// ISAClient Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ISAClient::ISAClient()
{
}
ISAClient::~ISAClient()
{
}
//////////////////////////////////////////////////////////////////////
// ISAConnection Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ISAConnection::ISAConnection(SAConnection *pSAConnection) :
m_pSAConnection(pSAConnection)
{
}
ISAConnection::~ISAConnection()
{
}
SAConnection *ISAConnection::getSAConnection()
{
return m_pSAConnection;
}
void ISAConnection::EnumCursors(EnumCursors_t fn, void *pAddlData)
{
if(!m_pSAConnection)
return;
m_pSAConnection->EnumCursors(fn, pAddlData);
}
//////////////////////////////////////////////////////////////////////
// ISACursor Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ISACursor::ISACursor(
ISAConnection *pISAConnection,
SACommand *pCommand) :
m_pISAConnection(pISAConnection),
m_pCommand(pCommand)
{
m_pParamBuffer = NULL;
m_nParamIndSize = 0;
m_nParamSizeSize = 0;
m_pSelectBuffer = NULL;
m_nIndSize = 0;
m_nSizeSize = 0;
m_nBulkReadingBufSize = 0;
}
/*virtual */
ISACursor::~ISACursor()
{
if(m_pParamBuffer)
free(m_pParamBuffer);
if(m_pSelectBuffer)
free(m_pSelectBuffer);
}
/*virtual */
unsigned int ISACursor::InputBufferSize(
const SAParam &Param) const
{
assert(Param.ParamDirType() == SA_ParamInput
|| Param.ParamDirType() == SA_ParamInputOutput);
if(Param.isNull())
return 0;
switch(Param.DataType())
{
case SA_dtUnknown:
throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_PARAMETER_TYPE, (const SAChar*)Param.Name());
case SA_dtBool:
assert(false); // sould be overloaded
break;
case SA_dtShort:
return sizeof(short);
case SA_dtLong:
return sizeof(long);
case SA_dtDouble:
return sizeof(double);
case SA_dtDateTime:
assert(false); // sould be overloaded
return 0;
case SA_dtString:
// defualt implementation:
// 1) no space for '\0' is reserved
// 2) always returns size in single characters (converts to multi-byte under Unicode)
// So, under Unicode this should be overloaded
// by clients that bind Unicode strings directly
// without converting them to multi-byte before binding
return Param.asString().GetMultiByteCharsLength();
case SA_dtBytes:
// in bytes, not characters
return Param.asBytes().GetBinaryLength();
case SA_dtLongBinary:
case SA_dtLongChar:
case SA_dtBLob:
case SA_dtCLob:
assert(false); // sould be overloaded
return 0;
case SA_dtCursor:
assert(false); // sould be overloaded
return 0;
default:
assert(false); // unknown type
}
return 0;
}
// align all members to 16-byte boundary
// it will speed up data access on Intel
// and it is very important on RISK
// platforms (like SPARC Solaris) to avoid non-aligment
void ISACursor::AllocBindBuffer(
unsigned int nIndSize,
unsigned int nSizeSize)
{
m_nParamIndSize = nIndSize;
m_nParamSizeSize = nSizeSize;
unsigned int nAllocatedSize = 0;
int cParamCount = m_pCommand->ParamCount();
for(int iParam = 0; iParam < cParamCount; ++iParam)
{
SAParam &Param = m_pCommand->ParamByIndex(iParam);
unsigned int nCurParamSize = 0;
nCurParamSize += SA_Align16(sizeof(unsigned int)); // space allocated for data
nCurParamSize += SA_Align16(nIndSize); // null indicator
nCurParamSize += SA_Align16(nSizeSize); // space for returned size
unsigned int nDataSize;
switch(Param.ParamDirType())
{
case SA_ParamInput:
nDataSize = InputBufferSize(Param);
break;
case SA_ParamInputOutput:
nDataSize = sa_max(InputBufferSize(Param), OutputBufferSize(Param.ParamType(), Param.ParamSize()));
break;
case SA_ParamOutput:
case SA_ParamReturn:
nDataSize = OutputBufferSize(Param.ParamType(), Param.ParamSize());
break;
default:
nDataSize = 0;
assert(false);
}
nCurParamSize += SA_Align16(nDataSize);
m_pParamBuffer = realloc(
m_pParamBuffer,
nAllocatedSize + nCurParamSize);
*(unsigned int*)((char*)m_pParamBuffer + nAllocatedSize) = nDataSize;
nAllocatedSize += nCurParamSize;
}
}
// align all members to 16-byte boundary
// it will speed up data access on Intel
// and it is very important on RISK
// platforms (like Sun SPARC) to avoid non-aligment
void ISACursor::AllocBindBuffer(
int nPlaceHolderCount,
saPlaceHolder **ppPlaceHolders,
unsigned int nIndSize,
unsigned int nSizeSize,
unsigned int nAddlSize,
void **ppAddl)
{
m_nParamIndSize = nIndSize;
m_nParamSizeSize = nSizeSize;
unsigned int nAllocatedSize = 0;
for(int i = 0; i < nPlaceHolderCount; ++i)
{
SAParam &Param = *ppPlaceHolders[i]->getParam();
unsigned int nCurParamSize = 0;
nCurParamSize += SA_Align16(sizeof(unsigned int)); // space allocated for data
nCurParamSize += SA_Align16(nIndSize); // null indicator
nCurParamSize += SA_Align16(nSizeSize); // space for returned size
unsigned int nDataSize;
switch(Param.ParamDirType())
{
case SA_ParamInput:
nDataSize = InputBufferSize(Param);
break;
case SA_ParamInputOutput:
nDataSize = sa_max(InputBufferSize(Param), OutputBufferSize(Param.ParamType(), Param.ParamSize()));
break;
case SA_ParamOutput:
case SA_ParamReturn:
nDataSize = OutputBufferSize(Param.ParamType(), Param.ParamSize());
break;
default:
nDataSize = 0;
assert(false);
}
nCurParamSize += SA_Align16(nDataSize);
m_pParamBuffer = ::realloc(
m_pParamBuffer,
nAllocatedSize + nCurParamSize);
*(unsigned int*)((char*)m_pParamBuffer + nAllocatedSize) = nDataSize;
nAllocatedSize += nCurParamSize;
}
// allocate additional block as requested by caller
if(nAddlSize)
m_pParamBuffer = ::realloc(
m_pParamBuffer,
nAllocatedSize + SA_Align16(nAddlSize));
if(ppAddl)
*ppAddl = (char*)m_pParamBuffer + nAllocatedSize;
}
/*virtual */
unsigned int ISACursor::OutputBufferSize(
SADataType_t eDataType,
unsigned int nDataSize) const
{
switch(eDataType)
{
case SA_dtUnknown:
throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_DATA_TYPE);
case SA_dtBool:
assert(false); // sould be overloaded
return 0;
case SA_dtShort:
return sizeof(short);
case SA_dtLong:
return sizeof(long);
case SA_dtDouble:
return sizeof(double);
case SA_dtDateTime:
assert(false); // sould be overloaded
return 0;
case SA_dtBytes:
return nDataSize;
case SA_dtString:
// No space for '\0' is reserved.
// nDataSize is always (under Unicode or multi-byte builds)
// assumed to be in bytes, not characters.
// If above is not true, client should overload.
return nDataSize;
case SA_dtLongBinary:
case SA_dtLongChar:
case SA_dtBLob:
case SA_dtCLob:
assert(false); // sould be overloaded
return 0;
case SA_dtCursor:
assert(false); // sould be overloaded
return 0;
default:
assert(false); // unknown type
}
return 0;
}
// align all members to 16-byte boundary
// it will speed up data access on Intel
// and it is very important on RISK
// platforms (like Sun SPARC) to avoid non-aligment
void ISACursor::AllocSelectBuffer(
unsigned int nIndSize,
unsigned int nSizeSize,
int nBulkReadingBufSize)
{
m_nIndSize = nIndSize;
m_nSizeSize = nSizeSize;
m_nBulkReadingBufSize = nBulkReadingBufSize;
unsigned int nAllocatedSize = 0;
int cFieldCount = m_pCommand->FieldCount();
int iField;
for(iField = 1; iField <= cFieldCount; ++iField)
{
SAField &Field = m_pCommand->Field(iField);
unsigned int nCurFieldSize = 0;
nCurFieldSize += SA_Align16(sizeof(unsigned int)); // space allocated for data
nCurFieldSize += SA_Align16(nIndSize * nBulkReadingBufSize); // null indicator
nCurFieldSize += SA_Align16(nSizeSize * nBulkReadingBufSize); // space for returned size
unsigned int nDataSize = OutputBufferSize(
Field.FieldType(),
Field.FieldSize());
nCurFieldSize += SA_Align16(nDataSize * nBulkReadingBufSize);
m_pSelectBuffer = ::realloc(
m_pSelectBuffer,
nAllocatedSize + nCurFieldSize);
*(unsigned int*)((char*)m_pSelectBuffer + nAllocatedSize) = nDataSize;
nAllocatedSize += nCurFieldSize;
}
void *pBuf = m_pSelectBuffer;
for(iField = 1; iField <= cFieldCount; ++iField)
{
void *pInd;
void *pSize;
void *pValue;
unsigned int nDataBufSize;
IncFieldBuffer(pBuf, pInd, pSize, nDataBufSize, pValue);
SetFieldBuffer(
iField,
pInd, nIndSize,
pSize, nSizeSize,
pValue, nDataBufSize);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -