~ubuntu-branches/ubuntu/precise/sqlite3/precise-updates

« back to all changes in this revision

Viewing changes to src/utf.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2009-12-11 14:34:09 UTC
  • mfrom: (9.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091211143409-o29fahwmcmyd0vq1
Tags: 3.6.21-2
Run autoreconf to prevent FTBFS with new libtool (closes: #560660).

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
** This file contains routines used to translate between UTF-8, 
13
13
** UTF-16, UTF-16BE, and UTF-16LE.
14
14
**
15
 
** $Id: utf.c,v 1.73 2009/04/01 18:40:32 drh Exp $
16
 
**
17
15
** Notes on UTF-8:
18
16
**
19
17
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
107
105
  }                                                                 \
108
106
}
109
107
 
110
 
#define READ_UTF16LE(zIn, c){                                         \
 
108
#define READ_UTF16LE(zIn, TERM, c){                                   \
111
109
  c = (*zIn++);                                                       \
112
110
  c += ((*zIn++)<<8);                                                 \
113
 
  if( c>=0xD800 && c<0xE000 ){                                        \
 
111
  if( c>=0xD800 && c<0xE000 && TERM ){                                \
114
112
    int c2 = (*zIn++);                                                \
115
113
    c2 += ((*zIn++)<<8);                                              \
116
114
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
117
115
  }                                                                   \
118
116
}
119
117
 
120
 
#define READ_UTF16BE(zIn, c){                                         \
 
118
#define READ_UTF16BE(zIn, TERM, c){                                   \
121
119
  c = ((*zIn++)<<8);                                                  \
122
120
  c += (*zIn++);                                                      \
123
 
  if( c>=0xD800 && c<0xE000 ){                                        \
 
121
  if( c>=0xD800 && c<0xE000 && TERM ){                                \
124
122
    int c2 = ((*zIn++)<<8);                                           \
125
123
    c2 += (*zIn++);                                                   \
126
124
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
305
303
    if( pMem->enc==SQLITE_UTF16LE ){
306
304
      /* UTF-16 Little-endian -> UTF-8 */
307
305
      while( zIn<zTerm ){
308
 
        READ_UTF16LE(zIn, c); 
 
306
        READ_UTF16LE(zIn, zIn<zTerm, c); 
309
307
        WRITE_UTF8(z, c);
310
308
      }
311
309
    }else{
312
310
      /* UTF-16 Big-endian -> UTF-8 */
313
311
      while( zIn<zTerm ){
314
 
        READ_UTF16BE(zIn, c); 
 
312
        READ_UTF16BE(zIn, zIn<zTerm, c); 
315
313
        WRITE_UTF8(z, c);
316
314
      }
317
315
    }
455
453
}
456
454
 
457
455
/*
458
 
** pZ is a UTF-16 encoded unicode string at least nChar characters long.
 
456
** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
 
457
** enc. A pointer to the new string is returned, and the value of *pnOut
 
458
** is set to the length of the returned string in bytes. The call should
 
459
** arrange to call sqlite3DbFree() on the returned pointer when it is
 
460
** no longer required.
 
461
** 
 
462
** If a malloc failure occurs, NULL is returned and the db.mallocFailed
 
463
** flag set.
 
464
*/
 
465
#ifdef SQLITE_ENABLE_STAT2
 
466
char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
 
467
  Mem m;
 
468
  memset(&m, 0, sizeof(m));
 
469
  m.db = db;
 
470
  sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
 
471
  if( sqlite3VdbeMemTranslate(&m, enc) ){
 
472
    assert( db->mallocFailed );
 
473
    return 0;
 
474
  }
 
475
  assert( m.z==m.zMalloc );
 
476
  *pnOut = m.n;
 
477
  return m.z;
 
478
}
 
479
#endif
 
480
 
 
481
/*
 
482
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
459
483
** Return the number of bytes in the first nChar unicode characters
460
484
** in pZ.  nChar must be non-negative.
461
485
*/
463
487
  int c;
464
488
  unsigned char const *z = zIn;
465
489
  int n = 0;
 
490
  
466
491
  if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
467
 
    /* Using an "if (SQLITE_UTF16NATIVE==SQLITE_UTF16BE)" construct here
468
 
    ** and in other parts of this file means that at one branch will
469
 
    ** not be covered by coverage testing on any single host. But coverage
470
 
    ** will be complete if the tests are run on both a little-endian and 
471
 
    ** big-endian host. Because both the UTF16NATIVE and SQLITE_UTF16BE
472
 
    ** macros are constant at compile time the compiler can determine
473
 
    ** which branch will be followed. It is therefore assumed that no runtime
474
 
    ** penalty is paid for this "if" statement.
475
 
    */
476
492
    while( n<nChar ){
477
 
      READ_UTF16BE(z, c);
 
493
      READ_UTF16BE(z, 1, c);
478
494
      n++;
479
495
    }
480
496
  }else{
481
497
    while( n<nChar ){
482
 
      READ_UTF16LE(z, c);
 
498
      READ_UTF16LE(z, 1, c);
483
499
      n++;
484
500
    }
485
501
  }
521
537
    assert( n>0 && n<=4 );
522
538
    z[0] = 0;
523
539
    z = zBuf;
524
 
    READ_UTF16LE(z, c);
 
540
    READ_UTF16LE(z, 1, c);
525
541
    assert( c==i );
526
542
    assert( (z-zBuf)==n );
527
543
  }
533
549
    assert( n>0 && n<=4 );
534
550
    z[0] = 0;
535
551
    z = zBuf;
536
 
    READ_UTF16BE(z, c);
 
552
    READ_UTF16BE(z, 1, c);
537
553
    assert( c==i );
538
554
    assert( (z-zBuf)==n );
539
555
  }