aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/misc/carray.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/ext/misc/carray.c b/ext/misc/carray.c
index b6eb0453a..709c894f2 100644
--- a/ext/misc/carray.c
+++ b/ext/misc/carray.c
@@ -28,7 +28,7 @@
**
** There is an optional third parameter to determine the datatype of
** the C-language array. Allowed values of the third parameter are
-** 'int32', 'int64', 'double', 'char*'. Example:
+** 'int32', 'int64', 'double', 'char*', 'struct iovec'. Example:
**
** SELECT * FROM carray($ptr,10,'char*');
**
@@ -56,6 +56,14 @@
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
+#ifdef _WIN32
+ struct iovec {
+ void *iov_base;
+ size_t iov_len;
+ };
+#else
+# include <sys/uio.h>
+#endif
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
** Must exactly match the definitions in carray.h.
@@ -65,6 +73,7 @@ SQLITE_EXTENSION_INIT1
# define CARRAY_INT64 1 /* Data is 64-bit signed integers */
# define CARRAY_DOUBLE 2 /* Data is doubles */
# define CARRAY_TEXT 3 /* Data is char* */
+# define CARRAY_BLOB 4 /* Data is struct iovec* */
#endif
#ifndef SQLITE_API
@@ -80,7 +89,8 @@ SQLITE_EXTENSION_INIT1
/*
** Names of allowed datatypes
*/
-static const char *azType[] = { "int32", "int64", "double", "char*" };
+static const char *azType[] = { "int32", "int64", "double", "char*",
+ "struct iovec" };
/*
** Structure used to hold the sqlite3_carray_bind() information
@@ -224,6 +234,12 @@ static int carrayColumn(
sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
return SQLITE_OK;
}
+ case CARRAY_BLOB: {
+ const struct iovec *p = (struct iovec*)pCur->pPtr;
+ sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base,
+ (int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT);
+ return SQLITE_OK;
+ }
}
}
}
@@ -268,7 +284,7 @@ static int carrayFilter(
if( pBind==0 ) break;
pCur->pPtr = pBind->aData;
pCur->iCnt = pBind->nData;
- pCur->eType = pBind->mFlags & 0x03;
+ pCur->eType = pBind->mFlags & 0x07;
break;
}
case 2:
@@ -431,24 +447,29 @@ SQLITE_API int sqlite3_carray_bind(
pNew->mFlags = mFlags;
if( xDestroy==SQLITE_TRANSIENT ){
sqlite3_int64 sz = nData;
- switch( mFlags & 0x03 ){
- case CARRAY_INT32: sz *= 4; break;
- case CARRAY_INT64: sz *= 8; break;
- case CARRAY_DOUBLE: sz *= 8; break;
- case CARRAY_TEXT: sz *= sizeof(char*); break;
+ switch( mFlags & 0x07 ){
+ case CARRAY_INT32: sz *= 4; break;
+ case CARRAY_INT64: sz *= 8; break;
+ case CARRAY_DOUBLE: sz *= 8; break;
+ case CARRAY_TEXT: sz *= sizeof(char*); break;
+ case CARRAY_BLOB: sz *= sizeof(struct iovec); break;
}
- if( (mFlags & 0x03)==CARRAY_TEXT ){
+ if( (mFlags & 0x07)==CARRAY_TEXT ){
for(i=0; i<nData; i++){
const char *z = ((char**)aData)[i];
if( z ) sz += strlen(z) + 1;
}
+ }else if( (mFlags & 0x07)==CARRAY_BLOB ){
+ for(i=0; i<nData; i++){
+ sz += ((struct iovec*)aData)[i].iov_len;
+ }
}
pNew->aData = sqlite3_malloc64( sz );
if( pNew->aData==0 ){
sqlite3_free(pNew);
return SQLITE_NOMEM;
}
- if( (mFlags & 0x03)==CARRAY_TEXT ){
+ if( (mFlags & 0x07)==CARRAY_TEXT ){
char **az = (char**)pNew->aData;
char *z = (char*)&az[nData];
for(i=0; i<nData; i++){
@@ -463,6 +484,16 @@ SQLITE_API int sqlite3_carray_bind(
memcpy(z, zData, n+1);
z += n+1;
}
+ }else if( (mFlags & 0x07)==CARRAY_BLOB ){
+ struct iovec *p = (struct iovec*)pNew->aData;
+ unsigned char *z = (unsigned char*)&p[nData];
+ for(i=0; i<nData; i++){
+ size_t n = ((struct iovec*)aData)[i].iov_len;
+ p[i].iov_len = n;
+ p[i].iov_base = z;
+ z += n;
+ memcpy(p[i].iov_base, ((struct iovec*)aData)[i].iov_base, n);
+ }
}else{
memcpy(pNew->aData, aData, sz);
}