lib/cdb++/cdb_reader.cc
changeset 2 b3afb9f1e801
parent 0 6f7a81934006
--- a/lib/cdb++/cdb_reader.cc	Sun Jan 20 00:12:17 2008 +0100
+++ b/lib/cdb++/cdb_reader.cc	Sun Jan 20 00:22:09 2008 +0100
@@ -14,6 +14,10 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
 #include "cdb++.h"
 #include "internal.h"
 
@@ -25,10 +29,17 @@
 }
 
 cdb_reader::cdb_reader(const mystring& filename)
-  : in(filename.c_str()),
-    failed(!in),
+  : map(0),
+    failed(1),
     eof(false)
 {
+  int fd = open(filename.c_str(), O_RDONLY);
+  if(fd == -1) return;
+  struct stat buf;
+  if(fstat(fd, &buf) != -1)
+    map = (unsigned char*)mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+  close(fd);
+  failed = !map;
   firstrec();
 }
 
@@ -39,43 +50,31 @@
 void cdb_reader::abort()
 {
   failed = true;
-  in.close();
+  if(map)
+    munmap(map, size);
 }
 
 bool cdb_reader::firstrec()
 {
   if(failed) return false;
-  if(!in.seek(0) || !in.read(header, 2048)) {
-    abort();
-    return false;
-  }
-  eof = false;
-  eod = unpack(header);
-  pos = 2048;
+  ptr = map + 2048;
+  eod = map + unpack(map);
   return true;
 }
 
 datum* cdb_reader::nextrec()
 {
   if(eof) return 0;
-  if(pos >= eod) {
+  if(ptr >= eod) {
     eof = true;
     return 0;
   }
-  if(failed || eod-pos < 8 || !in.seek(pos)) FAIL;
-  pos += 8;
-  unsigned char buf[8];
-  if(!in.read(buf, 8)) FAIL;
-  uint32 klen = unpack(buf);
-  uint32 dlen = unpack(buf+4);
-  if (eod - pos < klen) FAIL;
-  pos += klen;
-  if (eod - pos < dlen) FAIL;
-  pos += dlen;
-  char tmp[max(klen, dlen)];
-  if(!in.read(tmp, klen)) FAIL;
-  mystring key(tmp, klen);
-  if(!in.read(tmp, dlen)) FAIL;
-  mystring data(tmp, dlen);
-  return new datum(key, data);
+  if(failed || eod-ptr < 8) FAIL;
+  uint32 klen = unpack(ptr); ptr += 4;
+  uint32 dlen = unpack(ptr); ptr += 4;
+  if ((uint32)(eod - ptr) < klen + dlen) FAIL;
+  datum* result = new datum(mystring((char*)ptr,      klen),
+			    mystring((char*)ptr+klen, dlen));
+  ptr += klen + dlen;
+  return result;
 }