2828**
2929** There is an optional third parameter to determine the datatype of
3030** the C-language array. Allowed values of the third parameter are
31- ** 'int32', 'int64', 'double', 'char*'. Example:
31+ ** 'int32', 'int64', 'double', 'char*', 'struct iovec' . Example:
3232**
3333** SELECT * FROM carray($ptr,10,'char*');
3434**
5656SQLITE_EXTENSION_INIT1
5757#include <assert.h>
5858#include <string.h>
59+ #ifdef _WIN32
60+ struct iovec {
61+ void * iov_base ;
62+ size_t iov_len ;
63+ };
64+ #else
65+ # include <sys/uio.h>
66+ #endif
5967
6068/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
6169** Must exactly match the definitions in carray.h.
@@ -65,6 +73,7 @@ SQLITE_EXTENSION_INIT1
6573# define CARRAY_INT64 1 /* Data is 64-bit signed integers */
6674# define CARRAY_DOUBLE 2 /* Data is doubles */
6775# define CARRAY_TEXT 3 /* Data is char* */
76+ # define CARRAY_BLOB 4 /* Data is struct iovec* */
6877#endif
6978
7079#ifndef SQLITE_API
@@ -80,7 +89,8 @@ SQLITE_EXTENSION_INIT1
8089/*
8190** Names of allowed datatypes
8291*/
83- static const char * azType [] = { "int32" , "int64" , "double" , "char*" };
92+ static const char * azType [] = { "int32" , "int64" , "double" , "char*" ,
93+ "struct iovec" };
8494
8595/*
8696** Structure used to hold the sqlite3_carray_bind() information
@@ -224,6 +234,12 @@ static int carrayColumn(
224234 sqlite3_result_text (ctx , p [pCur -> iRowid - 1 ], -1 , SQLITE_TRANSIENT );
225235 return SQLITE_OK ;
226236 }
237+ case CARRAY_BLOB : {
238+ const struct iovec * p = (struct iovec * )pCur -> pPtr ;
239+ sqlite3_result_blob (ctx , p [pCur -> iRowid - 1 ].iov_base ,
240+ (int )p [pCur -> iRowid - 1 ].iov_len , SQLITE_TRANSIENT );
241+ return SQLITE_OK ;
242+ }
227243 }
228244 }
229245 }
@@ -268,7 +284,7 @@ static int carrayFilter(
268284 if ( pBind == 0 ) break ;
269285 pCur -> pPtr = pBind -> aData ;
270286 pCur -> iCnt = pBind -> nData ;
271- pCur -> eType = pBind -> mFlags & 0x03 ;
287+ pCur -> eType = pBind -> mFlags & 0x07 ;
272288 break ;
273289 }
274290 case 2 :
@@ -431,24 +447,29 @@ SQLITE_API int sqlite3_carray_bind(
431447 pNew -> mFlags = mFlags ;
432448 if ( xDestroy == SQLITE_TRANSIENT ){
433449 sqlite3_int64 sz = nData ;
434- switch ( mFlags & 0x03 ){
435- case CARRAY_INT32 : sz *= 4 ; break ;
436- case CARRAY_INT64 : sz *= 8 ; break ;
437- case CARRAY_DOUBLE : sz *= 8 ; break ;
438- case CARRAY_TEXT : sz *= sizeof (char * ); break ;
450+ switch ( mFlags & 0x07 ){
451+ case CARRAY_INT32 : sz *= 4 ; break ;
452+ case CARRAY_INT64 : sz *= 8 ; break ;
453+ case CARRAY_DOUBLE : sz *= 8 ; break ;
454+ case CARRAY_TEXT : sz *= sizeof (char * ); break ;
455+ case CARRAY_BLOB : sz *= sizeof (struct iovec ); break ;
439456 }
440- if ( (mFlags & 0x03 )== CARRAY_TEXT ){
457+ if ( (mFlags & 0x07 )== CARRAY_TEXT ){
441458 for (i = 0 ; i < nData ; i ++ ){
442459 const char * z = ((char * * )aData )[i ];
443460 if ( z ) sz += strlen (z ) + 1 ;
444461 }
462+ }else if ( (mFlags & 0x07 )== CARRAY_BLOB ){
463+ for (i = 0 ; i < nData ; i ++ ){
464+ sz += ((struct iovec * )aData )[i ].iov_len ;
465+ }
445466 }
446467 pNew -> aData = sqlite3_malloc64 ( sz );
447468 if ( pNew -> aData == 0 ){
448469 sqlite3_free (pNew );
449470 return SQLITE_NOMEM ;
450471 }
451- if ( (mFlags & 0x03 )== CARRAY_TEXT ){
472+ if ( (mFlags & 0x07 )== CARRAY_TEXT ){
452473 char * * az = (char * * )pNew -> aData ;
453474 char * z = (char * )& az [nData ];
454475 for (i = 0 ; i < nData ; i ++ ){
@@ -463,6 +484,16 @@ SQLITE_API int sqlite3_carray_bind(
463484 memcpy (z , zData , n + 1 );
464485 z += n + 1 ;
465486 }
487+ }else if ( (mFlags & 0x07 )== CARRAY_BLOB ){
488+ struct iovec * p = (struct iovec * )pNew -> aData ;
489+ unsigned char * z = (unsigned char * )& p [nData ];
490+ for (i = 0 ; i < nData ; i ++ ){
491+ size_t n = ((struct iovec * )aData )[i ].iov_len ;
492+ p [i ].iov_len = n ;
493+ p [i ].iov_base = z ;
494+ z += n ;
495+ memcpy (p [i ].iov_base , ((struct iovec * )aData )[i ].iov_base , n );
496+ }
466497 }else {
467498 memcpy (pNew -> aData , aData , sz );
468499 }
0 commit comments