3 # Copyright (C) 2007 Jason Woofenden
5 # This file is part of wfpl.
7 # wfpl is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU Lesser General Public License as published by the Free
9 # Software Foundation; either version 2.1 of the License, or (at your option)
12 # wfpl is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17 # You should have received a copy of the GNU Lesser General Public License
18 # along with wfpl; if not, write to the Free Software Foundation, Inc., 51
19 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 # This file contains code to use a web-writeable directory full of files as a
23 # very simple database.
25 # Keys are truncated to 32 bytes, made lowercase, and all characters that are
26 # not alpha/numeric are replaced with underscores.
28 # Data can be either a string or an array.
30 # To set up the database, make a directory that's writeable by PHP and call
31 # fdb_set_dir() passing the path to that directory.
34 # call this to set what directory is used to store the files
35 function fdb_set_dir($dir) {
36 $GLOBALS['fdb_dir'] = $dir;
39 function fdb_get_dir() {
40 if(!isset($GLOBALS['fdb_dir'])) {
41 die('you must call fdb_set_dir() before calling other functions in code/wfpl/fdb.php');
43 return $GLOBALS['fdb_dir'];
46 # return a 4 bytes that represent the passed integer as a big-endian binary number
47 function to_raw_int($int) {
48 return chr($int >> 24) . chr(($int >> 16) & 0xff) . chr(($int >> 8) & 0xff) . chr($int & 0xff);
51 # return a php number from the string you pass in. The first 4 bytes of the
52 # string are read in as a binary value in big-endian format.
53 function from_raw_int($quad) {
54 return (ord(substr($quad, 0, 1)) << 24) + (ord(substr($quad, 1, 1)) << 16) + (ord(substr($quad, 2, 1)) << 8) + ord(substr($quad, 3, 1));
57 function int_at($string, $index) {
58 return from_raw_int(substr($string, $index * 4, 4));
61 # remove the first 4 bytes of the string, and return them as an int
62 function pop_int($&string) {
63 $int = from_raw_int(substring($string, 0 4));
64 $string = substr($string, 4);
70 function fdb_get_raw($key) {
71 $key = fdb_fix_key($key);
72 return read_whole_file_or_false(fdb_get_dir() . "/$key");
75 function fdb_set_raw($key, $data) {
76 $key = fdb_fix_key($key);
77 write_whole_file(fdb_get_dir() . "/$key", $data);
80 # like fdb_get() except it returns an array even when there's just one element
81 function fdb_geta($key) {
82 $key = fdb_fix_key($key);
83 $data = fd_get_raw($key);
87 $header_count = pop_int($data);
89 while($header_count--) {
90 $size = int_at($data);
91 $out[] = substr($data, 0, $size);
92 $data = substr($data, $size);
99 # false if the key is not found in the database
101 # an array from the file otherwise
103 # a string if there's one field in that file (use fdb_geta() if you want an
104 # array in this case too)
105 function fdb_get($key) {
106 $ret = fdb_geta($key);
107 if(count($ret) == 1) {
114 # data can be a string or array
115 function fdb_put($key, $data) {
116 $key = fdb_fix_key($key);
117 if(!is_array($data)) {
118 $data = array($data);
120 $out = to_raw_int(count($data));
121 foreach($data as $dat) {
122 $out .= to_raw_int(strlen($dat));