sqliterk_util.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Tencent is pleased to support the open source community by making
  3. * WCDB available.
  4. *
  5. * Copyright (C) 2017 THL A29 Limited, a Tencent company.
  6. * All rights reserved.
  7. *
  8. * Licensed under the BSD 3-Clause License (the "License"); you may not use
  9. * this file except in compliance with the License. You may obtain a copy of
  10. * the License at
  11. *
  12. * https://opensource.org/licenses/BSD-3-Clause
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. #include "sqliterk_util.h"
  21. #include "SQLiteRepairKit.h"
  22. #include <stdarg.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. int sqliterkParseInt(const unsigned char *data,
  26. int offset,
  27. int length,
  28. int *value)
  29. {
  30. if (!value || length > sizeof(int)) {
  31. return SQLITERK_MISUSE;
  32. }
  33. int64_t out;
  34. int rc = sqliterkParseInt64(data, offset, length, &out);
  35. if (rc != SQLITERK_OK) {
  36. return rc;
  37. }
  38. *value = (int) out;
  39. return SQLITERK_OK;
  40. }
  41. int sqliterkParseInt64(const unsigned char *data,
  42. int offset,
  43. int length,
  44. int64_t *value)
  45. {
  46. if (!data || !value)
  47. return SQLITERK_MISUSE;
  48. const unsigned char *p = data + offset;
  49. int64_t out;
  50. switch (length) {
  51. case 1:
  52. out = (int8_t) p[0];
  53. break;
  54. case 2:
  55. out = (((int8_t) p[0]) * 256) | p[1];
  56. break;
  57. case 3:
  58. out = (((int8_t) p[0]) * 65536) | (p[1] << 8) | p[2];
  59. break;
  60. case 4:
  61. out = (((int8_t) p[0]) * 16777216) | (p[1] << 16) | (p[2] << 8) |
  62. p[3];
  63. break;
  64. case 6:
  65. out = (((int8_t) p[0]) * 256) | p[1];
  66. out *= ((int64_t) 1) << 32;
  67. out +=
  68. (((uint32_t) p[2]) << 24) | (p[3] << 16) | (p[4] << 8) | p[5];
  69. break;
  70. case 8:
  71. out = (((int8_t) p[0]) * 16777216) | (p[1] << 16) | (p[2] << 8) |
  72. p[3];
  73. out *= ((int64_t) 1) << 32;
  74. out +=
  75. (((uint32_t) p[4]) << 24) | (p[5] << 16) | (p[6] << 8) | p[7];
  76. break;
  77. default:
  78. return SQLITERK_MISUSE;
  79. }
  80. *value = out;
  81. return SQLITERK_OK;
  82. }
  83. // Varint is a kind of huffman encoding value. For further informantion,
  84. // see https://www.sqlite.org/fileformat2.html#varint
  85. int sqliterkParseVarint(const unsigned char *data,
  86. int offset,
  87. int *length,
  88. int *value)
  89. {
  90. if (!value) {
  91. return SQLITERK_MISUSE;
  92. }
  93. int64_t out;
  94. int rc = sqliterkParseVarint64(data, offset, length, &out);
  95. if (rc != SQLITERK_OK) {
  96. return rc;
  97. }
  98. *value = (int) out;
  99. return SQLITERK_OK;
  100. }
  101. int sqliterkParseVarint64(const unsigned char *data,
  102. int offset,
  103. int *length,
  104. int64_t *value)
  105. {
  106. if (!data || !length || !value) {
  107. return SQLITERK_MISUSE;
  108. }
  109. int64_t out = 0;
  110. const unsigned char *begin = data + offset;
  111. int i = 0;
  112. while ((begin[i] & 0x80) && i < sqliterkGetMaxVarintLength()) {
  113. out |= (begin[i] & 0x7f);
  114. out = (out << 7);
  115. i++;
  116. if (i >= sqliterkGetMaxVarintLength()) {
  117. return SQLITERK_DAMAGED;
  118. }
  119. }
  120. out |= begin[i];
  121. *length = i + 1;
  122. *value = out;
  123. return SQLITERK_OK;
  124. }
  125. int sqliterkGetMaxVarintLength()
  126. {
  127. return 9;
  128. }
  129. int sqliterkParseNumber(const unsigned char *data, int offset, double *value)
  130. {
  131. if (!data || !value) {
  132. return SQLITERK_MISUSE;
  133. }
  134. unsigned char out[8];
  135. const unsigned char *begin = data + offset;
  136. int i;
  137. for (i = 0; i < 8; i++) {
  138. // All float values in SQLite is big-endian with 8 lengths.
  139. // For further informantion, see [Record Format] chapter at
  140. // https://www.sqlite.org/fileformat2.html
  141. out[i] = begin[8 - 1 - i];
  142. }
  143. memcpy(value, out, 8);
  144. return SQLITERK_OK;
  145. }
  146. const char *sqliterkGetResultCodeDescription(int result)
  147. {
  148. switch (result) {
  149. case SQLITERK_OK:
  150. return "SQLITERK_OK";
  151. case SQLITERK_CANTOPEN:
  152. return "SQLITERK_CANTOPEN";
  153. case SQLITERK_MISUSE:
  154. return "SQLITERK_MISUSE";
  155. case SQLITERK_IOERR:
  156. return "SQLITERK_IOERR";
  157. case SQLITERK_NOMEM:
  158. return "SQLITERK_NOMEM";
  159. case SQLITERK_SHORT_READ:
  160. return "SQLITERK_SHORT_READ";
  161. case SQLITERK_DAMAGED:
  162. return "SQLITERK_DAMAGED";
  163. case SQLITERK_DISCARD:
  164. return "SQLITERK_DISCARD";
  165. default:
  166. break;
  167. }
  168. return "SQLITERK_UNKNOWN";
  169. }