Disk ARchive  2.4.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
.pc/delete2/infinint.hpp
00001 /*********************************************************************/
00002 // dar - disk archive - a backup/restoration program
00003 // Copyright (C) 2002-2052 Denis Corbin
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 // to contact the author : dar.linux@free.fr
00020 /*********************************************************************/
00021 // $Id$
00022 //
00023 /*********************************************************************/
00024 
00025 #ifndef INFININT_HPP
00026 #define INFININT_HPP
00027 
00028 #pragma interface
00029 
00030 #include <sys/types.h>
00031 #include <typeinfo>
00032 
00033 #include "storage.hpp"
00034 #include "integers.hpp"
00035 
00036 class generic_file;
00037 
00038 class infinint
00039 {
00040 public :
00041 
00042     infinint(off_t a = 0) throw(Ememory, Erange, Ebug)
00043         { E_BEGIN; infinint_from(a); E_END("infinint::infinint", "off_t"); };
00044 #if time_t != off_t
00045     infinint(time_t a = 0) throw(Ememory, Erange, Ebug)
00046         { E_BEGIN; infinint_from(a); E_END("infinint::infinint", "off_t"); };
00047 #endif
00048     infinint(const infinint & ref) throw(Ememory, Ebug) 
00049         { E_BEGIN; copy_from(ref); E_END("infinint::infinint", "const infinint &"); };
00050     ~infinint() throw(Ebug) 
00051         { E_BEGIN; detruit(); E_END("infinint::~infinint",""); };
00052     
00053 
00054     infinint & operator = (const infinint & ref) throw(Ememory, Ebug) 
00055         { E_BEGIN; detruit(); copy_from(ref); return *this; E_END("infinint::operator =",""); };
00056 
00057     void read_from_file(int fd) throw(Erange, Ememory, Ebug); // read an infinint from a file
00058     void dump(int fd) const throw(Einfinint, Ememory, Erange, Ebug); // write byte sequence to file 
00059     void read_from_file(generic_file &x) throw(Erange, Ememory, Ebug); // read an infinint from a file
00060     void dump(generic_file &x) const throw(Einfinint, Ememory, Erange, Ebug); // write byte sequence to file 
00061 
00062     infinint & operator += (const infinint & ref) throw(Ememory, Erange, Ebug);
00063     infinint & operator -= (const infinint & ref) throw(Ememory, Erange, Ebug);
00064     infinint & operator *= (unsigned char arg) throw(Ememory, Erange, Ebug);
00065     infinint & operator *= (const infinint & ref) throw(Ememory, Erange, Ebug);
00066     inline infinint & operator /= (const infinint & ref) throw(Einfinint, Erange, Ememory, Ebug);
00067     inline infinint & operator %= (const infinint & ref) throw(Einfinint, Erange, Ememory, Ebug);
00068     infinint & operator >>= (U_32 bit) throw(Ememory, Erange, Ebug);
00069     infinint & operator >>= (infinint bit) throw(Ememory, Erange, Ebug);
00070     infinint & operator <<= (U_32 bit) throw(Ememory, Erange, Ebug);
00071     infinint & operator <<= (infinint bit) throw(Ememory, Erange, Ebug);
00072     infinint operator ++(int a) throw(Ememory, Erange, Ebug) 
00073         { E_BEGIN; infinint ret = *this; ++(*this); return ret; E_END("infinint::operator ++", "int"); };
00074     infinint operator --(int a) throw(Ememory, Erange, Ebug) 
00075         { E_BEGIN; infinint ret = *this; --(*this); return ret; E_END("infinint::operator --", "int"); };
00076     infinint & operator ++() throw(Ememory, Erange, Ebug) 
00077         { E_BEGIN; return *this += 1; E_END("infinint::operator ++", "()"); };
00078     infinint & operator --() throw(Ememory, Erange, Ebug) 
00079         { E_BEGIN; return *this -= 1; E_END("infinint::operator --", "()"); };
00080 
00081     U_32 operator % (U_32 arg) const throw(Einfinint, Ememory, Erange, Ebug) 
00082         { E_BEGIN; return modulo(arg); E_END("infinint::operator %",""); };
00083 
00084         // increment the argument up to a legal value for its storage type and decrement the object in consequence
00085         // note that the initial value of the argument is not ignored !
00086         // when the object is null the value of the argument stays the same as before
00087     template <class T>void unstack(T &v) throw(Ememory, Erange, Ebug) 
00088         { E_BEGIN; infinint_unstack_to(v); E_END("infinint::unstack", typeid(v).name()); };
00089 
00090     friend bool operator < (const infinint &, const infinint &) throw(Erange, Ebug);
00091     friend bool operator == (const infinint &, const infinint &) throw(Erange, Ebug);
00092     friend bool operator > (const infinint &, const infinint &) throw(Erange, Ebug);
00093     friend bool operator <= (const infinint &, const infinint &) throw(Erange, Ebug);
00094     friend bool operator != (const infinint &, const infinint &) throw(Erange, Ebug);
00095     friend bool operator >= (const infinint &, const infinint &) throw(Erange, Ebug);
00096     friend void euclide(infinint a, const infinint &b, infinint &q, infinint &r) throw(Einfinint, Erange, Ememory, Ebug);
00097 
00098 private :
00099     static const int TG = 4;
00100 
00101     enum endian { big_endian, little_endian, not_initialized };
00102     typedef unsigned char group[TG];
00103      
00104     storage *field;
00105 
00106     bool is_valid() const throw();
00107     void reduce() throw(Erange, Ememory, Ebug); // put the object in canonical form : no leading byte equal to zero
00108     void copy_from(const infinint & ref) throw(Ememory, Ebug);
00109     void detruit() throw(Ebug);
00110     void make_at_least_as_wider_as(const infinint & ref) throw(Erange, Ememory, Ebug);
00111     template <class T> void infinint_from(T a) throw(Ememory, Erange, Ebug);
00112     template <class T> void infinint_unstack_to(T &a) throw(Ememory, Erange, Ebug);
00113     template <class T> T modulo(T arg) const throw(Einfinint, Ememory, Erange, Ebug);
00114     signed int difference(const infinint & b) const throw(Erange, Ebug); // gives the sign of (*this - arg) but only the sign !
00115 
00117         // static statments
00118         //
00119     static endian used_endian;
00120     static void setup_endian();
00121 };
00122 
00123 #define OPERATOR(OP) inline bool operator OP (const infinint &a, const infinint &b) throw(Erange, Ebug) \
00124 { \
00125     E_BEGIN; \
00126     return a.difference(b) OP 0; \
00127     E_END("operator OP", "infinint, infinint"); \
00128 }
00129 
00130 OPERATOR(<);
00131 OPERATOR(>);
00132 OPERATOR(<=);
00133 OPERATOR(>=);
00134 OPERATOR(==);
00135 OPERATOR(!=);
00136 
00137 infinint operator + (const infinint &, const infinint &) throw(Erange, Ememory, Ebug);
00138 infinint operator - (const infinint &, const infinint &) throw(Erange, Ememory, Ebug);
00139 infinint operator * (const infinint &, const infinint &) throw(Erange, Ememory, Ebug);
00140 infinint operator * (const infinint &, const unsigned char) throw(Erange, Ememory, Ebug);
00141 infinint operator * (const unsigned char, const infinint &) throw(Erange, Ememory, Ebug);
00142 infinint operator / (const infinint &, const infinint &) throw(Einfinint, Erange, Ememory, Ebug);
00143 infinint operator % (const infinint &, const infinint &) throw(Einfinint, Erange, Ememory, Ebug);
00144 infinint operator >> (const infinint & a, U_32 bit) throw(Erange, Ememory, Ebug);
00145 infinint operator >> (const infinint & a, const infinint & bit) throw(Erange, Ememory, Ebug);
00146 infinint operator << (const infinint & a, U_32 bit) throw(Erange, Ememory, Ebug);
00147 infinint operator << (const infinint & a, const infinint & bit) throw(Erange, Ememory, Ebug);
00148 void euclide(infinint a, const infinint &b, infinint &q, infinint &r) throw(Einfinint, Erange, Ememory, Ebug);
00149 template <class T> inline void euclide(T a, T b, T & q, T &r) 
00150 { 
00151     E_BEGIN;
00152     q = a/b; r = a%b; 
00153     E_END("euclide", "");
00154 };
00155 
00156 inline infinint & infinint::operator /= (const infinint & ref) throw(Einfinint, Erange, Ememory, Ebug)
00157 { 
00158     E_BEGIN;
00159     *this = *this / ref;
00160     return *this;
00161     E_END("infinint::operator /=", "");
00162 }
00163 
00164 inline infinint & infinint::operator %= (const infinint & ref) throw(Einfinint, Erange, Ememory, Ebug)
00165 { 
00166     E_BEGIN;
00167     *this = *this % ref; 
00168     return *this;
00169     E_END("infinint::operator %=", "");
00170 }
00171 
00172 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines