lib/cdb++/cdb_reader.cc
changeset 2 b3afb9f1e801
parent 0 6f7a81934006
equal deleted inserted replaced
1:30113bfbe723 2:b3afb9f1e801
    12 //
    12 //
    13 // You should have received a copy of the GNU General Public License
    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
    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
    15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    16 
    16 
       
    17 #include <sys/types.h>
       
    18 #include <sys/stat.h>
       
    19 #include <sys/mman.h>
       
    20 #include <unistd.h>
    17 #include "cdb++.h"
    21 #include "cdb++.h"
    18 #include "internal.h"
    22 #include "internal.h"
    19 
    23 
    20 #define FAIL do{ abort(); return 0; }while(0)
    24 #define FAIL do{ abort(); return 0; }while(0)
    21 
    25 
    23 {
    27 {
    24   return a > b ? a : b;
    28   return a > b ? a : b;
    25 }
    29 }
    26 
    30 
    27 cdb_reader::cdb_reader(const mystring& filename)
    31 cdb_reader::cdb_reader(const mystring& filename)
    28   : in(filename.c_str()),
    32   : map(0),
    29     failed(!in),
    33     failed(1),
    30     eof(false)
    34     eof(false)
    31 {
    35 {
       
    36   int fd = open(filename.c_str(), O_RDONLY);
       
    37   if(fd == -1) return;
       
    38   struct stat buf;
       
    39   if(fstat(fd, &buf) != -1)
       
    40     map = (unsigned char*)mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
       
    41   close(fd);
       
    42   failed = !map;
    32   firstrec();
    43   firstrec();
    33 }
    44 }
    34 
    45 
    35 cdb_reader::~cdb_reader()
    46 cdb_reader::~cdb_reader()
    36 {
    47 {
    37 }
    48 }
    38 
    49 
    39 void cdb_reader::abort()
    50 void cdb_reader::abort()
    40 {
    51 {
    41   failed = true;
    52   failed = true;
    42   in.close();
    53   if(map)
       
    54     munmap(map, size);
    43 }
    55 }
    44 
    56 
    45 bool cdb_reader::firstrec()
    57 bool cdb_reader::firstrec()
    46 {
    58 {
    47   if(failed) return false;
    59   if(failed) return false;
    48   if(!in.seek(0) || !in.read(header, 2048)) {
    60   ptr = map + 2048;
    49     abort();
    61   eod = map + unpack(map);
    50     return false;
       
    51   }
       
    52   eof = false;
       
    53   eod = unpack(header);
       
    54   pos = 2048;
       
    55   return true;
    62   return true;
    56 }
    63 }
    57 
    64 
    58 datum* cdb_reader::nextrec()
    65 datum* cdb_reader::nextrec()
    59 {
    66 {
    60   if(eof) return 0;
    67   if(eof) return 0;
    61   if(pos >= eod) {
    68   if(ptr >= eod) {
    62     eof = true;
    69     eof = true;
    63     return 0;
    70     return 0;
    64   }
    71   }
    65   if(failed || eod-pos < 8 || !in.seek(pos)) FAIL;
    72   if(failed || eod-ptr < 8) FAIL;
    66   pos += 8;
    73   uint32 klen = unpack(ptr); ptr += 4;
    67   unsigned char buf[8];
    74   uint32 dlen = unpack(ptr); ptr += 4;
    68   if(!in.read(buf, 8)) FAIL;
    75   if ((uint32)(eod - ptr) < klen + dlen) FAIL;
    69   uint32 klen = unpack(buf);
    76   datum* result = new datum(mystring((char*)ptr,      klen),
    70   uint32 dlen = unpack(buf+4);
    77 			    mystring((char*)ptr+klen, dlen));
    71   if (eod - pos < klen) FAIL;
    78   ptr += klen + dlen;
    72   pos += klen;
    79   return result;
    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 }
    80 }