{ if ( ( P.flags & MEM_Zero ) != 0 ) sqlite3VdbeMemExpandBlob( P ); } // TODO -- Convert to inline for speed /* ** If pMem is an object with a valid string representation, this routine ** ensures the internal encoding for the string representation is ** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. ** ** If pMem is not a string object, or the encoding of the string ** representation is already stored using the requested encoding, then this ** routine is a no-op. ** ** SQLITE_OK is returned if the conversion is successful (or not required). ** SQLITE_NOMEM may be returned if a malloc() fails during conversion ** between formats. */ static int sqlite3VdbeChangeEncoding( MemRef pMem, int desiredEnc ) { int rc; Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); Debug.Assert( desiredEnc == SQLITE_UTF8 || desiredEnc == SQLITE_UTF16LE || desiredEnc == SQLITE_UTF16BE ); if ( ( pMem.flags & MEM_Str ) == 0 || pMem.enc == desiredEnc ) { if ( pMem.z == null && pMem.zBLOB != null ) pMem.z = Encoding.UTF8.GetString( pMem.zBLOB ); return SQLITE_OK; } Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); #if SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); Debug.Assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); Debug.Assert(rc==SQLITE_OK || pMem.enc!=desiredEnc); Debug.Assert(rc==SQLITE_NOMEM || pMem.enc==desiredEnc); return rc; #endif }
/* ** Create a new sqlite3_value object. */ static sqlite3_value sqlite3ValueNew( sqlite3 db ) { MemRef p = new MemRef();//sqlite3DbMallocZero(db, sizeof(*p)); if ( p != null ) { p.flags = MEM_Null; p.type = SQLITE_NULL; p.db = db; } return p; }
/* ** Compare the values contained by the two memory cells, returning ** negative, zero or positive if pMem1 is less than, equal to, or greater ** than pMem2. Sorting order is NULL's first, followed by numbers (integers ** and reals) sorted numerically, followed by text ordered by the collating ** sequence pColl and finally blob's ordered by memcmp(). ** ** Two NULL values are considered equal by this function. */ static int sqlite3MemCompare( MemRef pMem1, MemRef pMem2, CollSeq pColl ) { int rc; int f1, f2; int combined_flags; /* Interchange pMem1 and pMem2 if the collating sequence specifies ** DESC order. */ f1 = pMem1.flags; f2 = pMem2.flags; combined_flags = f1 | f2; Debug.Assert( ( combined_flags & MEM_RowSet ) == 0 ); /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ if ( ( combined_flags & MEM_Null ) != 0 ) { return ( f2 & MEM_Null ) - ( f1 & MEM_Null ); } /* If one value is a number and the other is not, the number is less. ** If both are numbers, compare as reals if one is a real, or as integers ** if both values are integers. */ if ( ( combined_flags & ( MEM_Int | MEM_Real ) ) != 0 ) { if ( ( f1 & ( MEM_Int | MEM_Real ) ) == 0 ) { return 1; } if ( ( f2 & ( MEM_Int | MEM_Real ) ) == 0 ) { return -1; } if ( ( f1 & f2 & MEM_Int ) == 0 ) { double r1, r2; if ( ( f1 & MEM_Real ) == 0 ) { r1 = (double)pMem1.ui; } else { r1 = pMem1.r; } if ( ( f2 & MEM_Real ) == 0 ) { r2 = (double)pMem2.ui; } else { r2 = pMem2.r; } if ( r1 < r2 ) return -1; if ( r1 > r2 ) return 1; return 0; } else { Debug.Assert( ( f1 & MEM_Int ) != 0 ); Debug.Assert( ( f2 & MEM_Int ) != 0 ); if ( pMem1.ui < pMem2.ui ) return -1; if ( pMem1.ui > pMem2.ui ) return 1; return 0; } } /* If one value is a string and the other is a blob, the string is less. ** If both are strings, compare using the collating functions. */ if ( ( combined_flags & MEM_Str ) != 0 ) { if ( ( f1 & MEM_Str ) == 0 ) { return 1; } if ( ( f2 & MEM_Str ) == 0 ) { return -1; } Debug.Assert( pMem1.enc == pMem2.enc ); Debug.Assert( pMem1.enc == SQLITE_UTF8 || pMem1.enc == SQLITE_UTF16LE || pMem1.enc == SQLITE_UTF16BE ); /* The collation sequence must be defined at this point, even if ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ Debug.Assert( pColl == null || pColl.xCmp != null ); if ( pColl != null ) { if ( pMem1.enc == pColl.enc ) { /* The strings are already in the correct encoding. Call the ** comparison function directly */ return pColl.xCmp( pColl.pUser, pMem1.n, pMem1.z, pMem2.n, pMem2.z ); } else { string v1, v2; int n1, n2; MemRef c1; MemRef c2; c1 = new MemRef();// memset( &c1, 0, sizeof( c1 ) ); c2 = new MemRef();//memset( &c2, 0, sizeof( c2 ) ); sqlite3VdbeMemShallowCopy( c1, pMem1, MEM_Ephem ); sqlite3VdbeMemShallowCopy( c2, pMem2, MEM_Ephem ); v1 = sqlite3ValueText( (sqlite3_value)c1, pColl.enc ); n1 = v1 == null ? 0 : c1.n; v2 = sqlite3ValueText( (sqlite3_value)c2, pColl.enc ); n2 = v2 == null ? 0 : c2.n; rc = pColl.xCmp( pColl.pUser, n1, v1, n2, v2 ); sqlite3VdbeMemRelease( c1 ); sqlite3VdbeMemRelease( c2 ); return rc; } } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } /* Both values must be blobs. Compare using memcmp(). */ if ( ( pMem1.flags & MEM_Blob ) != 0 ) if ( pMem1.zBLOB != null ) rc = memcmp( pMem1.zBLOB, pMem2.zBLOB, ( pMem1.n > pMem2.n ) ? pMem2.n : pMem1.n ); else rc = memcmp( pMem1.z, pMem2.zBLOB, ( pMem1.n > pMem2.n ) ? pMem2.n : pMem1.n ); else rc = memcmp( pMem1.z, pMem2.z, ( pMem1.n > pMem2.n ) ? pMem2.n : pMem1.n ); if ( rc == 0 ) { rc = pMem1.n - pMem2.n; } return rc; }
/* ** Transfer the contents of pFrom to pTo. Any existing value in pTo is ** freed. If pFrom contains ephemeral data, a copy is made. ** ** pFrom contains an SQL NULL when this routine returns. */ static void sqlite3VdbeMemMove( ref Mem pTo, MemRef pFrom ) { Debug.Assert( pFrom.db == null || sqlite3_mutex_held( pFrom.db.mutex ) ); Debug.Assert( pTo.db == null || sqlite3_mutex_held( pTo.db.mutex ) ); Debug.Assert( pFrom.db == null || pTo.db == null || pFrom.db == pTo.db ); sqlite3VdbeMemRelease( ref pTo ); pFrom.CopyTo( ref pTo );// memcpy(pTo, pFrom, Mem).Length; pFrom.flags = MEM_Null; pFrom.xDel = null; pFrom.z = null; pFrom.zBLOB = null; //pFrom.zMalloc=null; }
/* ** Make a full copy of pFrom into pTo. Prior contents of pTo are ** freed before the copy is made. */ static int sqlite3VdbeMemCopy( MemRef pTo, MemRef pFrom ) { int rc = SQLITE_OK; Debug.Assert( ( pFrom.flags & MEM_RowSet ) == 0 ); sqlite3VdbeMemReleaseExternal( pTo ); pFrom.CopyTo( pTo );// memcpy(pTo, pFrom, MEMCELLSIZE); pTo.flags = (u16)( pTo.flags & ~MEM_Dyn ); if ( ( pTo.flags & ( MEM_Str | MEM_Blob ) ) != 0 ) { if ( 0 == ( pFrom.flags & MEM_Static ) ) { pTo.flags |= MEM_Ephem; rc = sqlite3VdbeMemMakeWriteable( pTo ); } } return rc; }
/* ** Return true if the Mem object contains a TEXT or BLOB that is ** too large - whose size exceeds p.db.aLimit[SQLITE_LIMIT_LENGTH]. */ static bool sqlite3VdbeMemTooBig( MemRef p ) { Debug.Assert( p.db != null ); if ( ( p.flags & ( MEM_Str | MEM_Blob ) ) != 0 ) { int n = p.n; if ( ( p.flags & MEM_Zero ) != 0 ) { n += p.unZero; } return n > p.db.aLimit[SQLITE_LIMIT_LENGTH]; } return false; }
/* ** Delete any previous value and set the value of pMem to be an ** empty boolean index. */ static void sqlite3VdbeMemSetRowSet( MemRef pMem ) { sqlite3 db = pMem.db; Debug.Assert( db != null ); Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); sqlite3VdbeMemRelease( pMem ); //pMem.zMalloc = sqlite3DbMallocRaw( db, 64 ); //if ( db.mallocFailed != 0 ) //{ // pMem.flags = MEM_Null; //} //else { //Debug.Assert( pMem.zMalloc ); pMem.upRowSet = new RowSet( db, 5 );// sqlite3RowSetInit( db, pMem.zMalloc, // sqlite3DbMallocSize( db, pMem.zMalloc ) ); Debug.Assert( pMem.upRowSet != null ); pMem.flags = MEM_RowSet; } }
/* ** Delete any previous value and set the value stored in pMem to val, ** manifest type INTEGER. */ static void sqlite3VdbeMemSetInt64( MemRef pMem, i64 val ) { sqlite3VdbeMemRelease( pMem ); pMem.ui = val; pMem.flags = MEM_Int; pMem.type = SQLITE_INTEGER; }
static void sqlite3VdbeMemRelease (MemRef p) { sqlite3VdbeMemRelease(ref p.inner); }
static void sqlite3VdbeMemReleaseExternal (MemRef p) { sqlite3VdbeMemReleaseExternal(ref p.inner); }
static int sqlite3VdbeMemFinalize (MemRef pMem, FuncDef pFunc) { return sqlite3VdbeMemFinalize(ref pMem.inner, pFunc); }
/* ** Add MEM_Str to the set of representations for the given Mem. Numbers ** are converted using sqlite3_snprintf(). Converting a BLOB to a string ** is a no-op. ** ** Existing representations MEM_Int and MEM_Real are *not* invalidated. ** ** A MEM_Null value will never be passed to this function. This function is ** used for converting values to text for returning to the user (i.e. via ** sqlite3_value_text()), or for ensuring that values to be used as btree ** keys are strings. In the former case a NULL pointer is returned the ** user and the later is an internal programming error. */ static int sqlite3VdbeMemStringify( MemRef pMem, int enc ) { int rc = SQLITE_OK; int fg = pMem.flags; const int nByte = 32; Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); Debug.Assert( ( fg & MEM_Zero ) == 0 ); Debug.Assert( ( fg & ( MEM_Str | MEM_Blob ) ) == 0 ); Debug.Assert( ( fg & ( MEM_Int | MEM_Real ) ) != 0 ); Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if ( sqlite3VdbeMemGrow( pMem, nByte, 0 ) != 0 ) { return SQLITE_NOMEM; } /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 ** string representation of the value. Then, if the required encoding ** is UTF-16le or UTF-16be do a translation. ** ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. */ if ( ( fg & MEM_Int ) != 0 ) { pMem.z = pMem.ui.ToString(); //sqlite3_snprintf(nByte, pMem.z, "%lld", pMem->u.i); } else { Debug.Assert( ( fg & MEM_Real ) != 0 ); if ( Double.IsNegativeInfinity( pMem.r ) ) pMem.z = "-Inf"; else if ( Double.IsInfinity( pMem.r ) ) pMem.z = "Inf"; else if ( Double.IsPositiveInfinity( pMem.r ) ) pMem.z = "+Inf"; else if ( pMem.r.ToString().Contains( "." ) ) pMem.z = pMem.r.ToString().ToLower();//sqlite3_snprintf(nByte, pMem.z, "%!.15g", pMem->r); else pMem.z = pMem.r.ToString() + ".0"; } pMem.n = sqlite3Strlen30( pMem.z ); pMem.enc = SQLITE_UTF8; pMem.flags |= MEM_Str | MEM_Term; sqlite3VdbeChangeEncoding( pMem, enc ); return rc; }
/* ** Make sure the given Mem is \u0000 terminated. */ static int sqlite3VdbeMemNulTerminate( MemRef pMem ) { Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); if ( ( pMem.flags & MEM_Term ) != 0 || ( pMem.flags & MEM_Str ) == 0 ) { return SQLITE_OK; /* Nothing to do */ } //if ( pMem.n != 0 && sqlite3VdbeMemGrow( pMem, pMem.n + 2, 1 ) != 0 ) //{ // return SQLITE_NOMEM; //} // pMem.z[pMem->n] = 0; // pMem.z[pMem->n+1] = 0; if ( pMem.z != null && pMem.n < pMem.z.Length ) pMem.z = pMem.z.Substring( 0, pMem.n ); pMem.flags |= MEM_Term; return SQLITE_OK; }
/* ** If the given Mem* has a zero-filled tail, turn it into an ordinary ** blob stored in dynamically allocated space. */ #if !SQLITE_OMIT_INCRBLOB static int sqlite3VdbeMemExpandBlob( MemRef pMem ) { if ( ( pMem.flags & MEM_Zero ) != 0 ) { u32 nByte; Debug.Assert( ( pMem.flags & MEM_Blob ) != 0 ); Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); /* Set nByte to the number of bytes required to store the expanded blob. */ nByte = (u32)( pMem.n + pMem.unZero ); if ( nByte <= 0 ) { nByte = 1; } if ( sqlite3VdbeMemGrow( pMem, (int)nByte, 1 ) != 0 ) { return SQLITE_NOMEM; } /* Set nByte to the number of bytes required to store the expanded blob. */ nByte = (u32)( pMem.n + pMem.unZero ); if ( nByte <= 0 ) { nByte = 1; } if ( sqlite3VdbeMemGrow( pMem, (int)nByte, 1 ) != 0 ) { return SQLITE_NOMEM; } //memset(&pMem->z[pMem->n], 0, pMem->u.nZero); pMem.zBLOB = Encoding.UTF8.GetBytes( pMem.z ); pMem.z = null; pMem.n += (int)pMem.unZero; pMem.ui = 0; pMem.flags = (u16)( pMem.flags & ~( MEM_Zero | MEM_Static | MEM_Ephem | MEM_Term ) ); pMem.flags |= MEM_Dyn; } return SQLITE_OK; }
/* ** Make the given Mem object MEM_Dyn. In other words, make it so ** that any TEXT or BLOB content is stored in memory obtained from ** malloc(). In this way, we know that the memory is safe to be ** overwritten or altered. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ static int sqlite3VdbeMemMakeWriteable( MemRef pMem ) { int f; Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); expandBlob( pMem ); f = pMem.flags; if ( ( f & ( MEM_Str | MEM_Blob ) ) != 0 ) // TODO -- && pMem.z != pMem.zMalloc ) { //if ( sqlite3VdbeMemGrow( pMem, pMem.n + 2, 1 ) != 0 ) //{ // return SQLITE_NOMEM; //} //pMem.z[pMem->n] = 0; //pMem.z[pMem->n + 1] = 0; pMem.flags |= MEM_Term; } return SQLITE_OK; }
/* ** Delete any previous value and set the value stored in pMem to NULL. */ static void sqlite3VdbeMemSetNull( MemRef pMem ) { if ( ( pMem.flags & MEM_RowSet ) != 0 ) { sqlite3RowSetClear( pMem.upRowSet ); } MemSetTypeFlag( pMem, MEM_Null ); pMem.zBLOB = null; pMem.z = null; pMem.type = SQLITE_NULL; }
/* ** Delete any previous value and set the value to be a BLOB of length ** n containing all zeros. */ static void sqlite3VdbeMemSetZeroBlob( MemRef pMem, int n ) { sqlite3VdbeMemRelease( pMem ); pMem.flags = MEM_Blob | MEM_Zero; pMem.type = SQLITE_BLOB; pMem.n = 0; if ( n < 0 ) n = 0; pMem.unZero = n; pMem.enc = SQLITE_UTF8; #if SQLITE_OMIT_INCRBLOB sqlite3VdbeMemGrow(pMem, n, 0); //if( pMem.z!= null ){ pMem.n = n; pMem.z = null;//memset(pMem.z, 0, n); pMem.zBLOB = new byte[n]; //} #endif }
/* ** Return some kind of integer value which is the best we can do ** at representing the value that *pMem describes as an integer. ** If pMem is an integer, then the value is exact. If pMem is ** a floating-point then the value returned is the integer part. ** If pMem is a string or blob, then we make an attempt to convert ** it into a integer and return that. If pMem represents an ** an SQL-NULL value, return 0. ** ** If pMem represents a string value, its encoding might be changed. */ static i64 sqlite3VdbeIntValue( MemRef pMem ) { int flags; Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); // assert( EIGHT_BYTE_ALIGNMENT(pMem) ); flags = pMem.flags; if ( ( flags & MEM_Int ) != 0 ) { return pMem.ui; } else if ( ( flags & MEM_Real ) != 0 ) { return doubleToInt64( pMem.r ); } else if ( ( flags & ( MEM_Str | MEM_Blob ) ) != 0 ) { i64 value = 0; pMem.flags |= MEM_Str; if ( sqlite3VdbeChangeEncoding( pMem, SQLITE_UTF8 ) != 0 || ( sqlite3VdbeMemNulTerminate( pMem ) != 0 ) ) { return 0; } if ( pMem.z == null ) return 0; Debug.Assert( pMem.z != null ); sqlite3Atoi64( pMem.z, ref value ); return value; } else { return 0; } }
/* ** Delete any previous value and set the value stored in pMem to val, ** manifest type REAL. */ static void sqlite3VdbeMemSetDouble( MemRef pMem, double val ) { if ( sqlite3IsNaN( val ) ) { sqlite3VdbeMemSetNull( pMem ); } else { sqlite3VdbeMemRelease( pMem ); pMem.r = val; pMem.flags = MEM_Real; pMem.type = SQLITE_FLOAT; } }
/* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ static double sqlite3VdbeRealValue( MemRef pMem ) { Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if ( ( pMem.flags & MEM_Real ) != 0 ) { return pMem.r; } else if ( ( pMem.flags & MEM_Int ) != 0 ) { return (double)pMem.ui; } else if ( ( pMem.flags & ( MEM_Str | MEM_Blob ) ) != 0 ) { /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ double val = (double)0; pMem.flags |= MEM_Str; if ( sqlite3VdbeChangeEncoding( pMem, SQLITE_UTF8 ) != 0 || sqlite3VdbeMemNulTerminate( pMem ) != 0 ) { /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } if ( pMem.zBLOB != null ) sqlite3AtoF( Encoding.UTF8.GetString( pMem.zBLOB ), ref val ); else if ( pMem.z != null ) sqlite3AtoF( pMem.z, ref val ); else val = 0.0; return val; } else { /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } }
/* ** 2004 May 26 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** ** $Id: vdbemem.c,v 1.152 2009/07/22 18:07:41 drh Exp $ ** ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** $Header$ ************************************************************************* */ //#include "sqliteInt.h" //#include "vdbeInt.h" /* ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ** P if required. */ //#define expandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) static void expandBlob( MemRef P ) { if ( ( P.flags & MEM_Zero ) != 0 ) sqlite3VdbeMemExpandBlob( P ); } // TODO -- Convert to inline for speed
/* ** The MEM structure is already a MEM_Real. Try to also make it a ** MEM_Int if we can. */ static void sqlite3VdbeIntegerAffinity( MemRef pMem ) { Debug.Assert( ( pMem.flags & MEM_Real ) != 0 ); Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem.ui = doubleToInt64( pMem.r ); /* Only mark the value as an integer if ** ** (1) the round-trip conversion real->int->real is a no-op, and ** (2) The integer is neither the largest nor the smallest ** possible integer (ticket #3922) ** ** The second term in the following conditional enforces the second ** condition under the assumption that additional overflow causes ** values to wrap around. */ if ( pMem.r == (double)pMem.ui && ( pMem.ui - 1 ) < ( pMem.ui + 1 ) ) { pMem.flags |= MEM_Int; } }
/* ** Size of struct Mem not including the Mem.zMalloc member. */ //#define MEMCELLSIZE (size_t)(&(((Mem *)0).zMalloc)) /* ** Make an shallow copy of pFrom into pTo. Prior contents of ** pTo are freed. The pFrom.z field is not duplicated. If ** pFrom.z is used, then pTo.z points to the same thing as pFrom.z ** and flags gets srcType (either MEM_Ephem or MEM_Static). */ static void sqlite3VdbeMemShallowCopy( MemRef pTo, MemRef pFrom, int srcType ) { Debug.Assert( ( pFrom.flags & MEM_RowSet ) == 0 ); sqlite3VdbeMemReleaseExternal( pTo ); pFrom.CopyTo( pTo );// memcpy(pTo, pFrom, MEMCELLSIZE); pTo.xDel = null; if ( ( pFrom.flags & MEM_Dyn ) != 0 ) {//|| pFrom.z==pFrom.zMalloc ){ pTo.flags = (u16)( pFrom.flags & ~( MEM_Dyn | MEM_Static | MEM_Ephem ) ); Debug.Assert( srcType == MEM_Ephem || srcType == MEM_Static ); pTo.flags |= (u16)srcType; } }
/* ** Convert pMem to type integer. Invalidate any prior representations. */ static int sqlite3VdbeMemIntegerify( MemRef pMem ) { Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem.ui = sqlite3VdbeIntValue( pMem ); MemSetTypeFlag( pMem, MEM_Int ); return SQLITE_OK; }
static void sqlite3VdbeMemMove (MemRef pTo, MemRef pFrom) { sqlite3VdbeMemMove(ref pTo.inner, pFrom); }
/* ** Convert pMem so that it is of type MEM_Real. ** Invalidate any prior representations. */ static int sqlite3VdbeMemRealify( MemRef pMem ) { Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem.r = sqlite3VdbeRealValue( pMem ); MemSetTypeFlag( pMem, MEM_Real ); return SQLITE_OK; }
/* ** 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. */ static int sqlite3VdbeMemSetStr( MemRef 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//)(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 ) { 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 && z[nByte] != 0 ; nByte++ ) { } } else { for ( nByte = 0 ; nByte <= iLimit && z[nByte] != 0 || z[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 = new byte[n]; for ( int i = 0 ; i < n && i < z.Length ; i++ ) pMem.zBLOB[i] = (byte)z[i]; } else { pMem.z = z;//memcpy(pMem.z, z, nAlloc); pMem.zBLOB = null; } } else if ( xDel == SQLITE_DYNAMIC ) { sqlite3VdbeMemRelease( pMem ); //pMem.zMalloc = pMem.z = (char*)z; if ( enc == 0 ) { pMem.z = null; pMem.zBLOB = Encoding.UTF8.GetBytes( z ); } else { pMem.z = z;//memcpy(pMem.z, z, nAlloc); pMem.zBLOB = null; } pMem.xDel = null; } else { sqlite3VdbeMemRelease( pMem ); if ( enc == 0 ) { pMem.z = null; pMem.zBLOB = Encoding.UTF8.GetBytes( z ); } else { pMem.z = z;//memcpy(pMem.z, z, nAlloc); pMem.zBLOB = null; } 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; }
/* ** Convert pMem so that it has types MEM_Real or MEM_Int or both. ** Invalidate any prior representations. */ static int sqlite3VdbeMemNumerify( MemRef pMem ) { double r1, r2; i64 i; Debug.Assert( ( pMem.flags & ( MEM_Int | MEM_Real | MEM_Null ) ) == 0 ); Debug.Assert( ( pMem.flags & ( MEM_Blob | MEM_Str ) ) != 0 ); Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); r1 = sqlite3VdbeRealValue( pMem ); i = doubleToInt64( r1 ); r2 = (double)i; if ( r1 == r2 ) { sqlite3VdbeMemIntegerify( pMem ); } else { pMem.r = r1; MemSetTypeFlag( pMem, MEM_Real ); } return SQLITE_OK; }
static int sqlite3VdbeMemGrow (MemRef pMem, int n, int preserve) { return sqlite3VdbeMemGrow(ref pMem.inner, n, preserve); }
static int sqlite3VdbeMemFromBtree ( BtCursor pCur, /* Cursor pointing at record to retrieve. */ int offset, /* Offset from the start of data to return bytes from. */ int amt, /* Number of bytes to return. */ bool key, /* If true, retrieve from the btree key, not data. */ MemRef pMem /* OUT: Return data in this Mem structure. */ ) { return sqlite3VdbeMemFromBtree(pCur, offset, amt, key, ref pMem.inner); }