lib/cdb++/cdb_reader.cc
changeset 0 6f7a81934006
child 2 b3afb9f1e801
equal deleted inserted replaced
-1:000000000000 0:6f7a81934006
       
     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 }