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 { limitint_from(a); };
100 { limitint_from(a); };
103 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
105 { limitint_from(a); };
108 { limitint_from(a); };
123 template <
class T>
limitint power(
const T & exponent)
const;
134 {
limitint ret = *
this; ++(*this);
return ret; };
136 {
limitint ret = *
this; --(*this);
return ret; };
138 {
return *
this += 1; };
140 {
return *
this -= 1; };
142 U_32 operator % (U_32 arg)
const;
147 template <
class T>
void unstack(T &v)
148 { limitint_unstack_to(v); }
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)
230 template <
class B>
inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
232 euclide(a, limitint<B>(b), q, r);
235 #ifndef INFININT_BASE_TYPE
236 #error INFININT_BASE_TYPE not defined cannot instantiate template
238 typedef limitint<INFININT_BASE_TYPE> infinint;
252 template <
class B>
typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
256 template <
class B> limitint<B>::limitint(user_interaction & dialog, S_I fd)
258 fichier f = fichier(dialog, dup(fd));
262 template <
class B> limitint<B>::limitint(generic_file & x)
267 template <
class B>
void limitint<B>::dump(user_interaction & dialog, S_I fd)
const
269 fichier f = fichier(dialog, dup(fd));
273 template <
class B>
void limitint<B>::build_from_file(generic_file & x)
277 limitint<B> skip = 0;
278 char *ptr = (
char *)&field;
280 int_tools_bitfield bf;
284 lu = x.read((
char *)&a, 1);
287 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Reached end of file before all data could be read"));
296 int_tools_expand_byte(a, bf);
297 for(S_I i = 0; i < 8; ++i)
300 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
311 if(skip.field > bytesize)
315 lu = x.read(ptr, skip.field);
317 if(used_endian == not_initialized)
319 if(used_endian == little_endian)
320 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
322 field >>= (bytesize - skip.field)*8;
329 template <
class B>
void limitint<B>::dump(generic_file & x)
const
333 unsigned char last_width;
336 unsigned char *ptr, *fin;
339 if(used_endian == not_initialized)
342 if(used_endian == little_endian)
345 ptr = (
unsigned char *)(&field) + (bytesize - 1);
346 fin = (
unsigned char *)(&field) - 1;
351 ptr = (
unsigned char *)(&field);
352 fin = (
unsigned char *)(&field) + bytesize;
355 while(ptr != fin && *ptr == 0)
366 euclide(width, (
const B)(TG), width, justification);
367 if(justification != 0)
371 euclide(width, (
const B)(8), width, pos);
375 last_width = 0x80 >> 7;
380 U_16 pos_s = (U_16)(0xFFFF & pos);
381 last_width = 0x80 >> (pos_s - 1);
387 if(width > ZEROED_SIZE)
389 x.write((
char *)zeroed_field, ZEROED_SIZE);
390 width -= ZEROED_SIZE;
394 x.write((
char *)zeroed_field, width);
400 x.write((
char *)&last_width, 1);
404 if(justification != 0)
406 justification = TG - justification;
407 if(justification > ZEROED_SIZE)
410 x.write((
char *)zeroed_field, justification);
415 x.write((
char *)zeroed_field, 1);
419 x.write((
char *)ptr, 1);
426 B res = field + arg.field;
427 if(res < field || res < arg.field)
435 template <
class B> limitint<B> & limitint<B>::operator -= (
const limitint & arg)
437 if(field < arg.field)
438 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
447 template <
class B> limitint<B> & limitint<B>::operator *= (
const limitint & arg)
449 static const B max_power = bytesize*8 - 1;
451 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
452 if(total > max_power)
459 total = field*arg.field;
460 if(field != 0 && arg.field != 0)
461 if(total < field || total < arg.field)
467 template <
class B>
template<
class T> limitint<B> limitint<B>::power(
const T & exponent)
const
470 for(T count = 0; count < exponent; ++count)
476 template <
class B> limitint<B> & limitint<B>::operator /= (
const limitint & arg)
479 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
485 template <
class B> limitint<B> & limitint<B>::operator %= (
const limitint & arg)
488 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
494 template <
class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
496 if(bit >= sizeof_field*8)
503 template <
class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
509 template <
class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
511 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
517 template <
class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
519 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
525 template <
class B> limitint<B> & limitint<B>::operator &= (
const limitint & arg)
531 template <
class B> limitint<B> & limitint<B>::operator |= (
const limitint & arg)
537 template <
class B> limitint<B> & limitint<B>::operator ^= (
const limitint & arg)
543 template <
class B> U_32 limitint<B>::operator % (U_32 arg)
const
545 return U_32(field % arg);
548 template <
class B>
template <
class T>
void limitint<B>::limitint_from(T a)
550 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
556 template <
class B>
template <
class T> T limitint<B>::max_val_of(T x)
564 x = int_tools_rotate_right_one_bit(x);
571 template <
class B>
template <
class T>
void limitint<B>::limitint_unstack_to(T &a)
577 static const T max_T = max_val_of(a);
580 if(field < (B)(step) && (T)(field) < step)
592 template <
class B> limitint<B> limitint<B>::get_storage_size()
const
603 return limitint<B>(ret);
606 template <
class B>
unsigned char limitint<B>::operator [] (
const limitint & position)
const
609 B index = position.field;
617 return (
unsigned char)(tmp & 0xFF);
620 template <
class B>
void limitint<B>::setup_endian()
623 used_endian = big_endian;
625 used_endian = little_endian;
627 bzero(zeroed_field, ZEROED_SIZE);
631 template <
class B>
bool limitint<B>::is_system_big_endian()
633 if(used_endian == not_initialized)
642 case not_initialized:
654 template <
class B> limitint<B> operator + (
const limitint<B> & a,
const limitint<B> & b)
662 template <
class B> limitint<B> operator - (
const limitint<B> & a,
const limitint<B> & b)
670 template <
class B> limitint<B> operator * (
const limitint<B> & a,
const limitint<B> & b)
678 template <
class B> limitint<B> operator / (
const limitint<B> & a,
const limitint<B> & b)
686 template <
class B> limitint<B> operator % (
const limitint<B> & a,
const limitint<B> & b)
694 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit)
701 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit)
708 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
715 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit)
722 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit)
729 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit)
736 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit)
743 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit)
750 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit)
757 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & bit)