Disk ARchive
2.4.5
|
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