tree/mux_tree.c

Go to the documentation of this file.
00001 
00002 /*
00003  * $Id: mux_tree.c,v 1.2 2005/06/23 22:02:14 av1-op Exp $
00004  *
00005  * Author: Markus Stenberg <fingon@iki.fi>
00006  *
00007  *  Copyright (c) 1996 Markus Stenberg
00008  *       All rights reserved
00009  *
00010  * Created: Mon Nov 25 11:41:43 1996 mstenber
00011  * Last modified: Mon Jun 22 07:27:06 1998 fingon
00012  *
00013  */
00014 
00015 #define FATAL(msgs...) \
00016 { fprintf(stderr, ##msgs); exit(1); }
00017 
00018 #define TREAD(to,len,msg) \
00019 if (feof(f)) FATAL("ERROR READING FILE (%s): EOF.\n", msg); \
00020 if (fread(to,1,len,f) != len) \
00021 FATAL("ERROR READING FILE (%s): NOT ENOUGH READ!\n", msg);
00022 
00023 #define TSAVE(from,len,msg) \
00024 if (fwrite(from, 1, len, tree_file) != len) \
00025 FATAL("ERROR WRITING FILE (%s): NOT ENOUGH WRITTEN(?!?)\n", msg);
00026 
00027 /* Main aim: Attempt to provide 1-1 interface when compared to my
00028    old rbtc code and the new AVL code */
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 
00034 #include "tree.h"
00035 #include "mux_tree.h"
00036 
00037 #define Create(var,typ,count) \
00038 if (!(var = (typ *) calloc(sizeof (typ), count))) \
00039 { fprintf(stderr, "Error mallocating!\n"); exit(1); }
00040 
00041 static int NodeCompare(Node * a, Node * b)
00042 {
00043     if (a->key < b->key)
00044         return -1;
00045     return (a->key > b->key);
00046 }
00047 
00048 static void NodeDelete(Node * a)
00049 {
00050     if (a->data)
00051         free((void *) a->data);
00052     free((void *) a);
00053 }
00054 
00055 void AddEntry(Tree * tree, muxkey_t key, dtype_t type, dsize_t size,
00056     void *data)
00057 {
00058     Node *foo;
00059 
00060     if (!tree)
00061         return;
00062     Create(foo, Node, 1);
00063     foo->key = key;
00064     foo->data = data;
00065     foo->type = type;
00066     foo->size = size;
00067     tree_add(tree, NodeCompare, foo, NodeDelete);
00068 }
00069 
00070 Node *FindNode(Tree tree, muxkey_t key)
00071 {
00072     Node foo;
00073 
00074     foo.key = key;
00075     return tree_srch(&tree, NodeCompare, &foo);
00076 }
00077 
00078 void DeleteEntry(Tree * tree, muxkey_t key)
00079 {
00080     Node foo;
00081 
00082     if (FindNode(*tree, key)) {
00083         foo.key = key;
00084         tree_delete(tree, NodeCompare, &foo, NodeDelete);
00085     }
00086 }
00087 
00088 static FILE *tree_file;
00089 
00090 static int nodesave_count;
00091 
00092 static int NodeSave(Node * n)
00093 {
00094     TSAVE(&n->key, sizeof(n->key), "key");
00095     TSAVE(&n->type, sizeof(n->type), "type");
00096     TSAVE(&n->size, sizeof(n->size), "size");
00097     if (n->size > 0)
00098         TSAVE(n->data, n->size, "data");
00099     nodesave_count++;
00100     return 1;
00101 }
00102 
00103 int SaveTree(FILE * f, Tree tree)
00104 {
00105     muxkey_t key;
00106 
00107     nodesave_count = 0;
00108     tree_file = f;
00109     tree_trav(&tree, NodeSave);
00110     key = -1;
00111     fwrite(&key, sizeof(key), 1, tree_file);
00112     return nodesave_count;
00113 }
00114 
00115 static void MyLoadTree(FILE * f, Tree * tree, int (*sizefunc)(int))
00116 {
00117     muxkey_t key;
00118     dtype_t type;
00119     dsize_t osize;
00120     int nsize, rsize;
00121     void *data;
00122 
00123     TREAD(&key, sizeof(key), "first key");
00124     while (key >= 0 && !feof(f)) {
00125         TREAD(&type, sizeof(type), "type");
00126         TREAD(&osize, sizeof(osize), "size");
00127         if (sizefunc && (rsize = sizefunc(type)) >= 0) {
00128             nsize = osize > rsize ? osize : rsize;
00129         } else
00130             nsize = rsize = osize;
00131         if (nsize) {
00132             if (!(data = malloc(nsize))) {
00133                 printf("Error malloccing!\n");
00134                 exit(1);
00135             }
00136             if (osize)
00137                 TREAD(data, osize, "data");
00138 
00139             if (nsize > osize)
00140                 memset(data + osize, 0, nsize - osize);
00141         } else
00142             data = NULL;
00143 
00144         /* Set node size to the real type size, rather than the read size,
00145          * so that the object will get 'truncated' to the right size on the
00146          * next dump.
00147          */
00148         AddEntry(tree, key, type, rsize, data);
00149         TREAD(&key, sizeof(key), "new key");
00150     }
00151 }
00152 
00153 
00154 /* This is a _MONSTER_ :P */
00155 void ClearTree(Tree * tree)
00156 {
00157     tree_mung(tree, NodeDelete);
00158 }
00159 
00160 void LoadTree(FILE * f, Tree * tree, int (*sizefunc)(int))
00161 {
00162     ClearTree(tree);
00163     MyLoadTree(f, tree, sizefunc);
00164 }
00165 
00166 void UpdateTree(FILE * f, Tree * tree, int(*sizefunc)(int))
00167 {
00168     MyLoadTree(f, tree, sizefunc);
00169 }
00170 
00171 void GoThruTree(Tree tree, int (*func) (Node *))
00172 {
00173     tree_trav(&tree, func);
00174 }

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