Fix commented code
[tedtools.git] / sfxstr.c
index 36d1f31..0803345 100644 (file)
--- a/sfxstr.c
+++ b/sfxstr.c
@@ -29,7 +29,9 @@
 
 #include <errno.h>
 #include <string.h>
+#include <stdint.h>
 #include <sys/types.h>
+#include <sys/file.h>
 #include <sys/uio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -45,7 +47,7 @@
 
 #define SFSTREE_VERSION                0x0100
 
-typedef unsigned long Opaque;  /* XXX sizeof(Opaque) == sizeof(void *) */
+typedef uintptr_t Opaque;  /* XXX sizeof(Opaque) == sizeof(void *) */
 
 #define CHECK_MEMORY(tree)     ( ( (tree)->plainmemory ) ? \
        tlog(TL_CRIT|TL_EXIT, "Tree in plain memory - read only access") : (void)0 ) 
@@ -138,17 +140,22 @@ SFSInit_c(SFSTree *info, char **in) {
        return info;
 }
 
+#define ISEND(p,w,l)   ( (l>0) ? ( ((char*)(p))-(w) >= (l) ) : ( *(p) == '\0' ) )
+
 void*
-SFSFindData(SFSTree *info, char *word) {
+SFSFindData(SFSTree *info, char *word, int len) {
        SFSNode *node = info->node;
        SFSNodeData *StopLow, *StopHigh, *StopMiddle;
        u_int8_t *ptr =(u_int8_t*)word;
 
-       while( node && *ptr ) {
+       while( node && !ISEND(ptr, word, len) ) {
                if ( node->isskip ) {
-                       if ( STRNCMP(ptr, ((char*)node)+node->dataptr, node->nchar) ) {
+               
+                       if ( len>0 &&  len - (((char*)ptr) - word) > node->nchar )
+                               return NULL;
+                       else if ( STRNCMP(ptr, ((char*)node)+node->dataptr, node->nchar) ) {
                                ptr+=node->nchar;
-                               if ( *ptr=='\0' && node->isword) {
+                               if ( ISEND(ptr, word, len) && node->isword) {
                                        return (void*) ( ((char*)(node->data)) + ((node->haschild) ? sizeof(SFSNode*) : 0) );
                                } else if ( node->haschild ) {
                                        node = getSkipChildPointer(info, node);
@@ -164,7 +171,7 @@ SFSFindData(SFSTree *info, char *word) {
                                StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
                                if ( StopMiddle->val == *ptr ) {
                                        ptr++;
-                                       if ( *ptr=='\0' && StopMiddle->isword ) {
+                                       if ( ISEND(ptr, word, len) && StopMiddle->isword ) {
                                                return (void*)( ((char*)node) + node->dataptr + info->datasize * StopMiddle->data );
                                        } else if ( StopMiddle->haschild ) {
                                                node = getChildPointer(info, StopMiddle);
@@ -977,7 +984,7 @@ SFSRevertPlain(SFSTree *info) {
 }
 
 static Opaque
-writeNode(WorkPlain *wp, int fd, SFSNode *node) {
+writeNode(WorkPlain *wp, int fd, SFSNode *node, u_int32_t extrasize) {
        int     size = getNodeSize(wp->info, node);
        SFSNode  *wnode = (SFSNode*)tmalloc(size);
        off_t   myoffset = wp->offset;
@@ -990,7 +997,7 @@ writeNode(WorkPlain *wp, int fd, SFSNode *node) {
        if ( node->isskip ) {
                if (node->haschild) 
                        *(Opaque*)( ((char*)wnode) + SFSNHRDSZ) = 
-                                       writeNode(wp, fd, getSkipChildPointer(wp->info, node));
+                                       writeNode(wp, fd, getSkipChildPointer(wp->info, node), extrasize);
        } else {
                SFSNodeData *nd = node->data;
                u_int32_t       i;
@@ -998,12 +1005,12 @@ writeNode(WorkPlain *wp, int fd, SFSNode *node) {
                for(i=0;i<node->nchar;i++) {
                        if (nd->haschild)
                                *(Opaque*)(((char*)wnode) + ( ((char*)nd) - ((char*)node) ) + nd->child) =
-                                               writeNode(wp, fd, getChildPointer( wp->info, nd ) );    
+                                               writeNode(wp, fd, getChildPointer( wp->info, nd ), extrasize ); 
                        nd++;
                }
        }
 
-       if ( lseek(fd, myoffset + SFSTDHSZ, SEEK_SET) < 0 )
+       if ( lseek(fd, myoffset + SFSTDHSZ + extrasize, SEEK_SET) < 0 )
                tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno));
        if ( write(fd, wnode, size) != size )
                tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno));
@@ -1014,15 +1021,23 @@ writeNode(WorkPlain *wp, int fd, SFSNode *node) {
 }
 
 void 
-SFSWriteDump(SFSTree *info, char *filename) {
+SFSWriteDump(SFSTree *info, char *filename, void *extradata, u_int32_t extrasize) {
        int                             fd;
        off_t                           size = info->totalen + SFSTDHSZ;
        SFSTreeDumpHeader       dh;
 
-       if ( (fd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_EXLOCK, 0666)) < 0 )
-               tlog(TL_CRIT|TL_EXIT, "Can not open file '%s': %s", strerror(errno));
+       if ( (fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0 )
+               tlog(TL_CRIT|TL_EXIT, "Can not open file '%s': %s", filename, strerror(errno));
+
+       if ( flock(fd, LOCK_EX) < 0 )
+               tlog(TL_CRIT|TL_EXIT, "flock failed: %s", strerror(errno));
+
+       if ( extrasize == 0 )
+               extradata = NULL;
+       else if ( extradata == NULL )
+               extrasize = 0;
 
-       if ( lseek(fd, size, SEEK_SET) < 0 )
+       if ( lseek(fd, size + MAXALIGN(extrasize) , SEEK_SET) < 0 )
                tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno));
 
        dh.version = SFSTREE_VERSION;
@@ -1031,12 +1046,25 @@ SFSWriteDump(SFSTree *info, char *filename) {
        dh.datasize = info->datasize;
        dh.totalen = info->totalen;
        dh.nnodes = info->nnodes;
+       dh.extrasize = extrasize;
 
        if ( lseek(fd, 0, SEEK_SET) < 0 )
                tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno));
        if ( write(fd, &dh, SFSTDHSZ) != SFSTDHSZ )
                tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno));
 
+       if ( extrasize ) {
+               if ( write(fd, extradata, extrasize) != extrasize )
+                       tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno));
+               if ( extrasize != MAXALIGN(extrasize) ) {
+                       char dummy[8] = {0,0,0,0,0,0,0,0};
+                       if ( write(fd, dummy, MAXALIGN(extrasize) - extrasize ) != MAXALIGN(extrasize) - extrasize )
+                               tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno));
+
+                       extrasize = MAXALIGN(extrasize);
+               }
+       }
+
        if ( info->plainmemory ) {
                if ( write(fd, info->node, info->totalen) != info->totalen )
                        tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno));
@@ -1046,14 +1074,15 @@ SFSWriteDump(SFSTree *info, char *filename) {
                wp.info = info;
                wp.offset = 0;
                
-               writeNode(&wp, fd, info->node);
+               writeNode(&wp, fd, info->node, extrasize);
        }
        
+       flock(fd, LOCK_UN);
        close(fd);
 }
 
 static SFSNode*
-readNode(SFSTree *info, int fd, char *buf, int bufsize) {
+readNode(SFSTree *info, int fd, char *buf, int bufsize, int extrasize) {
        SFSNode *node;
        int             size;
 
@@ -1068,10 +1097,10 @@ readNode(SFSTree *info, int fd, char *buf, int bufsize) {
 
        if ( node->isskip ) {
                if (node->haschild) {
-                       if ( lseek(fd, *(Opaque*)node->data + SFSTDHSZ, SEEK_SET) < 0 )
+                       if ( lseek(fd, *(Opaque*)node->data + SFSTDHSZ + extrasize, SEEK_SET) < 0 )
                                tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno));
                        *(SFSNode**)( (char*)(node->data) ) = 
-                               readNode(info, fd, buf, bufsize);
+                               readNode(info, fd, buf, bufsize, extrasize);
                }
        } else {
                SFSNodeData *nd = node->data;
@@ -1079,10 +1108,10 @@ readNode(SFSTree *info, int fd, char *buf, int bufsize) {
 
                for(i=0;i<node->nchar;i++) {
                        if (nd->haschild) {
-                               if ( lseek(fd, *(Opaque*)(((char*)nd) + nd->child ) + SFSTDHSZ, SEEK_SET) < 0 )
+                               if ( lseek(fd, *(Opaque*)(((char*)nd) + nd->child ) + SFSTDHSZ + extrasize, SEEK_SET) < 0 )
                                        tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno));
                                *(SFSNode**) (((char*)nd) + nd->child ) = 
-                                       readNode(info, fd, buf, bufsize);
+                                       readNode(info, fd, buf, bufsize, extrasize);
                        }
                        nd++;
                }
@@ -1092,16 +1121,23 @@ readNode(SFSTree *info, int fd, char *buf, int bufsize) {
 }
 
 void
-SFSReadDump(SFSTree *info, char *filename) {
+SFSReadDump(SFSTree *info, char *filename, void **extradata, u_int32_t *extrasize) {
        int                 fd;
        SFSTreeDumpHeader   dh;
        char                            *buf;
-       int                                     bufsize; 
-       
+       int                                     bufsize;
+
+       if ( extradata )
+               *extradata = NULL;
+       if (extrasize )
+               *extrasize = 0;
+
        memset(info,0,sizeof(SFSTree));
 
-       if ( (fd = open(filename, O_RDONLY|O_SHLOCK)) < 0 )
+       if ( (fd = open(filename, O_RDONLY)) < 0 )
                tlog(TL_CRIT|TL_EXIT, "Can not open file '%s': %s", strerror(errno));
+       if ( flock(fd, LOCK_SH) < 0 )
+               tlog(TL_CRIT|TL_EXIT, "flock failed: %s", strerror(errno));
 
        if ( read(fd, &dh, SFSTDHSZ) != SFSTDHSZ )
                tlog(TL_CRIT|TL_EXIT, "read failed: %s", strerror(errno));
@@ -1117,19 +1153,40 @@ SFSReadDump(SFSTree *info, char *filename) {
        info->nnodes = dh.nnodes;
        info->datasize = dh.datasize;
 
+       if ( dh.extrasize ) {
+               void    *pointer = tmalloc( MAXALIGN(dh.extrasize) );
+
+               if ( read(fd, pointer, MAXALIGN(dh.extrasize)) != MAXALIGN(dh.extrasize) )
+                       tlog(TL_CRIT|TL_EXIT, "read failed: %s", strerror(errno));
+
+               if ( extradata )
+                       *extradata = pointer;
+               else 
+                       tfree(pointer);
+
+               if ( extrasize )
+                       *extrasize = dh.extrasize;
+       }
+
        /* allocate buffer with max allowed size */
        bufsize = SFSNHRDSZ + 256*(sizeof(SFSNodeData) + sizeof(void*) + info->datasize);
        buf = tmalloc( bufsize );
-       info->node = readNode(info, fd, buf, bufsize);
+       info->node = readNode(info, fd, buf, bufsize, MAXALIGN(dh.extrasize));
        tfree(buf);
 
+       flock(fd, LOCK_UN);
        close(fd);
 }
 
 void
-SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size) {
+SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size, void **extradata, u_int32_t *extrasize) {
        SFSTreeDumpHeader       *dh;
 
+       if ( extradata )
+               *extradata = NULL;
+       if (extrasize )
+               *extrasize = 0;
+
        memset(info,0,sizeof(SFSTree));
 
        if ( size && size < SFSTDHSZ )
@@ -1143,14 +1200,22 @@ SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size) {
                tlog(TL_CRIT|TL_EXIT, "sizeof(Opaque) mismatch");
        if ( dh->headersize != SFSTDHSZ )
                tlog(TL_CRIT|TL_EXIT, "Tree's header size mismatch (should be %d but %d bytes)", SFSTDHSZ, dh->headersize);
-       if ( size && size != dh->totalen + SFSTDHSZ )
-               tlog(TL_CRIT|TL_EXIT, "Memory size mismatch (should be %d but %d bytes)", dh->totalen + SFSTDHSZ, size);
+       if ( size && size != dh->totalen + SFSTDHSZ  + MAXALIGN(dh->extrasize) )
+               tlog(TL_CRIT|TL_EXIT, "Memory size mismatch (should be %d but %d bytes)", dh->totalen + SFSTDHSZ + dh->extrasize , size);
 
        info->totalen = dh->totalen;
        info->nnodes = dh->nnodes;
        info->datasize = dh->datasize;
        info->plainmemory = 1;
 
+       if ( dh->extrasize ) {
+               if ( extradata )
+                       *extradata = ((char*)pointer) + SFSTDHSZ;
+
+               if ( extrasize )
+                       *extrasize = dh->extrasize;
+       }
+
        if ( info->totalen && info->nnodes ) 
-               info->node = (SFSNode*)( ((char*)pointer) + SFSTDHSZ );
+               info->node = (SFSNode*)( ((char*)pointer) + SFSTDHSZ + MAXALIGN(dh->extrasize) );
 }