mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
8.1 KiB
344 lines
8.1 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
#include <float.h>
|
|
|
|
#ifdef AFX_DB_SEG
|
|
#pragma code_seg(AFX_DB_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// Helpers for floating point operations
|
|
static const float afxFloatPseudoNull = AFX_RFX_SINGLE_PSEUDO_NULL;
|
|
static const double afxDoublePseudoNull = AFX_RFX_DOUBLE_PSEUDO_NULL;
|
|
|
|
extern void AFXAPI AfxTextFloatFormat(CDataExchange* pDX, int nIDC,
|
|
void* pData, double value, int nSizeGcvt);
|
|
|
|
extern BOOL AFXAPI AfxFieldText(CDataExchange* pDX, int nIDC, void* pv,
|
|
CRecordset* pRecordset);
|
|
|
|
void AFXAPI RFX_Single(CFieldExchange* pFX, LPCTSTR szName,
|
|
float& value)
|
|
{
|
|
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
|
|
ASSERT(AfxIsValidString(szName));
|
|
|
|
UINT nField;
|
|
if (!pFX->IsFieldType(&nField))
|
|
return;
|
|
|
|
LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(nField - 1, pFX->m_nFieldType);
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CFieldExchange::BindFieldToColumn:
|
|
{
|
|
#ifdef _DEBUG
|
|
// Assumes all bound fields BEFORE unbound fields
|
|
CODBCFieldInfo* pODBCInfo =
|
|
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
|
|
|
|
if (pODBCInfo->m_nSQLType != SQL_C_FLOAT)
|
|
{
|
|
// Warn of possible field schema mismatch
|
|
if (afxTraceFlags & traceDatabase)
|
|
TRACE1("Warning: float converted from SQL type %ld.\n",
|
|
pODBCInfo->m_nSQLType);
|
|
}
|
|
#endif
|
|
}
|
|
// fall through
|
|
|
|
default:
|
|
LDefault:
|
|
pFX->Default(szName, &value, plLength, SQL_C_FLOAT,
|
|
sizeof(value), 13);
|
|
return;
|
|
|
|
case CFieldExchange::Fixup:
|
|
if (*plLength == SQL_NULL_DATA)
|
|
{
|
|
pFX->m_prs->SetNullFieldStatus(nField - 1);
|
|
value = afxFloatPseudoNull;
|
|
}
|
|
return;
|
|
|
|
case CFieldExchange::SetFieldNull:
|
|
if ((pFX->m_pvField == NULL &&
|
|
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
|
|
pFX->m_pvField == &value)
|
|
{
|
|
if (pFX->m_bField)
|
|
{
|
|
pFX->m_prs->SetNullFieldStatus(nField - 1);
|
|
value = afxFloatPseudoNull;
|
|
*plLength = SQL_NULL_DATA;
|
|
}
|
|
else
|
|
{
|
|
pFX->m_prs->ClearNullFieldStatus(nField - 1);
|
|
*plLength = sizeof(value);
|
|
}
|
|
#ifdef _DEBUG
|
|
pFX->m_nFieldFound = nField;
|
|
#endif
|
|
}
|
|
return;
|
|
|
|
case CFieldExchange::MarkForAddNew:
|
|
// can force writing of psuedo-null value (as a non-null) by setting field dirty
|
|
if (!pFX->m_prs->IsFieldStatusDirty(nField - 1))
|
|
{
|
|
if (value != afxFloatPseudoNull)
|
|
{
|
|
pFX->m_prs->SetDirtyFieldStatus(nField - 1);
|
|
pFX->m_prs->ClearNullFieldStatus(nField - 1);
|
|
}
|
|
}
|
|
return;
|
|
|
|
case CFieldExchange::MarkForUpdate:
|
|
if (value != afxFloatPseudoNull)
|
|
pFX->m_prs->ClearNullFieldStatus(nField - 1);
|
|
goto LDefault;
|
|
|
|
case CFieldExchange::AllocCache:
|
|
{
|
|
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
|
|
|
|
// Data cached by value, no allocation necessary
|
|
pInfo->m_nDataType = AFX_RFX_SINGLE;
|
|
}
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CFieldExchange::DumpField:
|
|
{
|
|
*pFX->m_pdcDump << "\n" << szName << " = " << value;
|
|
}
|
|
return;
|
|
#endif //_DEBUG
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void AFXAPI RFX_Double(CFieldExchange* pFX, LPCTSTR szName,
|
|
double& value)
|
|
{
|
|
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
|
|
ASSERT(AfxIsValidString(szName));
|
|
|
|
UINT nField;
|
|
if (!pFX->IsFieldType(&nField))
|
|
return;
|
|
|
|
LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(nField - 1, pFX->m_nFieldType);
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CFieldExchange::BindFieldToColumn:
|
|
{
|
|
#ifdef _DEBUG
|
|
// Assumes all bound fields BEFORE unbound fields
|
|
CODBCFieldInfo* pODBCInfo =
|
|
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
|
|
|
|
if (pODBCInfo->m_nSQLType != SQL_C_DOUBLE &&
|
|
pODBCInfo->m_nSQLType != SQL_FLOAT)
|
|
{
|
|
// Warn of possible field schema mismatch
|
|
if (afxTraceFlags & traceDatabase)
|
|
TRACE1("Warning: double converted from SQL type %ld.\n",
|
|
pODBCInfo->m_nSQLType);
|
|
}
|
|
#endif
|
|
}
|
|
// fall through
|
|
|
|
default:
|
|
LDefault:
|
|
pFX->Default(szName, &value, plLength, SQL_C_DOUBLE,
|
|
sizeof(value), 22);
|
|
return;
|
|
|
|
case CFieldExchange::Fixup:
|
|
if (*plLength == SQL_NULL_DATA)
|
|
{
|
|
pFX->m_prs->SetNullFieldStatus(nField - 1);
|
|
value = afxDoublePseudoNull;
|
|
}
|
|
return;
|
|
|
|
case CFieldExchange::SetFieldNull:
|
|
if ((pFX->m_pvField == NULL &&
|
|
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
|
|
pFX->m_pvField == &value)
|
|
{
|
|
if (pFX->m_bField)
|
|
{
|
|
pFX->m_prs->SetNullFieldStatus(nField - 1);
|
|
value = afxDoublePseudoNull;
|
|
*plLength = SQL_NULL_DATA;
|
|
}
|
|
else
|
|
{
|
|
pFX->m_prs->ClearNullFieldStatus(nField - 1);
|
|
*plLength = sizeof(value);
|
|
}
|
|
#ifdef _DEBUG
|
|
pFX->m_nFieldFound = nField;
|
|
#endif
|
|
}
|
|
return;
|
|
|
|
case CFieldExchange::MarkForAddNew:
|
|
// can force writing of psuedo-null value (as a non-null) by setting field dirty
|
|
if (!pFX->m_prs->IsFieldStatusDirty(nField - 1))
|
|
{
|
|
if (value != afxDoublePseudoNull)
|
|
{
|
|
pFX->m_prs->SetDirtyFieldStatus(nField - 1);
|
|
pFX->m_prs->ClearNullFieldStatus(nField - 1);
|
|
}
|
|
}
|
|
return;
|
|
|
|
case CFieldExchange::MarkForUpdate:
|
|
if (value != afxDoublePseudoNull)
|
|
pFX->m_prs->ClearNullFieldStatus(nField - 1);
|
|
goto LDefault;
|
|
|
|
case CFieldExchange::AllocCache:
|
|
{
|
|
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
|
|
pInfo->m_pvDataCache = new double;
|
|
pInfo->m_nDataType = AFX_RFX_DOUBLE;
|
|
}
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CFieldExchange::DumpField:
|
|
{
|
|
*pFX->m_pdcDump << "\n" << szName << " = " << value;
|
|
}
|
|
return;
|
|
#endif //_DEBUG
|
|
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void AFXAPI RFX_Single_Bulk(CFieldExchange* pFX, LPCTSTR szName,
|
|
float** prgFltVals, long** prgLengths)
|
|
{
|
|
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
|
|
ASSERT(AfxIsValidString(szName));
|
|
|
|
UINT nField;
|
|
if (!pFX->IsFieldType(&nField))
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CFieldExchange::AllocMultiRowBuffer:
|
|
{
|
|
// The buffer pointer better be initialized to NULL
|
|
// or cleanup in exceptional cases mail fail
|
|
ASSERT(*prgFltVals == NULL);
|
|
ASSERT(*prgLengths == NULL);
|
|
|
|
int nRowsetSize = pFX->m_prs->GetRowsetSize();
|
|
|
|
// Allocate buffers to hold data and length
|
|
*prgFltVals = new float[nRowsetSize];
|
|
*prgLengths = new long[nRowsetSize];
|
|
}
|
|
break;
|
|
|
|
case CFieldExchange::DeleteMultiRowBuffer:
|
|
delete [] *prgFltVals;
|
|
*prgFltVals = NULL;
|
|
|
|
delete [] *prgLengths;
|
|
*prgLengths = NULL;
|
|
break;
|
|
|
|
default:
|
|
AfxRFXBulkDefault(pFX, szName, *prgFltVals, *prgLengths,
|
|
SQL_C_FLOAT, sizeof(float));
|
|
break;
|
|
}
|
|
}
|
|
|
|
void AFXAPI RFX_Double_Bulk(CFieldExchange* pFX, LPCTSTR szName,
|
|
double** prgDblVals, long** prgLengths)
|
|
{
|
|
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
|
|
ASSERT(AfxIsValidString(szName));
|
|
|
|
UINT nField;
|
|
if (!pFX->IsFieldType(&nField))
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CFieldExchange::AllocMultiRowBuffer:
|
|
{
|
|
// The buffer pointer better be initialized to NULL
|
|
// or cleanup in exceptional cases mail fail
|
|
ASSERT(*prgDblVals == NULL);
|
|
ASSERT(*prgLengths == NULL);
|
|
|
|
int nRowsetSize = pFX->m_prs->GetRowsetSize();
|
|
|
|
// Allocate buffers to hold data and length
|
|
*prgDblVals = new double[nRowsetSize];
|
|
*prgLengths = new long[nRowsetSize];
|
|
}
|
|
break;
|
|
|
|
case CFieldExchange::DeleteMultiRowBuffer:
|
|
delete [] *prgDblVals;
|
|
*prgDblVals = NULL;
|
|
|
|
delete [] *prgLengths;
|
|
*prgLengths = NULL;
|
|
break;
|
|
|
|
default:
|
|
AfxRFXBulkDefault(pFX, szName, *prgDblVals, *prgLengths,
|
|
SQL_C_DOUBLE, sizeof(double));
|
|
break;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, float& value,
|
|
CRecordset* pRecordset)
|
|
{
|
|
if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
|
|
AfxTextFloatFormat(pDX, nIDC, &value, value, FLT_DIG);
|
|
}
|
|
|
|
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, double& value,
|
|
CRecordset* pRecordset)
|
|
{
|
|
if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
|
|
AfxTextFloatFormat(pDX, nIDC, &value, value, DBL_DIG);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|