Exemplo n.º 1
0
/*
** Change the value of a Mem to be a string or a BLOB.
*/
int sqlite3VdbeMemSetStr(
  Mem *pMem,          /* Memory cell to set to string value */
  const char *z,      /* String pointer */
  int n,              /* Bytes in string, or negative */
  u8 enc,             /* Encoding of z.  0 for BLOBs */
  void (*xDel)(void*) /* Destructor function */
){
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  sqlite3VdbeMemRelease(pMem);
  if( !z ){
    pMem->flags = MEM_Null;
    pMem->type = SQLITE_NULL;
    return SQLITE_OK;
  }
  pMem->z = (char *)z;
  if( xDel==SQLITE_STATIC ){
    pMem->flags = MEM_Static;
  }else if( xDel==SQLITE_TRANSIENT ){
    pMem->flags = MEM_Ephem;
  }else{
    pMem->flags = MEM_Dyn;
    pMem->xDel = xDel;
  }

  pMem->enc = enc;
  pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT;
  pMem->n = n;

  assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE 
      || enc==SQLITE_UTF16BE );
  switch( enc ){
    case 0:
      pMem->flags |= MEM_Blob;
      pMem->enc = SQLITE_UTF8;
      break;

    case SQLITE_UTF8:
      pMem->flags |= MEM_Str;
      if( n<0 ){
        pMem->n = strlen(z);
        pMem->flags |= MEM_Term;
      }
      break;

#ifndef SQLITE_OMIT_UTF16
    case SQLITE_UTF16LE:
    case SQLITE_UTF16BE:
      pMem->flags |= MEM_Str;
      if( pMem->n<0 ){
        pMem->n = sqlite3Utf16ByteLen(pMem->z,-1);
        pMem->flags |= MEM_Term;
      }
      if( sqlite3VdbeMemHandleBom(pMem) ){
        return SQLITE_NOMEM;
      }
#endif /* SQLITE_OMIT_UTF16 */
  }
  if( pMem->flags&MEM_Ephem ){
    return sqlite3VdbeMemMakeWriteable(pMem);
  }
  return SQLITE_OK;
}
Exemplo n.º 2
0
/*
 ** 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.
 */
SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
                                        Mem *pMem,          /* Memory cell to set to string value */
                                        const char *z,      /* String pointer */
                                        int n,              /* Bytes in string, or negative */
                                        u8 enc,             /* Encoding of z.  0 for BLOBs */
                                        void (*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 */
    
    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
    assert( (pMem->flags & MEM_RowSet)==0 );
    
    /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
    if( !z ){
        sqlite3VdbeMemSetNull(pMem);
        return SQLITE_OK;
    }
    
    if( pMem->db ){
        iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
    }else{
        iLimit = SQLITE_MAX_LENGTH;
    }
    flags = (enc==0?MEM_Blob:MEM_Str);
    if( nByte<0 ){
        assert( enc!=0 );
        if( enc==SQLITE_UTF8 ){
            for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
        }else{
            for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); 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 ){
        int nAlloc = nByte;
        if( flags&MEM_Term ){
            nAlloc += (enc==SQLITE_UTF8?1:2);
        }
        if( nByte>iLimit ){
            return SQLITE_TOOBIG;
        }
        if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
            return SQLITE_NOMEM;
        }
        memcpy(pMem->z, z, nAlloc);
    }else if( xDel==SQLITE_DYNAMIC ){
        sqlite3VdbeMemRelease(pMem);
        pMem->zMalloc = pMem->z = (char *)z;
        pMem->xDel = 0;
    }else{
        sqlite3VdbeMemRelease(pMem);
        pMem->z = (char *)z;
        pMem->xDel = xDel;
        flags |= ((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);
    
#ifndef SQLITE_OMIT_UTF16
    if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
        return SQLITE_NOMEM;
    }
#endif
    
    if( nByte>iLimit ){
        return SQLITE_TOOBIG;
    }
    
    return SQLITE_OK;
}