35 #include "../my_config.h"
40 #include <sys/types.h>
63 #define ZEROED_SIZE 50
73 class user_interaction;
91 #if SIZEOF_OFF_T > SIZEOF_TIME_T
92 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
94 { limitint_from(a); };
97 { limitint_from(a); };
100 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
102 { limitint_from(a); };
105 { limitint_from(a); };
120 template <
class T>
limitint power(
const T & exponent)
const;
131 {
limitint ret = *
this; ++(*this);
return ret; };
133 {
limitint ret = *
this; --(*this);
return ret; };
135 {
return *
this += 1; };
137 {
return *
this -= 1; };
139 U_32 operator % (U_32 arg)
const;
144 template <
class T>
void unstack(T &v)
145 { limitint_unstack_to(v); }
150 unsigned char operator [] (
const limitint & position)
const;
154 bool operator < (
const limitint &x)
const {
return field < x.field; };
155 bool operator == (
const limitint &x)
const {
return field == x.field; };
156 bool operator > (
const limitint &x)
const {
return field > x.field; };
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; };
161 static bool is_system_big_endian();
163 #ifdef LIBDAR_SPECIAL_ALLOC
167 B debug_get_max()
const {
return max_value; };
168 B debug_get_bytesize()
const {
return bytesize; };
171 static const int TG = 4;
172 static const U_32 sizeof_field =
sizeof(B);
174 enum endian { big_endian, little_endian, not_initialized };
175 typedef unsigned char group[TG];
180 template <
class T>
void limitint_from(T a);
181 template <
class T> T max_val_of(T x);
182 template <
class T>
void limitint_unstack_to(T &a);
187 static endian used_endian;
188 static const U_I bytesize =
sizeof(B);
189 static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
190 static U_8 zeroed_field[ZEROED_SIZE];
192 static void setup_endian();
200 template <
class B> limitint<B> operator - (
const limitint<B> &,
const limitint<B> &);
201 template <
class B>
inline limitint<B> operator - (
const limitint<B> & a, U_I b)
202 {
return a - limitint<B>(b); }
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> 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_32 bit);
211 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit);
212 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit);
213 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit);
214 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit);
215 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit);
216 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit);
217 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit);
218 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit);
219 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit);
221 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
227 template <
class B>
inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
229 euclide(a, limitint<B>(b), q, r);
232 #ifndef INFININT_BASE_TYPE
233 #error INFININT_BASE_TYPE not defined cannot instantiate template
235 typedef limitint<INFININT_BASE_TYPE> infinint;
249 template <
class B>
typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
253 template <
class B> limitint<B>::limitint(user_interaction & dialog, S_I fd)
255 fichier f = fichier(dialog, dup(fd));
259 template <
class B> limitint<B>::limitint(generic_file & x)
264 template <
class B>
void limitint<B>::dump(user_interaction & dialog, S_I fd)
const
266 fichier f = fichier(dialog, dup(fd));
270 template <
class B>
void limitint<B>::build_from_file(generic_file & x)
274 limitint<B> skip = 0;
275 char *ptr = (
char *)&field;
277 int_tools_bitfield bf;
281 lu = x.read((
char *)&a, 1);
284 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Reached end of file before all data could be read"));
293 int_tools_expand_byte(a, bf);
294 for(S_I i = 0; i < 8; ++i)
297 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
308 if(skip.field > bytesize)
312 lu = x.read(ptr, skip.field);
314 if(used_endian == not_initialized)
316 if(used_endian == little_endian)
317 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
319 field >>= (bytesize - skip.field)*8;
326 template <
class B>
void limitint<B>::dump(generic_file & x)
const
330 unsigned char last_width;
333 unsigned char *ptr, *fin;
336 if(used_endian == not_initialized)
339 if(used_endian == little_endian)
342 ptr = (
unsigned char *)(&field) + (bytesize - 1);
343 fin = (
unsigned char *)(&field) - 1;
348 ptr = (
unsigned char *)(&field);
349 fin = (
unsigned char *)(&field) + bytesize;
352 while(ptr != fin && *ptr == 0)
363 euclide(width, (
const B)(TG), width, justification);
364 if(justification != 0)
368 euclide(width, (
const B)(8), width, pos);
372 last_width = 0x80 >> 7;
377 U_16 pos_s = (U_16)(0xFFFF & pos);
378 last_width = 0x80 >> (pos_s - 1);
384 if(width > ZEROED_SIZE)
386 x.write((
char *)zeroed_field, ZEROED_SIZE);
387 width -= ZEROED_SIZE;
391 x.write((
char *)zeroed_field, width);
397 x.write((
char *)&last_width, 1);
401 if(justification != 0)
403 justification = TG - justification;
404 if(justification > ZEROED_SIZE)
407 x.write((
char *)zeroed_field, justification);
412 x.write((
char *)zeroed_field, 1);
416 x.write((
char *)ptr, 1);
423 B res = field + arg.field;
424 if(res < field || res < arg.field)
432 template <
class B> limitint<B> & limitint<B>::operator -= (
const limitint & arg)
434 if(field < arg.field)
435 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
444 template <
class B> limitint<B> & limitint<B>::operator *= (
const limitint & arg)
446 static const B max_power = bytesize*8 - 1;
448 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
449 if(total > max_power)
456 total = field*arg.field;
457 if(field != 0 && arg.field != 0)
458 if(total < field || total < arg.field)
464 template <
class B>
template<
class T> limitint<B> limitint<B>::power(
const T & exponent)
const
467 for(T count = 0; count < exponent; ++count)
473 template <
class B> limitint<B> & limitint<B>::operator /= (
const limitint & arg)
476 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
482 template <
class B> limitint<B> & limitint<B>::operator %= (
const limitint & arg)
485 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
491 template <
class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
493 if(bit >= sizeof_field*8)
500 template <
class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
506 template <
class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
508 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
514 template <
class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
516 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
522 template <
class B> limitint<B> & limitint<B>::operator &= (
const limitint & arg)
528 template <
class B> limitint<B> & limitint<B>::operator |= (
const limitint & arg)
534 template <
class B> limitint<B> & limitint<B>::operator ^= (
const limitint & arg)
540 template <
class B> U_32 limitint<B>::operator % (U_32 arg)
const
542 return U_32(field % arg);
545 template <
class B>
template <
class T>
void limitint<B>::limitint_from(T a)
547 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
553 template <
class B>
template <
class T> T limitint<B>::max_val_of(T x)
561 x = int_tools_rotate_right_one_bit(x);
568 template <
class B>
template <
class T>
void limitint<B>::limitint_unstack_to(T &a)
574 static const T max_T = max_val_of(a);
577 if(field < (B)(step) && (T)(field) < step)
589 template <
class B> limitint<B> limitint<B>::get_storage_size()
const
600 return limitint<B>(ret);
603 template <
class B>
unsigned char limitint<B>::operator [] (
const limitint & position)
const
606 B index = position.field;
614 return (
unsigned char)(tmp & 0xFF);
617 template <
class B>
void limitint<B>::setup_endian()
620 used_endian = big_endian;
622 used_endian = little_endian;
624 (void)memset(zeroed_field, 0, ZEROED_SIZE);
628 template <
class B>
bool limitint<B>::is_system_big_endian()
630 if(used_endian == not_initialized)
639 case not_initialized:
651 template <
class B> limitint<B> operator + (
const limitint<B> & a,
const limitint<B> & b)
659 template <
class B> limitint<B> operator - (
const limitint<B> & a,
const limitint<B> & b)
667 template <
class B> limitint<B> operator * (
const limitint<B> & a,
const limitint<B> & b)
675 template <
class B> limitint<B> operator / (
const limitint<B> & a,
const limitint<B> & b)
683 template <
class B> limitint<B> operator % (
const limitint<B> & a,
const limitint<B> & b)
691 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit)
698 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit)
705 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
712 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit)
719 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit)
726 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit)
733 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit)
740 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit)
747 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit)
754 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit)