src/mmdb.c

Go to the documentation of this file.
00001 /*
00002  i ib_rw.c 
00003  */
00004 #include "copyright.h"
00005 #include "config.h"
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <dirent.h>
00011 #include <sys/time.h>
00012 #include <sys/stat.h>
00013 #include <sys/types.h>
00014 #include <fcntl.h>
00015 #include <sys/mman.h>
00016 #include <errno.h>
00017 #include <event.h>
00018 #include <string.h>
00019 #include <sys/file.h>
00020 #include <stdint.h>
00021 
00022 #include "debug.h"
00023 
00024 struct mmdb_t {
00025         void *base;
00026         void *ppos;
00027         void *end;
00028         int length;
00029         int fd;
00030 };
00031 
00032 struct mmdb_t *mmdb_open_read(char *filename)
00033 {
00034         struct stat statbuf;
00035         struct mmdb_t *mmdb;
00036         int fd, length;
00037 
00038         if(stat(filename, &statbuf) < 0) {
00039         return NULL;
00040     }
00041         mmdb = malloc(sizeof(struct mmdb_t));
00042     if(!mmdb) return NULL;
00043 
00044         fd = open(filename, O_RDONLY);
00045     if(!fd)  {
00046         free(mmdb);
00047         return NULL;
00048     }
00049     
00050         mmdb->fd = fd;
00051         mmdb->length = (statbuf.st_size + 0x3FF) & ~(0x3FF);
00052         mmdb->base =
00053                 mmap(NULL, mmdb->length, PROT_READ, MAP_SHARED,
00054                          mmdb->fd, 0);
00055         if(!mmdb->base) {
00056         close(mmdb->fd);
00057         free(mmdb);
00058         return NULL;
00059     }
00060     mmdb->end = mmdb->base + mmdb->length;
00061 
00062         mmdb->ppos = mmdb->base;
00063         return mmdb;
00064 
00065 }
00066 
00067 struct mmdb_t *mmdb_open_write(char *filename)
00068 {
00069         struct stat statbuf;
00070         struct mmdb_t *mmdb;
00071         int fd, length;
00072 
00073         mmdb = malloc(sizeof(struct mmdb_t));
00074         dperror((fd = open(filename, O_RDWR | O_CREAT, 0644)) < 0);
00075 
00076         mmdb->fd = fd;
00077         mmdb->length = 0x400 * 16;
00078         mmdb->base = NULL;
00079         mmdb->ppos = NULL;
00080         dprintk("mmdb->length %d", mmdb->length);
00081         ftruncate(mmdb->fd, mmdb->length);
00082         fsync(mmdb->fd);
00083         mmdb->base =
00084                 mmap(NULL, mmdb->length, PROT_READ | PROT_WRITE, MAP_SHARED, mmdb->fd,
00085                          0);
00086         dperror(mmdb->base == MAP_FAILED);
00087         mmdb->end = mmdb->base + mmdb->length;
00088         mmdb->ppos = mmdb->base;
00089         return mmdb;
00090 }
00091 
00092 void mmdb_resize(struct mmdb_t *mmdb, int length)
00093 {
00094         int offset = 0;
00095         if(mmdb->base) {
00096                 offset = mmdb->ppos - mmdb->base;
00097                 msync(mmdb->base, mmdb->length, MS_ASYNC);
00098                 munmap(mmdb->base, mmdb->length);
00099                 mmdb->base = NULL;
00100                 mmdb->ppos = NULL;
00101         }
00102         mmdb->length = (length + 0x3FF) & ~(0x3FF);
00103         ftruncate(mmdb->fd, mmdb->length);
00104         mmdb->base =
00105                 mmap(NULL, mmdb->length, PROT_READ | PROT_WRITE, MAP_SHARED, mmdb->fd,
00106                          0);
00107         dperror(mmdb->base == NULL);
00108         mmdb->end = mmdb->base + mmdb->length;
00109         mmdb->ppos = mmdb->base + offset;
00110 }
00111 
00112 void mmdb_close(struct mmdb_t *mmdb)
00113 {
00114         msync(mmdb->base, mmdb->length, MS_SYNC);
00115         munmap(mmdb->base, mmdb->length);
00116         ftruncate(mmdb->fd, mmdb->ppos - mmdb->base);
00117         dprintk("truncating to %d bytes.", mmdb->ppos - mmdb->base);
00118         close(mmdb->fd);
00119         mmdb->fd = 0;
00120         memset(mmdb, 0, sizeof(struct mmdb_t));
00121         free(mmdb);
00122 }
00123 
00124 void mmdb_write(struct mmdb_t *mmdb, void *data, int length)
00125 {
00126         if(mmdb->end - mmdb->ppos < length) {
00127                 mmdb_resize(mmdb, mmdb->length + length);
00128         }
00129         memcpy(mmdb->ppos, data, length);
00130         mmdb->ppos += length;
00131 }
00132 
00133 void mmdb_write_uint32(struct mmdb_t *mmdb, uint32_t data)
00134 {
00135         data = htonl(data);
00136         mmdb_write(mmdb, &data, sizeof(uint32_t));
00137 }
00138 
00139 uint32_t mmdb_read_uint32(struct mmdb_t *mmdb)
00140 {
00141         uint32_t data = *((uint32_t *) (mmdb->ppos));
00142         mmdb->ppos += sizeof(uint32_t);
00143         return ntohl(data);
00144 }
00145 
00146 unsigned int mmdb_read_uint(struct mmdb_t *mmdb) {
00147     printk("This function is deprecated, please use mmdb_read_uint32 instead.\n");
00148     return (unsigned int)mmdb_read_uint32(mmdb);
00149 }
00150 
00151 void mmdb_write_uint(struct mmdb_t *mmdb, unsigned int val) {
00152     printk("This function is deprecated, please use mmdb_write_uint32 instead.\n");
00153     mmdb_write_uint32(mmdb, (uint32_t)val);
00154     return;
00155 }
00156 
00157 void mmdb_write_uint64(struct mmdb_t *mmdb, uint64_t data)
00158 {
00159     dprintk("technically, this is not 64 bit safe yet.");
00160         data = htonl(data);
00161         mmdb_write(mmdb, &data, sizeof(uint64_t));
00162 }
00163 
00164 uint64_t mmdb_read_uint64(struct mmdb_t *mmdb)
00165 {
00166     dprintk("technically, this is not 64 bit safe yet.");
00167         uint64_t data = *((uint64_t *) (mmdb->ppos));
00168         mmdb->ppos += sizeof(uint64_t);
00169         return ntohl(data);
00170 }
00171 
00172 void mmdb_write_single(struct mmdb_t *mmdb, float data)
00173 {
00174         data = htonl(data);
00175         mmdb_write(mmdb, &data, sizeof(float));
00176 }
00177 
00178 float mmdb_read_single(struct mmdb_t *mmdb)
00179 {
00180         float data = *((float *) (mmdb->ppos));
00181         mmdb->ppos += sizeof(float);
00182         return ntohl(data);
00183 }
00184 
00185 void mmdb_write_double(struct mmdb_t *mmdb, double data)
00186 {
00187         data = htonl(data);
00188         mmdb_write(mmdb, &data, sizeof(double));
00189 }
00190 
00191 double mmdb_read_double(struct mmdb_t *mmdb)
00192 {
00193         double data = *((double *) (mmdb->ppos));
00194         mmdb->ppos += sizeof(double);
00195         return ntohl(data);
00196 }
00197 
00198 
00199 void *mmdb_read(struct mmdb_t *mmdb, void *dest, int length)
00200 {
00201         if((mmdb->end - mmdb->ppos) < length)
00202                 return NULL;
00203         memcpy(dest, mmdb->ppos, length);
00204         mmdb->ppos += length;
00205         if(length & 3)
00206                 mmdb->ppos += 4 - (length & 3);
00207         return dest;
00208 }
00209 
00210 void mmdb_write_opaque(struct mmdb_t *mmdb, void *data, int length)
00211 {
00212         unsigned char *pad = (unsigned char *)"\x00\x00\x00\x00";
00213         mmdb_write_uint32(mmdb, length);
00214         mmdb_write(mmdb, data, length);
00215         if((length & 3) > 0)
00216                 mmdb_write(mmdb, pad, 4 - (length & 3));
00217 }
00218 
00219 void mmdb_write_string(struct mmdb_t *mmdb, void *data) {
00220     if(data == NULL) {
00221         mmdb_write_uint32(mmdb, 0);
00222     } else {
00223         mmdb_write_opaque(mmdb, data, strlen(data)+1);
00224     }
00225 }
00226 
00227 char *mmdb_read_string(struct mmdb_t *mmdb) {
00228     char *tmp;
00229     int length;
00230     length = mmdb_read_uint32(mmdb);
00231     if(length == 0) return NULL;
00232     tmp = malloc(length);
00233     mmdb_read(mmdb, tmp, length);
00234     return tmp;
00235 }
00236 
00237 char mmdb_read_opaque(struct mmdb_t *mmdb, void *dest, int maxlength) {
00238     int length = mmdb_read_uint32(mmdb);
00239     
00240         if((mmdb->end - mmdb->ppos) < length)
00241                 return NULL;
00242     if(length > maxlength) {
00243         memcpy(dest, mmdb->ppos, maxlength);
00244     } else {
00245         memcpy(dest, mmdb->ppos, length);
00246     }
00247         mmdb->ppos += length;
00248         if(length & 3)
00249                 mmdb->ppos += 4 - (length & 3);
00250         return dest;
00251 }

Generated on Mon May 28 04:25:25 2007 for BattletechMUX by  doxygen 1.4.7