00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00028
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
00145
00146
00147
00148 AddEntry(tree, key, type, rsize, data);
00149 TREAD(&key, sizeof(key), "new key");
00150 }
00151 }
00152
00153
00154
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 }