List:Commits« Previous MessageNext Message »
From:pharvey Date:May 19 2006 6:50am
Subject:Connector/ODBC 5 commit: r258 - MYODBCC/MYODBCCLib MYODBCC/include MYSQLPlus/MYSQLPlusLib
View as plain text  
Modified:
   MYODBCC/MYODBCCLib/MYODBCC.cpp
   MYODBCC/include/MYODBCC.h
   MYSQLPlus/MYSQLPlusLib/MResult.cpp
   MYSQLPlus/MYSQLPlusLib/MResult.h
Log:


Modified: MYODBCC/MYODBCCLib/MYODBCC.cpp
===================================================================
--- MYODBCC/MYODBCCLib/MYODBCC.cpp	2006-05-18 21:38:18 UTC (rev 257)
+++ MYODBCC/MYODBCCLib/MYODBCC.cpp	2006-05-19 06:50:17 UTC (rev 258)
@@ -1391,13 +1391,106 @@
         return true;
     }
 #else
-    BOOLEAN MYODBCC::doStrNCpy( SQLWCHAR *pszDest, size_t nChars, const SQLWCHAR *pszSrc
)
+    BOOLEAN MYODBCC::doStrNCpy( SQLWCHAR *pszDest, size_t nMaxChars, const SQLWCHAR
*pszSrc )
     {
         wcsncpy( pszDest, pszSrc, nChars );
         return true;
     }
 #endif
 
+/*!
+    \brief      Copies a C string.
+
+                The following occurs in this method;
+
+                1. the dest string is always null terminated (unless buffer is not
provided)
+                2. considers truncation
+
+    \return     BOOLEAN
+
+    \retval     true    Copy completed with no warnings/errors
+                false   Copy completed but result was truncated due to lack of space in
dest buffer 
+*/
+BOOLEAN MYODBCC::doStringCopyOut( SQLCHAR *pszDest, SQLINTEGER nDestMaxChars, SQLCHAR
*pszSrc )
+{
+    SQLINTEGER nIndex = 0;
+
+    /* sanity checks */
+    if ( !pszDest || nDestMaxChars < 1 )
+    {
+        if ( *pszSrc )
+            return false;
+        return true;
+    }
+
+    if ( !pszSrc )
+    {
+        *pszDest = '\0';
+        return true; /* ok - but nothing to copy */
+    }
+
+    /* copy chars while room in pszDest or end of pszSrc */
+    for ( nIndex = 0; nIndex < nDestMaxChars; nIndex++ )
+    {
+        pszDest[nIndex] = pszSrc[nIndex];
+        if ( pszSrc[nIndex] == '\0' )
+            return true;
+    }
+
+    /* pszDest full - ensure last char is null terminator */
+    pszDest[nIndex-1] = '\0';
+
+    /* results are truncated */
+    return false;
+}
+
+/*!
+    \brief      Copies a wide character C string.
+
+                The following occurs in this method;
+
+                1. the dest string is always null terminated (unless buffer is not
provided)
+                2. considers truncation
+
+    \return     BOOLEAN
+
+    \retval     true    Copy completed with no warnings/errors
+                false   Copy completed but result was truncated due to lack of space in
dest buffer 
+*/
+BOOLEAN MYODBCC::doStringCopyOut( SQLWCHAR *pszDest, SQLINTEGER nDestMaxChars, SQLWCHAR
*pszSrc )
+{
+    SQLINTEGER nIndex = 0;
+
+    /* sanity checks */
+    if ( !pszDest || nDestMaxChars < 1 )
+    {
+        if ( *pszSrc )
+            return false;
+        return true;
+    }
+
+    if ( !pszSrc )
+    {
+        *pszDest = '\0';
+        return true; /* ok - but nothing to copy */
+    }
+
+    /* copy chars while room in pszDest or end of pszSrc */
+    for ( nIndex = 0; nIndex < nDestMaxChars; nIndex++ )
+    {
+        pszDest[nIndex] = pszSrc[nIndex];
+        if ( pszSrc[nIndex] == '\0' )
+            return true;
+    }
+
+    /* pszDest full - ensure last char is null terminator */
+    pszDest[nIndex-1] = '\0';
+
+    /* results are truncated */
+    return false;
+}
+
+
 void MYODBCC::doFree( void *p )
 {
     if ( p ) 

Modified: MYODBCC/include/MYODBCC.h
===================================================================
--- MYODBCC/include/MYODBCC.h	2006-05-18 21:38:18 UTC (rev 257)
+++ MYODBCC/include/MYODBCC.h	2006-05-19 06:50:17 UTC (rev 258)
@@ -250,6 +250,9 @@
     static BOOLEAN  doStrNCpy( SQLWCHAR *pszDest, size_t nSizeInWords, const SQLWCHAR
*pszSrc );
 #endif
 
+    static BOOLEAN doStringCopyOut( SQLCHAR *pszDest, SQLINTEGER nDestMaxChars, SQLCHAR
*pszSrc );
+    static BOOLEAN doStringCopyOut( SQLWCHAR *pszDest, SQLINTEGER nDestMaxChars, SQLWCHAR
*pszSrc );
+
     static void     doFree( void *p );
 
     static BOOLEAN isConnectAttr( SQLINTEGER nAttribute );

Modified: MYSQLPlus/MYSQLPlusLib/MResult.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResult.cpp	2006-05-18 21:38:18 UTC (rev 257)
+++ MYSQLPlus/MYSQLPlusLib/MResult.cpp	2006-05-19 06:50:17 UTC (rev 258)
@@ -41,7 +41,6 @@
     pnIndicator             = NULL;
 
     nTargetTypeAdjusted     = SQL_C_CHAR;
-    nBytesRemaining         = 0;
     nIndicator              = SQL_NO_TOTAL;
     variantData.clear();
     pDescriptorRecordIRD    = NULL;
@@ -56,7 +55,7 @@
     MYODBCDbgEnter();
 
     if ( this->nColumn == nColumn           &&
-         nBytesRemaining > 0                &&
+         !variantData.isNull()              &&
          this->nTargetType == nTargetType   &&
          MDescriptorRecordIRD::isVariableLength( nType ) )
     {
@@ -1007,6 +1006,14 @@
         | SQL_C_CHAR  |	Byte length of data < BufferLength  | Data            | Length
of data in bytes | n/a      |
         |             | Byte length of data >= BufferLength | Truncated data  | Length
of data in bytes | 01004    |
        
+-------------+-------------------------------------+-----------------+-------------------------+----------+
+
+        When character data is returned from the driver to the application, the driver
must always null-terminate it. 
+        This gives the application the choice of whether to handle the data as a string
or a character array. If the 
+        application buffer is not large enough to return all of the character data, the
driver truncates it to the byte 
+        length of the buffer less the number of bytes required by the null-termination
character, null-terminates the 
+        truncated data, and stores it in the buffer. Therefore, applications must always
allocate extra space for the 
+        null-termination character in buffers used to retrieve character data. For
example, a 51-byte buffer is needed 
+        to retrieve 50 characters of data.
     */
 
     if ( !resultGetData.variantData.canConvert<QString>() )
@@ -1015,16 +1022,24 @@
     QString stringData = resultGetData.variantData.toString();
     if ( resultGetData.pTarget && resultGetData.nBytesMax )
     {
-        MYODBCC::doStrNCpy( (SQLCHAR*)resultGetData.pTarget, resultGetData.nBytesMax,
stringData.toAscii().data() );
-        if ( resultGetData.nBytesMax >= stringData.length() )
+        if ( MYODBCC::doStringCopy( (SQLCHAR*)resultGetData.pTarget,
resultGetData.nBytesMax, stringData.toAscii().data() ) )
+        {
+            variantData.clear();
+            if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining = 0;
+        }
+        else
+        {
+            if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
stringData.length() - resultGetData.nBytesMax;
+            variantData.setValue( stringData.mid( resultGetData.nBytesMax - 1 ) );
             MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01004 ) );
+        }
     }
     else 
+    {
+        if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
stringData.length();
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01004 ) );
+    }
 
-    resultGetData.nBytesRemaining = ( stringData.length() + 1 ) -
resultGetData.nBytesMax;
-    if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
resultGetData.nBytesRemaining;
-
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
@@ -1041,6 +1056,14 @@
         | SQL_C_WCHAR |	Character length of data < BufferLength  | Data            |
Length of data in characters | n/a      |
         |             | Character length of data >= BufferLength | Truncated data  |
Length of data in characters | 01004    |
        
+-------------+------------------------------------------+-----------------+------------------------------+----------+
+
+        When character data is returned from the driver to the application, the driver
must always null-terminate it. 
+        This gives the application the choice of whether to handle the data as a string
or a character array. If the 
+        application buffer is not large enough to return all of the character data, the
driver truncates it to the byte 
+        length of the buffer less the number of bytes required by the null-termination
character, null-terminates the 
+        truncated data, and stores it in the buffer. Therefore, applications must always
allocate extra space for the 
+        null-termination character in buffers used to retrieve character data. For
example, a 51-byte buffer is needed 
+        to retrieve 50 characters of data.
     */
 
     if ( !resultGetData.variantData.canConvert<QString>() )
@@ -1049,16 +1072,24 @@
     QString stringData = resultGetData.variantData.toString();
     if ( resultGetData.pTarget && resultGetData.nBytesMax )
     {
-        MYODBCC::doStrNCpy( (SQLWCHAR*)resultGetData.pTarget, resultGetData.nBytesMax /
sizeof(SQLWCHAR), stringData.utf16() );
-        if ( resultGetData.nBytesMax >= stringData.length() / sizeof(SQLWCHAR) )
+        if ( MYODBCC::doStringCopy( (SQLWCHAR*)resultGetData.pTarget,
resultGetData.nBytesMax / sizeof(SQLWCHAR), stringData.utf16() ) )
+        {
+            variantData.clear();
+            if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining = 0;
+        }
+        else
+        {
+            if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
stringData.length() * sizeof(SQLWCHAR) - resultGetData.nBytesMax;
+            variantData.setValue( stringData.mid( (resultGetData.nBytesMax - 1) /
sizeof(SQLWCHAR) ) );
             MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01004 ) );
+        }
     }
     else 
+    {
+        if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
stringData.length() * sizeof(SQLWCHAR);
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01004 ) );
+    }
 
-    resultGetData.nBytesRemaining = ( stringData.length() + 1 ) - resultGetData.nBytesMax
/ sizeof(SQLWCHAR);
-    if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
resultGetData.nBytesRemaining;
-
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
@@ -1231,13 +1262,32 @@
 {
     MYODBCDbgEnter();
 
+    if ( !resultGetData.variantData.canConvert<QByteArray>() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006 ) );
+
     QByteArray bytearray = resultGetData.variantData.toByteArray();
 
-    MYODBCC::doMemCpy( resultGetData.pTarget, bytearray.constData(),
resultGetData.nBytesMax );
+    if ( resultGetData.pTarget && resultGetData.nBytesMax )
+    {
+        MYODBCC::doMemCpy( resultGetData.pTarget, bytearray.constData(), min(
resultGetData.nBytesMax, bytearray.size() ) );
+        if ( bytearray.size() <= resultGetData.nBytesMax )
+        {
+            variantData.clear();
+            if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining = 0;
+        }
+        else
+        {
+            if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
bytearray.size() - resultGetData.nBytesMax;
+            variantData.setValue( bytearray.mid( resultGetData.nBytesMax - 1 ) );
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01004 ) );
+        }
+    }
+    else 
+    {
+        if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
bytearray.size();
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01004 ) );
+    }
 
-    resultGetData.nBytesRemaining = bytearray.size() - resultGetData.nBytesMax;
-    if ( resultGetData.pnBytesRemaining ) *resultGetData.pnBytesRemaining =
resultGetData.nBytesRemaining;
-
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 

Modified: MYSQLPlus/MYSQLPlusLib/MResult.h
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResult.h	2006-05-18 21:38:18 UTC (rev 257)
+++ MYSQLPlus/MYSQLPlusLib/MResult.h	2006-05-19 06:50:17 UTC (rev 258)
@@ -41,7 +41,6 @@
 
     /* these are additional fields which assist in maintaining our getData state */
     SQLSMALLINT             nTargetTypeAdjusted;    /*!< is nTargetType, SQL_C_DEFAULT
derived, or ARD derived              */
-    SQLINTEGER              nBytesRemaining;        /*!< cached ver of value at
pnBytesRemaining                     */ 
     SQLINTEGER              nIndicator;             /*!< cached ver of value at
pnIndicator                                 */
     QVariant                variantData;            /*!< resultset cell data          
                                     */     
     MDescriptorRecordIRD *  pDescriptorRecordIRD;   /*!< descriptor describing the
resultset column                         */

Thread
Connector/ODBC 5 commit: r258 - MYODBCC/MYODBCCLib MYODBCC/include MYSQLPlus/MYSQLPlusLibpharvey19 May