⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdbeaux.c

📁 嵌入式数据系统软件!
💻 C
📖 第 1 页 / 共 5 页
字号:
**      3                     3            signed integer**      4                     4            signed integer**      5                     6            signed integer**      6                     8            signed integer**      7                     8            IEEE float**      8                     0            Integer constant 0**      9                     0            Integer constant 1**     10,11                               reserved for expansion**    N>=12 and even       (N-12)/2        BLOB**    N>=13 and odd        (N-13)/2        text**** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions** of SQLite will not understand those serial types.*//*** Return the serial-type for the value stored in pMem.*/u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){  int flags = pMem->flags;  int n;  if( flags&MEM_Null ){    return 0;  }  if( flags&MEM_Int ){    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */#   define MAX_6BYTE ((((i64)0x00001000)<<32)-1)    i64 i = pMem->u.i;    u64 u;    if( file_format>=4 && (i&1)==i ){      return 8+i;    }    u = i<0 ? -i : i;    if( u<=127 ) return 1;    if( u<=32767 ) return 2;    if( u<=8388607 ) return 3;    if( u<=2147483647 ) return 4;    if( u<=MAX_6BYTE ) return 5;    return 6;  }  if( flags&MEM_Real ){    return 7;  }  assert( flags&(MEM_Str|MEM_Blob) );  n = pMem->n;  if( flags & MEM_Zero ){    n += pMem->u.i;  }  assert( n>=0 );  return ((n*2) + 12 + ((flags&MEM_Str)!=0));}/*** Return the length of the data corresponding to the supplied serial-type.*/int sqlite3VdbeSerialTypeLen(u32 serial_type){  if( serial_type>=12 ){    return (serial_type-12)/2;  }else{    static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };    return aSize[serial_type];  }}/*** If we are on an architecture with mixed-endian floating ** points (ex: ARM7) then swap the lower 4 bytes with the ** upper 4 bytes.  Return the result.**** For most architectures, this is a no-op.**** (later):  It is reported to me that the mixed-endian problem** on ARM7 is an issue with GCC, not with the ARM7 chip.  It seems** that early versions of GCC stored the two words of a 64-bit** float in the wrong order.  And that error has been propagated** ever since.  The blame is not necessarily with GCC, though.** GCC might have just copying the problem from a prior compiler.** I am also told that newer versions of GCC that follow a different** ABI get the byte order right.**** Developers using SQLite on an ARM7 should compile and run their** application using -DSQLITE_DEBUG=1 at least once.  With DEBUG** enabled, some asserts below will ensure that the byte order of** floating point values is correct.**** (2007-08-30)  Frank van Vugt has studied this problem closely** and has send his findings to the SQLite developers.  Frank** writes that some Linux kernels offer floating point hardware** emulation that uses only 32-bit mantissas instead of a full ** 48-bits as required by the IEEE standard.  (This is the** CONFIG_FPE_FASTFPE option.)  On such systems, floating point** byte swapping becomes very complicated.  To avoid problems,** the necessary byte swapping is carried out using a 64-bit integer** rather than a 64-bit float.  Frank assures us that the code here** works for him.  We, the developers, have no way to independently** verify this, but Frank seems to know what he is talking about** so we trust him.*/#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOATstatic u64 floatSwap(u64 in){  union {    u64 r;    u32 i[2];  } u;  u32 t;  u.r = in;  t = u.i[0];  u.i[0] = u.i[1];  u.i[1] = t;  return u.r;}# define swapMixedEndianFloat(X)  X = floatSwap(X)#else# define swapMixedEndianFloat(X)#endif/*** Write the serialized data blob for the value stored in pMem into ** buf. It is assumed that the caller has allocated sufficient space.** Return the number of bytes written.**** nBuf is the amount of space left in buf[].  nBuf must always be** large enough to hold the entire field.  Except, if the field is** a blob with a zero-filled tail, then buf[] might be just the right** size to hold everything except for the zero-filled tail.  If buf[]** is only big enough to hold the non-zero prefix, then only write that** prefix into buf[].  But if buf[] is large enough to hold both the** prefix and the tail then write the prefix and set the tail to all** zeros.**** Return the number of bytes actually written into buf[].  The number** of bytes in the zero-filled tail is included in the return value only** if those bytes were zeroed in buf[].*/ int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){  u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);  int len;  /* Integer and Real */  if( serial_type<=7 && serial_type>0 ){    u64 v;    int i;    if( serial_type==7 ){      assert( sizeof(v)==sizeof(pMem->r) );      memcpy(&v, &pMem->r, sizeof(v));      swapMixedEndianFloat(v);    }else{      v = pMem->u.i;    }    len = i = sqlite3VdbeSerialTypeLen(serial_type);    assert( len<=nBuf );    while( i-- ){      buf[i] = (v&0xFF);      v >>= 8;    }    return len;  }  /* String or blob */  if( serial_type>=12 ){    assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.i:0)             == sqlite3VdbeSerialTypeLen(serial_type) );    assert( pMem->n<=nBuf );    len = pMem->n;    memcpy(buf, pMem->z, len);    if( pMem->flags & MEM_Zero ){      len += pMem->u.i;      if( len>nBuf ){        len = nBuf;      }      memset(&buf[pMem->n], 0, len-pMem->n);    }    return len;  }  /* NULL or constants 0 or 1 */  return 0;}/*** Deserialize the data blob pointed to by buf as serial type serial_type** and store the result in pMem.  Return the number of bytes read.*/ int sqlite3VdbeSerialGet(  const unsigned char *buf,     /* Buffer to deserialize from */  u32 serial_type,              /* Serial type to deserialize */  Mem *pMem                     /* Memory cell to write value into */){  switch( serial_type ){    case 10:   /* Reserved for future use */    case 11:   /* Reserved for future use */    case 0: {  /* NULL */      pMem->flags = MEM_Null;      break;    }    case 1: { /* 1-byte signed integer */      pMem->u.i = (signed char)buf[0];      pMem->flags = MEM_Int;      return 1;    }    case 2: { /* 2-byte signed integer */      pMem->u.i = (((signed char)buf[0])<<8) | buf[1];      pMem->flags = MEM_Int;      return 2;    }    case 3: { /* 3-byte signed integer */      pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];      pMem->flags = MEM_Int;      return 3;    }    case 4: { /* 4-byte signed integer */      pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];      pMem->flags = MEM_Int;      return 4;    }    case 5: { /* 6-byte signed integer */      u64 x = (((signed char)buf[0])<<8) | buf[1];      u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];      x = (x<<32) | y;      pMem->u.i = *(i64*)&x;      pMem->flags = MEM_Int;      return 6;    }    case 6:   /* 8-byte signed integer */    case 7: { /* IEEE floating point */      u64 x;      u32 y;#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)      /* Verify that integers and floating point values use the same      ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is      ** defined that 64-bit floating point values really are mixed      ** endian.      */      static const u64 t1 = ((u64)0x3ff00000)<<32;      static const double r1 = 1.0;      u64 t2 = t1;      swapMixedEndianFloat(t2);      assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );#endif      x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];      y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];      x = (x<<32) | y;      if( serial_type==6 ){        pMem->u.i = *(i64*)&x;        pMem->flags = MEM_Int;      }else{        assert( sizeof(x)==8 && sizeof(pMem->r)==8 );        swapMixedEndianFloat(x);        memcpy(&pMem->r, &x, sizeof(x));        pMem->flags = MEM_Real;      }      return 8;    }    case 8:    /* Integer 0 */    case 9: {  /* Integer 1 */      pMem->u.i = serial_type-8;      pMem->flags = MEM_Int;      return 0;    }    default: {      int len = (serial_type-12)/2;      pMem->z = (char *)buf;      pMem->n = len;      pMem->xDel = 0;      if( serial_type&0x01 ){        pMem->flags = MEM_Str | MEM_Ephem;      }else{        pMem->flags = MEM_Blob | MEM_Ephem;      }      return len;    }  }  return 0;}/*** The header of a record consists of a sequence variable-length integers.** These integers are almost always small and are encoded as a single byte.** The following macro takes advantage this fact to provide a fast decode** of the integers in a record header.  It is faster for the common case** where the integer is a single byte.  It is a little slower when the** integer is two or more bytes.  But overall it is faster.**** The following expressions are equivalent:****     x = sqlite3GetVarint32( A, &B );****     x = GetVarint( A, B );***/#define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))/*** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero** or positive integer if {nKey1, pKey1} is less than, equal to or ** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings** composed by the OP_MakeRecord opcode of the VDBE.*/int sqlite3VdbeRecordCompare(  void *userData,  int nKey1, const void *pKey1,   int nKey2, const void *pKey2){  KeyInfo *pKeyInfo = (KeyInfo*)userData;  u32 d1, d2;          /* Offset into aKey[] of next data element */  u32 idx1, idx2;      /* Offset into aKey[] of next header element */  u32 szHdr1, szHdr2;  /* Number of bytes in header */  int i = 0;  int nField;  int rc = 0;  const unsigned char *aKey1 = (const unsigned char *)pKey1;  const unsigned char *aKey2 = (const unsigned char *)pKey2;  Mem mem1;  Mem mem2;  mem1.enc = pKeyInfo->enc;  mem1.db = pKeyInfo->db;  mem2.enc = pKeyInfo->enc;  mem2.db = pKeyInfo->db;    idx1 = GetVarint(aKey1, szHdr1);  d1 = szHdr1;  idx2 = GetVarint(aKey2, szHdr2);  d2 = szHdr2;  nField = pKeyInfo->nField;  while( idx1<szHdr1 && idx2<szHdr2 ){    u32 serial_type1;    u32 serial_type2;    /* Read the serial types for the next element in each key. */    idx1 += GetVarint( aKey1+idx1, serial_type1 );    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;    idx2 += GetVarint( aKey2+idx2, serial_type2 );    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;    /* Extract the values to be compared.    */    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);    /* Do the comparison    */    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);    if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);    if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);    if( rc!=0 ){      break;    }    i++;  }  /* One of the keys ran out of fields, but all the fields up to that point  ** were equal. If the incrKey flag is true, then the second key is  ** treated as larger.  */  if( rc==0 ){    if( pKeyInfo->incrKey ){      rc = -1;    }else if( !pKeyInfo->prefixIsEqual ){      if( d1<nKey1 ){        rc = 1;      }else if( d2<nKey2 ){        rc = -1;      }    }  }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField               && pKeyInfo->aSortOrder[i] ){    rc = -rc;  }  return rc;}/*** The argument is an index entry composed using the OP_MakeRecord opcode.** The last entry in this record should be an integer (specifically** an integer rowid).  This routine returns the number of bytes in** that integer.*/int sqlite3VdbeIdxRowidLen(const u8 *aKey){  u32 szHdr;        /* Size of the header */  u32 typeRowid;    /* Serial type of the rowid */  sqlite3GetVarint32(aKey, &szHdr);  sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid);  return sqlite3VdbeSerialTypeLen(typeRowid);}  /*** pCur points at an index entry created using the OP_MakeRecord opcode.** Read the rowid (the last field in the record) and store it in *rowid.** Return SQLITE_OK if everything works, or an error code otherwise.*/int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){  i64 nCellKey = 0;  int rc;  u32 szHdr;        /* Size of the header */  u32 typeRowid;    /* Serial type of the rowid */  u32 lenRowid;     /* Size of the rowid */  Mem m, v;  sqlite3BtreeKeySize(pCur, &nCellKey);  if( nCellKey<=0 ){    return SQLITE_CORRUPT_BKPT;  }  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);  if( rc ){    return rc;  }  sqlite3GetVarint32((u8*)m.z, &szHdr);  sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);  sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);  *rowid = v.u.i;  sqlite3VdbeMemRelease(&m);  return SQLITE_OK;}/*** Compare the key of the index entry that cursor pC is point to against** the key string in pKey (of length nKey).  Write into *pRes a number** that is negative, zero, or positive if pC is less than, equal to,** or greater than pKey.  Return SQLITE_OK on success.**** pKey is either created without a rowid or is truncated so that it** omits the rowid at the end.  The rowid at the end of the index entry** is ignored as well.*/int sqlite3VdbeIdxKeyCompare(  Cursor *pC,                 /* The cursor to compare against */  int nKey, const u8 *pKey,   /* The key to compare */  int *res                    /* Write the comparison result here */){  i64 nCellKey = 0;  int r

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -