rot13.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. ** Perform rot13 encoding on a single ASCII character.
  22. */
  23. static unsigned char rot13(unsigned char c){
  24. if( c>='a' && c<='z' ){
  25. c += 13;
  26. if( c>'z' ) c -= 26;
  27. }else if( c>='A' && c<='Z' ){
  28. c += 13;
  29. if( c>'Z' ) c -= 26;
  30. }
  31. return c;
  32. }
  33. /*
  34. ** Implementation of the rot13() function.
  35. **
  36. ** Rotate ASCII alphabetic characters by 13 character positions.
  37. ** Non-ASCII characters are unchanged. rot13(rot13(X)) should always
  38. ** equal X.
  39. */
  40. static void rot13func(
  41. sqlite3_context *context,
  42. int argc,
  43. sqlite3_value **argv
  44. ){
  45. const unsigned char *zIn;
  46. int nIn;
  47. unsigned char *zOut;
  48. unsigned char *zToFree = 0;
  49. int i;
  50. unsigned char zTemp[100];
  51. assert( argc==1 );
  52. if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  53. zIn = (const unsigned char*)sqlite3_value_text(argv[0]);
  54. nIn = sqlite3_value_bytes(argv[0]);
  55. if( nIn<sizeof(zTemp)-1 ){
  56. zOut = zTemp;
  57. }else{
  58. zOut = zToFree = (unsigned char*)sqlite3_malloc64( nIn+1 );
  59. if( zOut==0 ){
  60. sqlite3_result_error_nomem(context);
  61. return;
  62. }
  63. }
  64. for(i=0; i<nIn; i++) zOut[i] = rot13(zIn[i]);
  65. zOut[i] = 0;
  66. sqlite3_result_text(context, (char*)zOut, i, SQLITE_TRANSIENT);
  67. sqlite3_free(zToFree);
  68. }
  69. /*
  70. ** Implement the rot13 collating sequence so that if
  71. **
  72. ** x=y COLLATE rot13
  73. **
  74. ** Then
  75. **
  76. ** rot13(x)=rot13(y) COLLATE binary
  77. */
  78. static int rot13CollFunc(
  79. void *notUsed,
  80. int nKey1, const void *pKey1,
  81. int nKey2, const void *pKey2
  82. ){
  83. const char *zA = (const char*)pKey1;
  84. const char *zB = (const char*)pKey2;
  85. int i, x;
  86. for(i=0; i<nKey1 && i<nKey2; i++){
  87. x = (int)rot13(zA[i]) - (int)rot13(zB[i]);
  88. if( x!=0 ) return x;
  89. }
  90. return nKey1 - nKey2;
  91. }
  92. #ifdef _WIN32
  93. __declspec(dllexport)
  94. #endif
  95. int sqlite3_rot_init(
  96. sqlite3 *db,
  97. char **pzErrMsg,
  98. const sqlite3_api_routines *pApi
  99. ){
  100. int rc = SQLITE_OK;
  101. SQLITE_EXTENSION_INIT2(pApi);
  102. (void)pzErrMsg; /* Unused parameter */
  103. rc = sqlite3_create_function(db, "rot13", 1,
  104. SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
  105. 0, rot13func, 0, 0);
  106. if( rc==SQLITE_OK ){
  107. rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc);
  108. }
  109. return rc;
  110. }