Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

stddata.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      stddata.cc
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include <stdlib.h>
00022 
00023 #include "analy_register.h"
00024 
00025 #include "htatom.h"
00026 #include "stddata.h"
00027 #include "stream.h"
00028 #include "tools.h"
00029 
00030 /*
00031  *   Area
00032  */
00033 void Area::init()
00034 {
00035         a = NULL;
00036 }
00037 
00038 static void areaload(ht_object_stream *st, area_s *&p, int level, int &left)
00039 {
00040         if (left<=0) {
00041                 p = NULL;
00042                 return;
00043         }
00044         p = (area_s *) smalloc0(sizeof(area_s));
00045         if ((level<=1) || (left<=1)) {
00046                 st->getObject(p->start, "start");
00047                 st->getObject(p->end, "end");
00048                 p->left = p->right = NULL;
00049                 left--;
00050         } else {
00051                 areaload(st, p->left, level / 2, left);
00052                 st->getObject(p->start, "start");
00053                 st->getObject(p->end, "end");
00054                 left--;
00055                 areaload(st, p->right, level / 2 -1, left);
00056         }
00057 }
00058 
00059 int     Area::load(ht_object_stream *st)
00060 {
00061         int count;
00062         GET_INT_DEC(st, count);
00063         areaload(st, a, count, count);
00064         return st->get_error();
00065 }
00066 
00067 void Area::done()
00068 {
00069         freeRecursive(a);
00070 }
00071 
00072 OBJECT_ID       Area::object_id() const
00073 {
00074         return ATOM_AREA;
00075 }
00076 
00077 static area_s *areaget(area_s *p, Object *V)
00078 {
00079         if (p) {
00080                 if (V->compareTo(p->start) < 0) return areaget(p->left, V);
00081                 if (V->compareTo(p->end) >= 0) return areaget(p->right, V);
00082                 /*if ((V >= (p->start)) && (V < (p->end)))*/ return p;
00083         } else return NULL;
00084 }
00085 
00086 area_s *Area::getArea(Object *at)
00087 {
00088         return areaget(a, at);
00089 }
00090 
00091 static void areaadd(area_s *&p, Object *Start, Object *End)
00092 {
00093         if (p) {
00094                 if ((Start->compareTo(p->start) >= 0) && (Start->compareTo(p->end)<=0)) {
00095                         if (p->end->compareTo(End) < 0) {
00096                                 delete p->end;
00097                                 p->end = End->duplicate();
00098                         }
00099                         if ((End->compareTo(p->start) >= 0) && (End->compareTo(p->end)<=0)) {
00100                                 if (p->start->compareTo(Start) > 0) {
00101                                         delete p->start;
00102                                         p->start = Start->duplicate();
00103                                 }
00104                         }
00105                         return;
00106                 }
00107                 if ((End->compareTo(p->start) >= 0) && (End->compareTo(p->end) <= 0)) {
00108                         if (p->start->compareTo(Start) > 0) {
00109                                 delete p->start;
00110                                 p->start = Start->duplicate();
00111                         }
00112                         return;
00113                 }
00114                 if (Start->compareTo(p->end) > 0) areaadd(p->right, Start, End);
00115                                           else  areaadd(p->left, Start, End);
00116         } else {
00117                 // new p
00118                 area_s *tmp = (area_s *) smalloc(sizeof(area_s));
00119                 p = tmp;
00120                 p->start = Start->duplicate();
00121                 p->end = End->duplicate();
00122                 p->left = NULL;
00123                 p->right = NULL;
00124         }
00125 }
00126 
00127 void Area::add(Object *Start, Object *End)
00128 {
00129         areaadd(a, Start, End);
00130 }
00131 
00132 static bool areacontains(area_s *p, Object *V)
00133 {
00134         if (p) {
00135                 if (V->compareTo(p->start) < 0) return areacontains(p->left, V);
00136                 if (V->compareTo(p->end) >= 0) return areacontains(p->right, V);
00137                 /*if ((V >= (p->start)) && (V < (p->end)))*/ return true;
00138         } else return false;
00139 }
00140 
00141 bool Area::contains(Object *v)
00142 {
00143         if (v->instanceOf(ATOM_ADDRESS_INVALID)) return false;
00144         return areacontains(a, v);
00145 }
00146 
00147 static void areafindnext(area_s *p, Object *from, Object **res)
00148 {
00149         if (!from || from->compareTo(p->start) < 0) {
00150                 *res = p->start;
00151                 if (p->left) areafindnext(p->left, from, res);
00152         } else if (from->compareTo(p->end) >= 0) {
00153                 if (p->right) areafindnext(p->right, from, res);
00154         } else *res = from;
00155 }
00156 
00157 Object *Area::findNext(Object *from)
00158 {
00159         Object *res = NULL;
00160         if (a) areafindnext(a, from, &res);
00161         return res;
00162 }
00163 
00164 static void areafindprev(area_s *p, Object *from, Object **res)
00165 {
00166 //FIXME ??:
00167         if (p) {
00168                 if (!from || from->compareTo(p->end) >= 0) {
00169                         *res = p->end;
00170                         areafindprev(p->right, from, res);
00171                 } else if (from->compareTo(p->start) < 0) {
00172                         areafindprev(p->left, from, res);
00173                 } else *res = from;
00174         };
00175 }
00176 
00177 Object *Area::findPrev(Object *from)
00178 {
00179         Object *res = NULL;
00180         areafindprev(a, from, &res);
00181         return res;
00182 }
00183 
00184 void Area::freeRecursive(area_s *p)
00185 {
00186         if (p) {
00187                 freeRecursive(p->left);
00188                 freeRecursive(p->right);
00189                 delete p->start;
00190                 delete p->end;
00191                 free(p);
00192         }
00193 }
00194 
00195 static void areacount(area_s *p, int &c, Object **startend)
00196 {
00197         if (p) {
00198                 areacount(p->left, c, startend);
00199                 if (!*startend || p->start->compareTo(*startend) != 0) c++;
00200                 *startend = p->end;
00201                 areacount(p->right, c, startend);
00202         }
00203 }
00204 
00205 static void areastore(ht_object_stream *f, area_s *p, Object **startend)
00206 {
00207         if (p) {
00208                 areastore(f, p->left, startend);
00209                 if (!*startend) {
00210                         f->putObject(p->start, "start");
00211                 } else {
00212                         if ((*startend)->compareTo(p->start) != 0) {
00213                                 f->putObject(*startend, "end");
00214                                 f->putObject(p->start, "start");
00215                         }
00216                 }
00217                 *startend = p->end;
00218                 areastore(f, p->right, startend);
00219         }
00220 }
00221 
00222 void Area::store(ht_object_stream *f)
00223 {
00224         int count = 0;
00225         Object *start = NULL;
00226         areacount(a, count, &start);
00227         PUT_INT_DEC(f, count);
00228         start = NULL;
00229         areastore(f, a, &start);
00230         if (start!=NULL) f->putObject(start, "end");
00231 }
00232 
00233 #ifdef DEBUG_FIXNEW
00234 static void areadump(int sp, area_s *A)
00235 {
00236         if (A) {
00237                 for (int i=0; i<sp; i++) printf(" ");
00238                 char buf[1024];
00239                 ht_snprintf(buf, sizeof buf, "%y %y\n", A->start, A->end);
00240                 printf(buf);
00241                 ++sp;++sp;
00242                 areadump(sp, A->left);
00243                 areadump(sp, A->right);
00244         }
00245 }
00246 
00247 void Area::dump()
00248 {
00249         areadump(1, a);
00250 }
00251 #endif
00252 
00253 /*
00254  *  BUILDER etc.
00255  */
00256 
00257 BUILDER(ATOM_AREA, Area)
00258 
00259 bool init_stddata()
00260 {
00261         REGISTER(ATOM_AREA, Area)
00262         return true;
00263 }
00264 
00265 void done_stddata()
00266 {
00267         UNREGISTER(ATOM_AREA, Area)
00268 }

Generated on Fri May 7 21:15:43 2004 by doxygen 1.3.5