38 #include "../my_config.h"
43 #include <sys/types.h>
66 #define ZEROED_SIZE 50
76 class user_interaction;
94 #if SIZEOF_OFF_T > SIZEOF_TIME_T
95 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
97 { E_BEGIN; limitint_from(a); E_END(
"limitint::limitint",
"off_t"); };
100 { E_BEGIN; limitint_from(a); E_END(
"limitint::limitint",
"size_t"); };
103 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
105 { E_BEGIN; limitint_from(a); E_END(
"limitint::limitint",
"time_t"); };
108 { E_BEGIN; limitint_from(a); E_END(
"limitint::limitint",
"size_t"); };
123 template <
class T>
limitint power(
const T & exponent)
const;
134 { E_BEGIN;
limitint ret = *
this; ++(*this);
return ret; E_END(
"limitint::operator ++",
"int"); };
136 { E_BEGIN;
limitint ret = *
this; --(*this);
return ret; E_END(
"limitint::operator --",
"int"); };
138 { E_BEGIN;
return *
this += 1; E_END(
"limitint::operator ++",
"()"); };
140 { E_BEGIN;
return *
this -= 1; E_END(
"limitint::operator --",
"()"); };
142 U_32 operator % (U_32 arg)
const;
147 template <
class T>
void unstack(T &v)
148 { E_BEGIN; limitint_unstack_to(v); E_END(
"limitint::unstack",
typeid(v).name()); }
153 unsigned char operator [] (
const limitint & position)
const;
157 bool operator < (
const limitint &x)
const {
return field < x.field; };
158 bool operator == (
const limitint &x)
const {
return field == x.field; };
159 bool operator > (
const limitint &x)
const {
return field > x.field; };
160 bool operator <= (
const limitint &x)
const {
return field <= x.field; };
161 bool operator != (
const limitint &x)
const {
return field != x.field; };
162 bool operator >= (
const limitint &x)
const {
return field >= x.field; };
164 static bool is_system_big_endian();
166 #ifdef LIBDAR_SPECIAL_ALLOC
170 B debug_get_max()
const {
return max_value; };
171 B debug_get_bytesize()
const {
return bytesize; };
174 static const int TG = 4;
175 static const U_32 sizeof_field =
sizeof(B);
177 enum endian { big_endian, little_endian, not_initialized };
178 typedef unsigned char group[TG];
183 template <
class T>
void limitint_from(T a);
184 template <
class T> T max_val_of(T x);
185 template <
class T>
void limitint_unstack_to(T &a);
190 static endian used_endian;
191 static const U_I bytesize =
sizeof(B);
192 static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
193 static U_8 zeroed_field[ZEROED_SIZE];
195 static void setup_endian();
203 template <
class B> limitint<B> operator - (
const limitint<B> &,
const limitint<B> &);
204 template <
class B>
inline limitint<B> operator - (
const limitint<B> & a, U_I b)
205 {
return a - limitint<B>(b); }
206 template <
class B> limitint<B> operator * (
const limitint<B> &,
const limitint<B> &);
207 template <
class B>
inline limitint<B> operator * (
const limitint<B> & a, U_I b)
208 {
return a * limitint<B>(b); }
209 template <
class B> limitint<B> operator / (
const limitint<B> &,
const limitint<B> &);
210 template <
class B> limitint<B> operator / (
const limitint<B> & a, U_I b)
211 {
return a / limitint<B>(b); }
212 template <
class B> limitint<B> operator % (
const limitint<B> &,
const limitint<B> &);
213 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit);
214 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit);
215 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit);
216 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit);
217 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit);
218 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit);
219 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit);
220 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit);
221 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit);
222 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit);
224 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
228 E_END(
"euclide",
"");
231 template <
class B>
inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
233 euclide(a, limitint<B>(b), q, r);
236 #ifndef INFININT_BASE_TYPE
237 #error INFININT_BASE_TYPE not defined cannot instantiate template
239 typedef limitint<INFININT_BASE_TYPE> infinint;
253 template <
class B>
typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
257 template <
class B> limitint<B>::limitint(user_interaction & dialog, S_I fd)
259 fichier f = fichier(dialog, dup(fd));
263 template <
class B> limitint<B>::limitint(generic_file & x)
268 template <
class B>
void limitint<B>::dump(user_interaction & dialog, S_I fd)
const
270 fichier f = fichier(dialog, dup(fd));
274 template <
class B>
void limitint<B>::build_from_file(generic_file & x)
279 limitint<B> skip = 0;
280 char *ptr = (
char *)&field;
282 int_tools_bitfield bf;
286 lu = x.read((
char *)&a, 1);
289 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Reached end of file before all data could be read"));
298 int_tools_expand_byte(a, bf);
299 for(S_I i = 0; i < 8; ++i)
302 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
313 if(skip.field > bytesize)
317 lu = x.read(ptr, skip.field);
319 if(used_endian == not_initialized)
321 if(used_endian == little_endian)
322 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
324 field >>= (bytesize - skip.field)*8;
328 E_END(
"limitint::read_from_file",
"generic_file");
332 template <
class B>
void limitint<B>::dump(generic_file & x)
const
337 unsigned char last_width;
340 unsigned char *ptr, *fin;
343 if(used_endian == not_initialized)
346 if(used_endian == little_endian)
349 ptr = (
unsigned char *)(&field) + (bytesize - 1);
350 fin = (
unsigned char *)(&field) - 1;
355 ptr = (
unsigned char *)(&field);
356 fin = (
unsigned char *)(&field) + bytesize;
359 while(ptr != fin && *ptr == 0)
370 euclide(width, (
const B)(TG), width, justification);
371 if(justification != 0)
375 euclide(width, (
const B)(8), width, pos);
379 last_width = 0x80 >> 7;
384 U_16 pos_s = (U_16)(0xFFFF & pos);
385 last_width = 0x80 >> (pos_s - 1);
391 if(width > ZEROED_SIZE)
393 x.write((
char *)zeroed_field, ZEROED_SIZE);
394 width -= ZEROED_SIZE;
398 x.write((
char *)zeroed_field, width);
404 x.write((
char *)&last_width, 1);
408 if(justification != 0)
410 justification = TG - justification;
411 if(justification > ZEROED_SIZE)
414 x.write((
char *)zeroed_field, justification);
419 x.write((
char *)zeroed_field, 1);
423 x.write((
char *)ptr, 1);
427 E_END(
"limitint::dump",
"generic_file");
433 B res = field + arg.field;
434 if(res < field || res < arg.field)
440 E_END(
"limitint::operator +=",
"");
443 template <
class B> limitint<B> & limitint<B>::operator -= (
const limitint & arg)
446 if(field < arg.field)
447 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
453 E_END(
"limitint::operator -=",
"");
457 template <
class B> limitint<B> & limitint<B>::operator *= (
const limitint & arg)
460 static const B max_power = bytesize*8 - 1;
462 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
463 if(total > max_power)
470 total = field*arg.field;
471 if(field != 0 && arg.field != 0)
472 if(total < field || total < arg.field)
476 E_END(
"limitint::operator *=",
"");
479 template <
class B>
template<
class T> limitint<B> limitint<B>::power(
const T & exponent)
const
482 for(T count = 0; count < exponent; ++count)
488 template <
class B> limitint<B> & limitint<B>::operator /= (
const limitint & arg)
492 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
496 E_END(
"limitint::operator /=",
"");
499 template <
class B> limitint<B> & limitint<B>::operator %= (
const limitint & arg)
503 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
507 E_END(
"limitint::operator /=",
"");
510 template <
class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
513 if(bit >= sizeof_field*8)
518 E_END(
"limitint::operator >>=",
"U_32");
521 template <
class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
526 E_END(
"limitint::operator >>=",
"limitint");
529 template <
class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
532 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
536 E_END(
"limitint::operator <<=",
"U_32");
539 template <
class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
542 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
546 E_END(
"limitint::operator <<=",
"limitint");
549 template <
class B> limitint<B> & limitint<B>::operator &= (
const limitint & arg)
554 E_END(
"limitint::operator &=",
"");
557 template <
class B> limitint<B> & limitint<B>::operator |= (
const limitint & arg)
562 E_END(
"limitint::operator |=",
"");
565 template <
class B> limitint<B> & limitint<B>::operator ^= (
const limitint & arg)
570 E_END(
"limitint::operator ^=",
"");
573 template <
class B> U_32 limitint<B>::operator % (U_32 arg)
const
576 return U_32(field % arg);
577 E_END(
"limitint::modulo",
"");
580 template <
class B>
template <
class T>
void limitint<B>::limitint_from(T a)
583 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
587 E_END(
"limitint::limitint_from",
"");
590 template <
class B>
template <
class T> T limitint<B>::max_val_of(T x)
598 x = int_tools_rotate_right_one_bit(x);
605 template <
class B>
template <
class T>
void limitint<B>::limitint_unstack_to(T &a)
611 static const T max_T = max_val_of(a);
614 if(field < (B)(step) && (T)(field) < step)
625 E_END(
"limitint::limitint_unstack_to",
"");
628 template <
class B> limitint<B> limitint<B>::get_storage_size()
const
639 return limitint<B>(ret);
642 template <
class B>
unsigned char limitint<B>::operator [] (
const limitint & position)
const
645 B index = position.field;
653 return (
unsigned char)(tmp & 0xFF);
656 template <
class B>
void limitint<B>::setup_endian()
660 used_endian = big_endian;
662 used_endian = little_endian;
664 bzero(zeroed_field, ZEROED_SIZE);
665 E_END(
"limitint::setup_endian",
"");
669 template <
class B>
bool limitint<B>::is_system_big_endian()
671 if(used_endian == not_initialized)
680 case not_initialized:
692 template <
class B> limitint<B> operator + (
const limitint<B> & a,
const limitint<B> & b)
699 E_END(
"operator +",
"limitint");
702 template <
class B> limitint<B> operator - (
const limitint<B> & a,
const limitint<B> & b)
709 E_END(
"operator -",
"limitint");
712 template <
class B> limitint<B> operator * (
const limitint<B> & a,
const limitint<B> & b)
719 E_END(
"operator *",
"limitint");
722 template <
class B> limitint<B> operator / (
const limitint<B> & a,
const limitint<B> & b)
729 E_END(
"operator / ",
"limitint");
732 template <
class B> limitint<B> operator % (
const limitint<B> & a,
const limitint<B> & b)
739 E_END(
"operator %",
"limitint");
742 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit)
748 E_END(
"operator >>",
"limitint, U_32");
751 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit)
757 E_END(
"operator >>",
"limitint");
760 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
766 E_END(
"operator <<",
"limitint, U_32");
769 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit)
775 E_END(
"operator <<",
"limitint");
778 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit)
784 E_END(
"operator &",
"limitint");
787 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit)
793 E_END(
"operator &",
"limitint");
796 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit)
802 E_END(
"operator |",
"U_32");
805 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit)
811 E_END(
"operator |",
"limitint");
814 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit)
820 E_END(
"operator ^",
"U_32");
823 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit)
829 E_END(
"operator ^",
"limitint");