/* ** Change the value of a Mem to be a string or a BLOB. ** ** The memory management strategy depends on the value of the xDel ** parameter. If the value passed is SQLITE_TRANSIENT, then the ** string is copied into a (possibly existing) buffer managed by the ** Mem structure. Otherwise, any existing buffer is freed and the ** pointer copied. ** ** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH ** size limit) then no memory allocation occurs. If the string can be ** stored without allocating memory, then it is. If a memory allocation ** is required to store the string, then value of pMem is unchanged. In ** either case, SQLITE_TOOBIG is returned. */ private static int sqlite3VdbeMemSetBlob( Mem pMem, /* Memory cell to set to string value */ byte[] zBlob, /* Blob pointer */ int n, /* Bytes in Blob */ u8 enc, /* 0 for BLOBs */ dxDel xDel /* Destructor function */ ) { return sqlite3VdbeMemSetBlob(pMem, zBlob, 0, n >= 0 ? n : zBlob.Length, enc, xDel); } // Call w/o offset
} // Call w/o offset private static int sqlite3VdbeMemSetBlob( Mem pMem, /* Memory cell to set to string value */ byte[] zBlob, /* Blob pointer */ int offset, /* offset into string */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ dxDel xDel//)(void*)/* Destructor function */ ) { int nByte = n; /* New value for pMem->n */ int iLimit; /* Maximum allowed string or blob size */ Debug.Assert(pMem.db == null || sqlite3_mutex_held(pMem.db.mutex)); Debug.Assert((pMem.flags & MEM_RowSet) == 0); /* If zBlob is a NULL pointer, set pMem to contain an SQL NULL. */ if (zBlob == null || zBlob.Length < offset) { sqlite3VdbeMemSetNull(pMem); return SQLITE_OK; } if (pMem.db != null) { iLimit = pMem.db.aLimit[SQLITE_LIMIT_LENGTH]; } else { iLimit = SQLITE_MAX_LENGTH; } if (nByte < 0) { Debug.Assert(enc != 0); if (enc == SQLITE_UTF8) { for (nByte = 0; nByte <= iLimit && nByte < zBlob.Length - offset && zBlob[offset + nByte] != 0; nByte++) { } } else { for (nByte = 0; nByte <= iLimit && zBlob[nByte + offset] != 0 || zBlob[offset + nByte + 1] != 0; nByte += 2) { } } } /* The following block sets the new values of Mem.z and Mem.xDel. It ** also sets a flag in local variable "flags" to indicate the memory ** management (one of MEM_Dyn or MEM_Static). */ Debug.Assert(enc == 0); { pMem.z = null; pMem.zBLOB = sqlite3Malloc(n); Buffer.BlockCopy(zBlob, offset, pMem.zBLOB, 0, n); } pMem.n = nByte; pMem.flags = MEM_Blob | MEM_Term; pMem.enc = (enc == 0 ? SQLITE_UTF8 : enc); pMem.type = (enc == 0 ? SQLITE_BLOB : SQLITE_TEXT); if (nByte > iLimit) { return SQLITE_TOOBIG; } return SQLITE_OK; }
//# define sqlite3_open16 0 //# define sqlite3_prepare16 0 //# define sqlite3_prepare16_v2 0 //# define sqlite3_result_error16 0 //# define sqlite3_result_text16 0 static void sqlite3_result_text16(sqlite3_context pCtx, string z, int n, dxDel xDel) { }
/* ** Change the string value of an sqlite3_value object */ private static void sqlite3ValueSetStr( sqlite3_value v, /* Value to be set */ int n, /* Length of string z */ string z, /* Text of the new string */ u8 enc, /* Encoding to use */ dxDel xDel//)(void*) /* Destructor for the string */ ) { if (v != null) sqlite3VdbeMemSetStr(v, z, n, enc, xDel); }
void sqlite3_result_text16le( sqlite3_context pCtx, string z, int n, dxDel xDel ){ Debug.Assert( sqlite3_mutex_held(pCtx.s.db.mutex) ); sqlite3VdbeMemSetStr(pCtx.s, z, n, SQLITE_UTF16LE, xDel); }
//# define sqlite3_open16 0 //# define sqlite3_prepare16 0 //# define sqlite3_prepare16_v2 0 //# define sqlite3_result_error16 0 //# define sqlite3_result_text16 0 static void sqlite3_result_text16( sqlite3_context pCtx, string z, int n, dxDel xDel ) { }
public static void sqlite3_result_blob( sqlite3_context pCtx, string z, int n, dxDel xDel ) { Debug.Assert( n >= 0 ); Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); setResultStrOrError( pCtx, z, n, 0, xDel ); }
/// <summary> /// Sqlite3s the vdbe mem set string. /// </summary> /// <param name='pMem'> /// Memory cell to set to string value /// </param> /// <param name='z'> /// String pointer /// </param> /// <param name='n'> /// Bytes in string, or negative /// </param> /// <param name='enc'> /// Encoding of z. 0 for BLOBs. /// </param> /// <param name='xDel'> /// Destructor function /// </param> static int sqlite3VdbeMemSetStr( Mem pMem, string z, int n, u8 enc, dxDel xDel ) { return sqlite3VdbeMemSetStr(pMem, z, 0, n, enc, xDel); }
/* ** Set the auxillary data pointer and delete function, for the iArg'th ** argument to the user-function defined by pCtx. Any previous value is ** deleted by calling the delete function specified when it was set. */ public static void sqlite3_set_auxdata( sqlite3_context pCtx, int iArg, string pAux, dxDel xDelete//void (*xDelete)(void*) ) { AuxData pAuxData; VdbeFunc pVdbeFunc; if (iArg < 0) goto failed; Debug.Assert(sqlite3_mutex_held(pCtx.s.db.mutex)); pVdbeFunc = pCtx.pVdbeFunc; if (null == pVdbeFunc || pVdbeFunc.nAux <= iArg) { int nAux = (pVdbeFunc != null ? pVdbeFunc.nAux : 0); int nMalloc = iArg; ;//VdbeFunc+ sizeof(struct AuxData)*iArg; if (pVdbeFunc == null) { //pVdbeFunc = (VdbeFunc)sqlite3DbRealloc( pCtx.s.db, pVdbeFunc, nMalloc ); pVdbeFunc = new VdbeFunc(); if (null == pVdbeFunc) { goto failed; } pCtx.pVdbeFunc = pVdbeFunc; } pVdbeFunc.apAux[nAux] = new AuxData();//memset(pVdbeFunc.apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux)); pVdbeFunc.nAux = iArg + 1; pVdbeFunc.pFunc = pCtx.pFunc; } pAuxData = pVdbeFunc.apAux[iArg]; if (pAuxData.pAux != null && pAuxData.xDelete != null) { pAuxData.xDelete(ref pAuxData.pAux); } pAuxData.pAux = pAux; pAuxData.xDelete = xDelete; return; failed: if (xDelete != null) { xDelete(ref pAux); } }
static void setResultStrOrError( sqlite3_context pCtx, /* Function context */ string z, /* String pointer */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ dxDel xDel //void (*xDel)(void) /* Destructor function */ ) { if ( sqlite3VdbeMemSetStr( pCtx.s, z, n, enc, xDel ) == SQLITE_TOOBIG ) { sqlite3_result_error_toobig( pCtx ); } }
/* ** Set the name of the idx'th column to be returned by the SQL statement. ** zName must be a pointer to a nul terminated string. ** ** This call must be made after a call to sqlite3VdbeSetNumCols(). ** ** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC ** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed ** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed. */ static int sqlite3VdbeSetColName( Vdbe p, /* Vdbe being configured */ int idx, /* Index of column zName applies to */ int var, /* One of the COLNAME_* constants */ string zName, /* Pointer to buffer containing name */ dxDel xDel /* Memory management strategy for zName */ ) { int rc; Mem pColName; Debug.Assert( idx < p.nResColumn ); Debug.Assert( var < COLNAME_N ); //if ( p.db.mallocFailed != 0 ) //{ // Debug.Assert( null == zName || xDel != SQLITE_DYNAMIC ); // return SQLITE_NOMEM; //} Debug.Assert( p.aColName != null ); pColName = p.aColName[idx + var * p.nResColumn]; rc = sqlite3VdbeMemSetStr( pColName, zName, -1, SQLITE_UTF8, xDel ); Debug.Assert( rc != 0 || null == zName || ( pColName.flags & MEM_Term ) != 0 ); return rc; }
//STRING //STRING + Type static void sqlite3VdbeChangeP4( Vdbe p, int addr, string z, dxDel P4_Type ) { union_p4 _p4 = new union_p4(); _p4.z = z; sqlite3VdbeChangeP4( p, addr, _p4, P4_DYNAMIC ); }
/// <summary> /// The following routines are used by user-defined functions to specify /// the function result. /// /// The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the /// result as a string or blob but if the string or blob is too large, it /// then sets the error code to SQLITE_TOOBIG /// </summary> /// <param name='pCtx'> /// Function context /// </param> /// <param name='z'> /// String pointer /// </param> /// <param name='o' /// <param name='n'> /// Bytes in string, or negative /// </param> /// <param name='enc'> /// Encoding of z. 0 for BLOBs /// </param> /// <param name='xDel'> /// Destructor function /// </param> static void setResultStrOrError( sqlite3_context pCtx, string z, int n, u8 enc, dxDel xDel ) { if (sqlite3VdbeMemSetStr(pCtx.s, z, n, enc, xDel) == SQLITE_TOOBIG) { sqlite3_result_error_toobig(pCtx); } }
private static int sqlite3VdbeMemSetStr( Mem pMem, /* Memory cell to set to string value */ string z, /* String pointer */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ dxDel xDel /* Destructor function */ ) { return sqlite3VdbeMemSetStr(pMem, z, 0, n, enc, xDel); } // Call w/o offset
public static void sqlite3_result_text( sqlite3_context pCtx, string z, int n, dxDel xDel ) { Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); setResultStrOrError( pCtx, z, n, SQLITE_UTF8, xDel ); }
} // Call w/o offset private static int sqlite3VdbeMemSetStr( Mem pMem, /* Memory cell to set to string value */ string z, /* String pointer */ int offset, /* offset into string */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ dxDel xDel//)(void*)/* Destructor function */ ) { int nByte = n; /* New value for pMem->n */ int iLimit; /* Maximum allowed string or blob size */ u16 flags = 0; /* New value for pMem->flags */ Debug.Assert(pMem.db == null || sqlite3_mutex_held(pMem.db.mutex)); Debug.Assert((pMem.flags & MEM_RowSet) == 0); /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if (z == null || z.Length < offset) { sqlite3VdbeMemSetNull(pMem); return SQLITE_OK; } if (pMem.db != null) { iLimit = pMem.db.aLimit[SQLITE_LIMIT_LENGTH]; } else { iLimit = SQLITE_MAX_LENGTH; } flags = (u16)(enc == 0 ? MEM_Blob : MEM_Str); if (nByte < 0) { Debug.Assert(enc != 0); if (enc == SQLITE_UTF8) { for (nByte = 0; nByte <= iLimit && nByte < z.Length - offset && z[offset + nByte] != 0; nByte++) { } } else { for (nByte = 0; nByte <= iLimit && z[nByte + offset] != 0 || z[offset + nByte + 1] != 0; nByte += 2) { } } flags |= MEM_Term; } /* The following block sets the new values of Mem.z and Mem.xDel. It ** also sets a flag in local variable "flags" to indicate the memory ** management (one of MEM_Dyn or MEM_Static). */ if (xDel == SQLITE_TRANSIENT) { u32 nAlloc = (u32)nByte; if ((flags & MEM_Term) != 0) { nAlloc += (u32)(enc == SQLITE_UTF8 ? 1 : 2); } if (nByte > iLimit) { return SQLITE_TOOBIG; } if (sqlite3VdbeMemGrow(pMem, (int)nAlloc, 0) != 0) { return SQLITE_NOMEM; } //if ( nAlloc < z.Length ) //pMem.z = new byte[nAlloc]; Buffer.BlockCopy( z, 0, pMem.z, 0, (int)nAlloc ); } //else if (enc == 0) { pMem.z = null; pMem.zBLOB = sqlite3Malloc(n); for (int i = 0; i < n && i < z.Length - offset; i++) pMem.zBLOB[i] = (byte)z[offset + i]; } else { pMem.z = n > 0 && z.Length - offset > n ? z.Substring(offset, n) : z.Substring(offset);//memcpy(pMem.z, z, nAlloc); sqlite3_free(ref pMem.zBLOB); } } else if (xDel == SQLITE_DYNAMIC) { sqlite3VdbeMemRelease(pMem); //pMem.zMalloc = pMem.z = (char*)z; if (enc == 0) { pMem.z = null; if (pMem.zBLOB != null) sqlite3_free(ref pMem.zBLOB); pMem.zBLOB = Encoding.UTF8.GetBytes(offset == 0 ? z : z.Length + offset < n ? z.Substring(offset, n) : z.Substring(offset)); } else { pMem.z = n > 0 && z.Length - offset > n ? z.Substring(offset, n) : z.Substring(offset);//memcpy(pMem.z, z, nAlloc); sqlite3_free(ref pMem.zBLOB); } pMem.xDel = null; } else { sqlite3VdbeMemRelease(pMem); if (enc == 0) { pMem.z = null; if (pMem.zBLOB != null) sqlite3_free(ref pMem.zBLOB); pMem.zBLOB = Encoding.UTF8.GetBytes(offset == 0 ? z : z.Length + offset < n ? z.Substring(offset, n) : z.Substring(offset)); } else { pMem.z = n > 0 && z.Length - offset > n ? z.Substring(offset, n) : z.Substring(offset);//memcpy(pMem.z, z, nAlloc); sqlite3_free(ref pMem.zBLOB); } pMem.xDel = xDel; flags |= (u16)((xDel == SQLITE_STATIC) ? MEM_Static : MEM_Dyn); } pMem.n = nByte; pMem.flags = flags; pMem.enc = (enc == 0 ? SQLITE_UTF8 : enc); pMem.type = (enc == 0 ? SQLITE_BLOB : SQLITE_TEXT); #if !SQLITE_OMIT_UTF16 if( pMem.enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem)!=0 ){ return SQLITE_NOMEM; } #endif if (nByte > iLimit) { return SQLITE_TOOBIG; } return SQLITE_OK; }
/// <summary> /// Change the value of a Mem to be a string or a BLOB. /// /// The memory management strategy depends on the value of the xDel /// parameter. If the value passed is SQLITE_TRANSIENT, then the /// string is copied into a (possibly existing) buffer managed by the /// Mem structure. Otherwise, any existing buffer is freed and the /// pointer copied. /// /// If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH /// size limit) then no memory allocation occurs. If the string can be /// stored without allocating memory, then it is. If a memory allocation /// is required to store the string, then value of pMem is unchanged. In /// either case, SQLITE_TOOBIG is returned. /// </summary> /// <param name='pMem'> /// Memory cell to set to string value. /// </param> /// <param name='zBlob'> /// Blob pointer /// </param> /// <param name='n'> /// Bytes in Blob /// </param> /// <param name='enc'> /// 0 for BLOBs /// </param> /// <param name='xDel'> /// Destructor function /// </param> static int sqlite3VdbeMemSetBlob( Mem pMem, byte[] zBlob, int n, u8 enc, dxDel xDel ) { return sqlite3VdbeMemSetBlob(pMem, zBlob, 0, n >= 0 ? n : zBlob.Length, enc, xDel); }