OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ** 2013-05-15 |
| 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: |
| 6 ** |
| 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. |
| 10 ** |
| 11 ****************************************************************************** |
| 12 ** |
| 13 ** This SQLite extension implements a rot13() function and a rot13 |
| 14 ** collating sequence. |
| 15 */ |
| 16 #include "sqlite3ext.h" |
| 17 SQLITE_EXTENSION_INIT1 |
| 18 #include <assert.h> |
| 19 #include <string.h> |
| 20 |
| 21 /* |
| 22 ** Perform rot13 encoding on a single ASCII character. |
| 23 */ |
| 24 static unsigned char rot13(unsigned char c){ |
| 25 if( c>='a' && c<='z' ){ |
| 26 c += 13; |
| 27 if( c>'z' ) c -= 26; |
| 28 }else if( c>='A' && c<='Z' ){ |
| 29 c += 13; |
| 30 if( c>'Z' ) c -= 26; |
| 31 } |
| 32 return c; |
| 33 } |
| 34 |
| 35 /* |
| 36 ** Implementation of the rot13() function. |
| 37 ** |
| 38 ** Rotate ASCII alphabetic characters by 13 character positions. |
| 39 ** Non-ASCII characters are unchanged. rot13(rot13(X)) should always |
| 40 ** equal X. |
| 41 */ |
| 42 static void rot13func( |
| 43 sqlite3_context *context, |
| 44 int argc, |
| 45 sqlite3_value **argv |
| 46 ){ |
| 47 const unsigned char *zIn; |
| 48 int nIn; |
| 49 unsigned char *zOut; |
| 50 char *zToFree = 0; |
| 51 int i; |
| 52 char zTemp[100]; |
| 53 assert( argc==1 ); |
| 54 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; |
| 55 zIn = (const unsigned char*)sqlite3_value_text(argv[0]); |
| 56 nIn = sqlite3_value_bytes(argv[0]); |
| 57 if( nIn<sizeof(zTemp)-1 ){ |
| 58 zOut = zTemp; |
| 59 }else{ |
| 60 zOut = zToFree = sqlite3_malloc( nIn+1 ); |
| 61 if( zOut==0 ){ |
| 62 sqlite3_result_error_nomem(context); |
| 63 return; |
| 64 } |
| 65 } |
| 66 for(i=0; i<nIn; i++) zOut[i] = rot13(zIn[i]); |
| 67 zOut[i] = 0; |
| 68 sqlite3_result_text(context, (char*)zOut, i, SQLITE_TRANSIENT); |
| 69 sqlite3_free(zToFree); |
| 70 } |
| 71 |
| 72 /* |
| 73 ** Implement the rot13 collating sequence so that if |
| 74 ** |
| 75 ** x=y COLLATE rot13 |
| 76 ** |
| 77 ** Then |
| 78 ** |
| 79 ** rot13(x)=rot13(y) COLLATE binary |
| 80 */ |
| 81 static int rot13CollFunc( |
| 82 void *notUsed, |
| 83 int nKey1, const void *pKey1, |
| 84 int nKey2, const void *pKey2 |
| 85 ){ |
| 86 const char *zA = (const char*)pKey1; |
| 87 const char *zB = (const char*)pKey2; |
| 88 int i, x; |
| 89 for(i=0; i<nKey1 && i<nKey2; i++){ |
| 90 x = (int)rot13(zA[i]) - (int)rot13(zB[i]); |
| 91 if( x!=0 ) return x; |
| 92 } |
| 93 return nKey1 - nKey2; |
| 94 } |
| 95 |
| 96 |
| 97 #ifdef _WIN32 |
| 98 __declspec(dllexport) |
| 99 #endif |
| 100 int sqlite3_rot_init( |
| 101 sqlite3 *db, |
| 102 char **pzErrMsg, |
| 103 const sqlite3_api_routines *pApi |
| 104 ){ |
| 105 int rc = SQLITE_OK; |
| 106 SQLITE_EXTENSION_INIT2(pApi); |
| 107 (void)pzErrMsg; /* Unused parameter */ |
| 108 rc = sqlite3_create_function(db, "rot13", 1, SQLITE_UTF8, 0, |
| 109 rot13func, 0, 0); |
| 110 if( rc==SQLITE_OK ){ |
| 111 rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc); |
| 112 } |
| 113 return rc; |
| 114 } |
OLD | NEW |