libsrc/tumbleari.cxx

Go to the documentation of this file.
00001 /**********************************************************************
00002  * Copyright 2002 Jeff Rush <jrush@taupro.com>
00003  * Original Copyright 1979-2002 Udanax.com
00004  *
00005  * This file is part of the Udanax xanalogical storage system.
00006  *
00007  * Udanax is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Udanax is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with Udanax; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  **********************************************************************/
00021 
00030 /* Modification History:
00031  * $Log: tumbleari.cxx,v $
00032  * Revision 1.10  2004/09/11 13:59:21  jrush
00033  * Changed all fprintf's to stderr to use the Nana library L() macro.  Also
00034  * removed a 2-3 minor compiler warnings.
00035  *
00036  * Revision 1.9  2004/09/04 16:02:18  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.8  2002/07/26 04:33:47  jrush
00040  * Replaced gerror() with assert()
00041  *
00042  * Revision 1.7  2002/05/28 04:22:29  jrush
00043  * Adjusted source files to comply with GPL licensing.
00044  *
00045  * Revision 1.6  2002/05/28 02:52:23  jrush
00046  * Made static any functions and global variables private to this source file
00047  * and commented out any unused functions.
00048  *
00049  * Revision 1.5  2002/04/12 11:56:43  jrush
00050  * Reorganized include file layout, renamed xanadu.h to udanax.h and
00051  * typecontext/typecrumcontext to C++ class Context/CrumContext.
00052  *
00053  * Revision 1.4  2002/04/09 21:45:46  jrush
00054  * Renamed class 'tumbler' to 'Tumbler', for consistency with Python sources,
00055  * and changed typeisa from typedef to a subclass, in preparation for cleaning
00056  * up the type/class tree.
00057  *
00058  * Revision 1.3  2002/04/06 15:01:17  jrush
00059  * Changed INT to just 'int'.
00060  *
00061  * Revision 1.2  2002/02/14 09:27:43  jrush
00062  * Cleaned up source:
00063  *
00064  * 1. ran thru the indent tool to achieve a standard look,
00065  * 2. added structured comments at top for use with DOxygen reporting
00066  *    as well as CVS keywords,
00067  * 3. fixed compiler warnings re ambiguous assign/compares,
00068  *    needed casts and unused/uninitialized variables,
00069  * 4. fixed funcs that didn't specify a return type,
00070  * 5. centralized prototypes in protos.h, removing incomplete ones,
00071  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00072  * 7. fixed initializer nesting in tumbler constants,
00073  * 8. renamed vars that conflict with C++ keywords (new, this),
00074  * 9. fixed global/extern confusion re some global vars.
00075  *
00076  */
00077 
00078 #include <memory.h>
00079 #include "udanax.h"
00080 
00081 /* Various integers relating to humbers */
00082 #define FIRSTCHAR  0x100
00083 #define SECONDCHAR 0x10000
00084 #define THIRDCHAR  0x1000000
00085 #define FOURTHCHAR 0xffffffff
00086 
00087 /* --------- Routines below set and change tumblers -------- */
00088 
00089 #define mlengthoflength(x) (unsigned int)((*(x))<128?1:lengthoflength(x))
00090 #define mexponentof(x) (humber)((x)+mlengthoflength(x))
00091 
00099     static unsigned int
00100 lengthoflength(
00101     humber ptr)
00102 {                                      /* YUCK */
00103     int i;
00104 
00105     if (*ptr < 128)
00106         return 1;
00107 
00108     switch (*ptr) {
00109     case 128:                         /* break to ultraINT and specialcases */
00110         assert(0); // ultraINTs not defined yet
00111         return 12134;
00112     case 129:
00113         return 1 + lengthoflength(ptr + 1);
00114     case 130:
00115         return 3;
00116     case 131:
00117         return 4;
00118     case 132:
00119         return 5;
00120     case 133:
00121         return 6;
00122     default:
00123         L("case %d in lengthoflength close by bytes:\n\t", ptr[-1]);
00124 
00125         for (i = -6; i < 0; i++)
00126             L("%x ", ptr[i - 1]);
00127         L(": ");
00128 
00129         for (i = 0; i < 6; i++)
00130             L("%x ", ptr[i - 1]);
00131         L("\n");
00132 
00133         assert(0); // Bad lengthoflength
00134         return 1;
00135     }
00136 }
00137 
00145     unsigned int
00146 functionlengthof(
00147     humber ptr)
00148 {                                      /* length of humber or vartumbler */
00149     int i;
00150 
00151 /* typedef union{char charlongchar[sizeof(int)];int charlonglong;} typecharlong; typecharlong temp; temp.charlonglong
00152  * = 0; */
00153     if (*ptr < 128)
00154         return 1;
00155 
00156     switch (*ptr++) {
00157     case 128:                         /* break to ultralong and specialcases */
00158         assert(0); // ultralongs not defined yet
00159         return 12134;
00160 
00161     case 129:                         /* negative */
00162         return 1 + lengthof(ptr + 1); /* is this right if we use 1 in the length of length */
00163     case 133:
00164         return 5;
00165     case 132:
00166         return 4;
00167     case 131:
00168         return 3;
00169     case 130:
00170         return 2;
00171 
00172     default:
00173         L("case %d in lengthof close by bytes:\n\t", ptr[-1]);
00174         for (i = -6; i < 0; i++)
00175             L("%x ", ptr[i - 1]);
00176         L(": ");
00177 
00178         for (i = 0; i < 6; i++)
00179             L("%x ", ptr[i - 1]);
00180         L("\n");
00181 
00182         assert(0); // Bad length in functionlengthof
00183         return 1;
00184     }
00185 }
00186 
00194     unsigned int
00195 functionintof(
00196     humber h)
00197 {
00198     int k;
00199     int i;
00200 
00201     if (((unsigned)h[0]) <= 127) {
00202         return h[0];
00203 
00204     } else {
00205         k = h[0] - 128;
00206         switch (k) {
00207         case 0:                       /* reserved for chge or wierd stuff */
00208             L("case %d in intof first 6 bytes: ", k);
00209             for (i = 0; i < 6; i++)
00210                 L("%x ", h[i]);
00211             assert(0); // weird length 0 in intof
00212             break;
00213         case 2:
00214 /* L("%x ",h[1]); */
00215             return (h[1]);
00216         case 3:
00217 /* L("%x %x ",h[1],h[2]); */
00218             return ((h[1] << 8) + h[2]);
00219         case 4:
00220 /* L("%x %x %x ",h[1],h[2],h[3]); */
00221             return ((((h[1] << 8) + h[2]) << 8) + h[3]);
00222         case 5:
00223 /* L("%x %x %x %x ",h[1],h[2],h[3],h[4]); */
00224             k = (((((h[1] << 8) + h[2]) << 8) + h[3]) << 8) + h[4];
00225             if (k == -1)
00226                 assert(0); // -1 in intof
00227 
00228             return k;
00229 
00230         default:
00231             L("case %d in intof close by bytes: ", k);
00232             for (i = -8; i < 0; i++)
00233                 L("%x ", h[i]);
00234             L(": ");
00235 
00236             for (i = 0; i < 6; i++)
00237                 L("%x ", h[i]);
00238             L("\n");
00239 
00240             for (i = -8; i < 0; i++)
00241                 L("%d ", h[i]);
00242             L(": ");
00243 
00244             for (i = 0; i < 6; i++)
00245                 L("%d ", h[i]);
00246             L("\n");
00247 
00248             assert(0); // in intof default case
00249             return 33333;
00250         }
00251     }
00252     return 0;                          /* for lint */
00253 }
00254 
00262     int
00263 tumblerptrtofixed(
00264     humber   p,
00265     Tumbler *tptr)
00266 {
00267     tumblerclear(tptr);
00268 
00269     int temp = lengthoftumbler(p);
00270 
00271     humber tempexp = mexponentof(p);
00272     if (*tempexp <= 127)
00273         tptr->exp = -*tempexp;
00274     else
00275         tptr->exp = -functionintof(mexponentof(p));
00276 
00277     humber humberEnd = p + temp;
00278 
00279     humber mantissadigitptr;
00280     p += mlengthoflength(p);
00281     if (*(p) < 128)                  /* always the case */
00282         mantissadigitptr = p + 1;
00283     else
00284         mantissadigitptr = p + functionlengthof(p);
00285 
00286     int i;
00287     for (i = 0; i < NPLACES && mantissadigitptr < humberEnd; i++) {
00288         if (mantissadigitptr[0] <= 127) {       /* see intof */
00289             tptr->mantissa[i] = mantissadigitptr[0];
00290             mantissadigitptr += 1;
00291         } else {
00292             tptr->mantissa[i] = functionintof(mantissadigitptr);
00293             mantissadigitptr += functionlengthof(mantissadigitptr);
00294         }
00295     }
00296 
00297     return temp;
00298 }
00299 
00307     static unsigned int
00308 calculatetotallength(
00309     unsigned int lengthofbody)
00310 /* of tumbler ie adds length of exponent in length of body */
00311 {
00312     if (lengthofbody < 127) {
00313         return (lengthofbody + 1);
00314     } else if (lengthofbody < FIRSTCHAR - 1) {
00315         return (lengthofbody + 2);
00316     } else if (lengthofbody < SECONDCHAR - 1 /* ? */ ) {
00317         return (lengthofbody + 3);
00318     } else if (lengthofbody < THIRDCHAR - 1) {
00319         return (lengthofbody + 4);
00320     } else if (lengthofbody < FOURTHCHAR /* - 1 */ ) {
00321         return (lengthofbody + 5);
00322     } else
00323         assert(0); // difficultly large length
00324 
00325     return 333333;
00326 }
00327 
00335     int
00336 tumblerfixedtoptr(
00337     Tumbler *ptr,
00338     humber   p)
00339 {
00340     unsigned int lengthofexponent;
00341     unsigned int digitlength;
00342     unsigned int totallength;
00343     unsigned int lengthlength;
00344     unsigned int numberofsignificantdigits;
00345 
00346     if (ptr->sign)
00347         assert(0); // negative tumbler in tumblerfixedtoptr
00348 
00349     humber op = p;
00350 
00351 /* dumptumbler(ptr); */
00352 
00353     unsigned int tumblerlength = 0;
00354     humberput(-ptr->exp, p, &lengthofexponent);
00355 
00356     p             += lengthofexponent;
00357     tumblerlength += lengthofexponent;
00358 
00359     numberofsignificantdigits = nstories(ptr);
00360 
00361     unsigned int i;
00362     for (i = 0; i < numberofsignificantdigits; i++) {
00363         humberput((int) ptr->mantissa[i], p, &digitlength);
00364         p += digitlength;
00365         tumblerlength += digitlength;
00366     }
00367 
00368     totallength  = calculatetotallength(tumblerlength);
00369     lengthlength = intlengthoflength(totallength);
00370 
00371     movmem(op, op + ptr->sign + lengthlength, tumblerlength);
00372     humberput((int) totallength, op + ptr->sign, &lengthlength);
00373 
00374     return totallength;
00375 }
00376 
00384     humber
00385 humberput(
00386     /* unsigned */ int i,
00387     humber             humberfoo,
00388     unsigned int      *lengthofhumberptr)
00389 {
00390     if (i == -1)
00391         assert(0); // humberput of -1
00392 
00393     if (i < 0) {
00394         L("humberput of %d\n", i);
00395         assert(0); // humberput of negative number
00396     }
00397 
00398     if (i < 128) {
00399         *lengthofhumberptr = 1;
00400         *humberfoo         = i;
00401 
00402     } else {                           /* if(i<256*256*256*256) impossible for a 32 bit int */
00403 
00404 /* NOTE zzz check to see that compiler does the 256*256 at compile time */
00405 /* and fix these damn shifts sometime to be efficient */
00406         if (i < FIRSTCHAR) {
00407             *lengthofhumberptr = 2;
00408             *(humberfoo)       = 128 + 2;
00409             *(humberfoo + 1)   = i;
00410 
00411         } else if (i < SECONDCHAR) {
00412             *lengthofhumberptr = 3;
00413             *(humberfoo)       = 128 + 3;
00414             *(humberfoo + 1)   = i >> 8;
00415             *(humberfoo + 2)   = i & 0xff;
00416 
00417         } else if (i < THIRDCHAR) {
00418             *lengthofhumberptr = 4;
00419             *(humberfoo)       = 128 + 4;
00420             *(humberfoo + 1)   = i >> 16;
00421             *(humberfoo + 2)   = i >> 8 & 0xff;
00422             *(humberfoo + 3)   = i & 0xff;
00423 
00424         } else {
00425             *lengthofhumberptr = 5;
00426             *(humberfoo)       = 128 + 5;
00427             *(humberfoo + 1)   = i >> 24;
00428             *(humberfoo + 2)   = i >> 16 & 0xff;
00429             *(humberfoo + 3)   = i >> 8 & 0xff;
00430             *(humberfoo + 4)   = i & 0xff;
00431         }
00432     }
00433 
00434 /* L("humberput puts %d\n",i); */
00435     return humberfoo;
00436 }
00437 
00445     humber
00446 humber3put(
00447     /* unsigned */ int i,
00448     humber             humberfoo,
00449     unsigned int      *lengthofhumberptr)
00450 {
00451     if (i == -1)
00452         assert(0); // humber3put of -1
00453 
00454     if (i < 0) {
00455         L("humberput of %d\n", i);
00456         assert(0); // humber3put of negative number
00457     }
00458 
00459     if (i < SECONDCHAR) {
00460         *lengthofhumberptr = 3;
00461         *(humberfoo)       = 128 + 3;
00462         *(humberfoo + 1)   = i >> 8;
00463         *(humberfoo + 2)   = i & 0xff;
00464     } else {
00465         L("in humber3put i = %d\n", i);
00466         assert(0); // humber3put called with too larg a value
00467     }
00468 
00469 /* 
00470  * }else if (i<THIRDCHAR){ *lengthofhumberptr = 4; *(humberfoo ) = 128 +4;
00471  * *(humberfoo + 1) = i>>16 ; *(humberfoo + 2) = i>>8 &0xff; *(humberfoo + 3) 
00472  * = i & 0xff; }else { *lengthofhumberptr = 5; *(humberfoo ) = 128 +5;
00473  * *(humberfoo + 1) = i>>24 ; *(humberfoo + 2) = i>>16 &0xff; *(humberfoo +
00474  * 3) = i>>8 &0xff; *(humberfoo + 4) = i & 0xff; } } */
00475 /* L("humberput puts %d\n",i); */
00476 
00477     return humberfoo;
00478 }
00479 
00487     unsigned int
00488 intlengthoflength(
00489     unsigned int i)
00490 {
00491     if      (i < 127)        return 1;
00492     else if (i < FIRSTCHAR)  return 2;
00493     else if (i < SECONDCHAR) return 3;
00494     else if (i < THIRDCHAR)  return 4;
00495     else if (i < FOURTHCHAR) return 5;
00496 
00497     assert(0); // impossible  in intlengthof
00498     return 0;
00499 }

Generated on Sun Aug 21 04:18:15 2005 for Udanax-Green by doxygen1.3.4