flatfile.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Marcus Boerger <helly@php.net> |
  14. | based on ext/db/db.c by: |
  15. | Rasmus Lerdorf <rasmus@php.net> |
  16. | Jim Winstead <jimw@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id$ */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "php.h"
  24. #include "php_globals.h"
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #if HAVE_UNISTD_H
  29. #include <unistd.h>
  30. #endif
  31. #include "flatfile.h"
  32. #define FLATFILE_BLOCK_SIZE 1024
  33. /*
  34. * ret = -1 means that database was opened for read-only
  35. * ret = 0 success
  36. * ret = 1 key already exists - nothing done
  37. */
  38. /* {{{ flatfile_store */
  39. int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode) {
  40. if (mode == FLATFILE_INSERT) {
  41. if (flatfile_findkey(dba, key_datum)) {
  42. return 1;
  43. }
  44. php_stream_seek(dba->fp, 0L, SEEK_END);
  45. php_stream_printf(dba->fp, "%zu\n", key_datum.dsize);
  46. php_stream_flush(dba->fp);
  47. if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
  48. return -1;
  49. }
  50. php_stream_printf(dba->fp, "%zu\n", value_datum.dsize);
  51. php_stream_flush(dba->fp);
  52. if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
  53. return -1;
  54. }
  55. } else { /* FLATFILE_REPLACE */
  56. flatfile_delete(dba, key_datum);
  57. php_stream_printf(dba->fp, "%zu\n", key_datum.dsize);
  58. php_stream_flush(dba->fp);
  59. if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
  60. return -1;
  61. }
  62. php_stream_printf(dba->fp, "%zu\n", value_datum.dsize);
  63. if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
  64. return -1;
  65. }
  66. }
  67. php_stream_flush(dba->fp);
  68. return 0;
  69. }
  70. /* }}} */
  71. /* {{{ flatfile_fetch */
  72. datum flatfile_fetch(flatfile *dba, datum key_datum) {
  73. datum value_datum = {NULL, 0};
  74. char buf[16];
  75. if (flatfile_findkey(dba, key_datum)) {
  76. if (php_stream_gets(dba->fp, buf, sizeof(buf))) {
  77. value_datum.dsize = atoi(buf);
  78. value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1);
  79. value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize);
  80. } else {
  81. value_datum.dptr = NULL;
  82. value_datum.dsize = 0;
  83. }
  84. }
  85. return value_datum;
  86. }
  87. /* }}} */
  88. /* {{{ flatfile_delete */
  89. int flatfile_delete(flatfile *dba, datum key_datum) {
  90. char *key = key_datum.dptr;
  91. size_t size = key_datum.dsize;
  92. size_t buf_size = FLATFILE_BLOCK_SIZE;
  93. char *buf = emalloc(buf_size);
  94. size_t num;
  95. size_t pos;
  96. php_stream_rewind(dba->fp);
  97. while(!php_stream_eof(dba->fp)) {
  98. /* read in the length of the key name */
  99. if (!php_stream_gets(dba->fp, buf, 15)) {
  100. break;
  101. }
  102. num = atoi(buf);
  103. if (num >= buf_size) {
  104. buf_size = num + FLATFILE_BLOCK_SIZE;
  105. buf = erealloc(buf, buf_size);
  106. }
  107. pos = php_stream_tell(dba->fp);
  108. /* read in the key name */
  109. num = php_stream_read(dba->fp, buf, num);
  110. if (size == num && !memcmp(buf, key, size)) {
  111. php_stream_seek(dba->fp, pos, SEEK_SET);
  112. php_stream_putc(dba->fp, 0);
  113. php_stream_flush(dba->fp);
  114. php_stream_seek(dba->fp, 0L, SEEK_END);
  115. efree(buf);
  116. return SUCCESS;
  117. }
  118. /* read in the length of the value */
  119. if (!php_stream_gets(dba->fp, buf, 15)) {
  120. break;
  121. }
  122. num = atoi(buf);
  123. if (num >= buf_size) {
  124. buf_size = num + FLATFILE_BLOCK_SIZE;
  125. buf = erealloc(buf, buf_size);
  126. }
  127. /* read in the value */
  128. num = php_stream_read(dba->fp, buf, num);
  129. }
  130. efree(buf);
  131. return FAILURE;
  132. }
  133. /* }}} */
  134. /* {{{ flatfile_findkey */
  135. int flatfile_findkey(flatfile *dba, datum key_datum) {
  136. size_t buf_size = FLATFILE_BLOCK_SIZE;
  137. char *buf = emalloc(buf_size);
  138. size_t num;
  139. int ret=0;
  140. void *key = key_datum.dptr;
  141. size_t size = key_datum.dsize;
  142. php_stream_rewind(dba->fp);
  143. while (!php_stream_eof(dba->fp)) {
  144. if (!php_stream_gets(dba->fp, buf, 15)) {
  145. break;
  146. }
  147. num = atoi(buf);
  148. if (num >= buf_size) {
  149. buf_size = num + FLATFILE_BLOCK_SIZE;
  150. buf = erealloc(buf, buf_size);
  151. }
  152. num = php_stream_read(dba->fp, buf, num);
  153. if (size == num) {
  154. if (!memcmp(buf, key, size)) {
  155. ret = 1;
  156. break;
  157. }
  158. }
  159. if (!php_stream_gets(dba->fp, buf, 15)) {
  160. break;
  161. }
  162. num = atoi(buf);
  163. if (num >= buf_size) {
  164. buf_size = num + FLATFILE_BLOCK_SIZE;
  165. buf = erealloc(buf, buf_size);
  166. }
  167. num = php_stream_read(dba->fp, buf, num);
  168. }
  169. efree(buf);
  170. return ret;
  171. }
  172. /* }}} */
  173. /* {{{ flatfile_firstkey */
  174. datum flatfile_firstkey(flatfile *dba) {
  175. datum res;
  176. size_t num;
  177. size_t buf_size = FLATFILE_BLOCK_SIZE;
  178. char *buf = emalloc(buf_size);
  179. php_stream_rewind(dba->fp);
  180. while(!php_stream_eof(dba->fp)) {
  181. if (!php_stream_gets(dba->fp, buf, 15)) {
  182. break;
  183. }
  184. num = atoi(buf);
  185. if (num >= buf_size) {
  186. buf_size = num + FLATFILE_BLOCK_SIZE;
  187. buf = erealloc(buf, buf_size);
  188. }
  189. num = php_stream_read(dba->fp, buf, num);
  190. if (*(buf) != 0) {
  191. dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
  192. res.dptr = buf;
  193. res.dsize = num;
  194. return res;
  195. }
  196. if (!php_stream_gets(dba->fp, buf, 15)) {
  197. break;
  198. }
  199. num = atoi(buf);
  200. if (num >= buf_size) {
  201. buf_size = num + FLATFILE_BLOCK_SIZE;
  202. buf = erealloc(buf, buf_size);
  203. }
  204. num = php_stream_read(dba->fp, buf, num);
  205. }
  206. efree(buf);
  207. res.dptr = NULL;
  208. res.dsize = 0;
  209. return res;
  210. }
  211. /* }}} */
  212. /* {{{ flatfile_nextkey */
  213. datum flatfile_nextkey(flatfile *dba) {
  214. datum res;
  215. size_t num;
  216. size_t buf_size = FLATFILE_BLOCK_SIZE;
  217. char *buf = emalloc(buf_size);
  218. php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
  219. while(!php_stream_eof(dba->fp)) {
  220. if (!php_stream_gets(dba->fp, buf, 15)) {
  221. break;
  222. }
  223. num = atoi(buf);
  224. if (num >= buf_size) {
  225. buf_size = num + FLATFILE_BLOCK_SIZE;
  226. buf = erealloc(buf, buf_size);
  227. }
  228. num = php_stream_read(dba->fp, buf, num);
  229. if (!php_stream_gets(dba->fp, buf, 15)) {
  230. break;
  231. }
  232. num = atoi(buf);
  233. if (num >= buf_size) {
  234. buf_size = num + FLATFILE_BLOCK_SIZE;
  235. buf = erealloc(buf, buf_size);
  236. }
  237. num = php_stream_read(dba->fp, buf, num);
  238. if (*(buf)!=0) {
  239. dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
  240. res.dptr = buf;
  241. res.dsize = num;
  242. return res;
  243. }
  244. }
  245. efree(buf);
  246. res.dptr = NULL;
  247. res.dsize = 0;
  248. return res;
  249. }
  250. /* }}} */
  251. /* {{{ flatfile_version */
  252. char *flatfile_version()
  253. {
  254. return "1.0, $Id$";
  255. }
  256. /* }}} */