|
1 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca> |
|
2 // |
|
3 // This program is free software; you can redistribute it and/or modify |
|
4 // it under the terms of the GNU General Public License as published by |
|
5 // the Free Software Foundation; either version 2 of the License, or |
|
6 // (at your option) any later version. |
|
7 // |
|
8 // This program is distributed in the hope that it will be useful, |
|
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 // GNU General Public License for more details. |
|
12 // |
|
13 // You should have received a copy of the GNU General Public License |
|
14 // along with this program; if not, write to the Free Software |
|
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
16 |
|
17 #include "cdb++.h" |
|
18 #include "internal.h" |
|
19 |
|
20 #define FAIL do{ abort(); return 0; }while(0) |
|
21 |
|
22 inline uint32 max(uint32 a, uint32 b) |
|
23 { |
|
24 return a > b ? a : b; |
|
25 } |
|
26 |
|
27 cdb_reader::cdb_reader(const mystring& filename) |
|
28 : in(filename.c_str()), |
|
29 failed(!in), |
|
30 eof(false) |
|
31 { |
|
32 firstrec(); |
|
33 } |
|
34 |
|
35 cdb_reader::~cdb_reader() |
|
36 { |
|
37 } |
|
38 |
|
39 void cdb_reader::abort() |
|
40 { |
|
41 failed = true; |
|
42 in.close(); |
|
43 } |
|
44 |
|
45 bool cdb_reader::firstrec() |
|
46 { |
|
47 if(failed) return false; |
|
48 if(!in.seek(0) || !in.read(header, 2048)) { |
|
49 abort(); |
|
50 return false; |
|
51 } |
|
52 eof = false; |
|
53 eod = unpack(header); |
|
54 pos = 2048; |
|
55 return true; |
|
56 } |
|
57 |
|
58 datum* cdb_reader::nextrec() |
|
59 { |
|
60 if(eof) return 0; |
|
61 if(pos >= eod) { |
|
62 eof = true; |
|
63 return 0; |
|
64 } |
|
65 if(failed || eod-pos < 8 || !in.seek(pos)) FAIL; |
|
66 pos += 8; |
|
67 unsigned char buf[8]; |
|
68 if(!in.read(buf, 8)) FAIL; |
|
69 uint32 klen = unpack(buf); |
|
70 uint32 dlen = unpack(buf+4); |
|
71 if (eod - pos < klen) FAIL; |
|
72 pos += klen; |
|
73 if (eod - pos < dlen) FAIL; |
|
74 pos += dlen; |
|
75 char tmp[max(klen, dlen)]; |
|
76 if(!in.read(tmp, klen)) FAIL; |
|
77 mystring key(tmp, klen); |
|
78 if(!in.read(tmp, dlen)) FAIL; |
|
79 mystring data(tmp, dlen); |
|
80 return new datum(key, data); |
|
81 } |