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); };
121 template <
class T>
limitint power(
const T & exponent)
const;
132 {
limitint ret = *
this; ++(*this);
return ret; };
134 {
limitint ret = *
this; --(*this);
return ret; };
136 {
return *
this += 1; };
138 {
return *
this -= 1; };
140 U_32 operator % (U_32 arg)
const;
145 template <
class T>
void unstack(T &v)
146 { limitint_unstack_to(v); }
151 unsigned char operator [] (
const limitint & position)
const;
154 bool is_zero()
const {
return field == 0; };
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; };
160 bool operator != (
const limitint &x)
const {
return field != x.field; };
161 bool operator >= (
const limitint &x)
const {
return field >= x.field; };
162 static bool is_system_big_endian();
164 B debug_get_max()
const {
return max_value; };
165 B debug_get_bytesize()
const {
return bytesize; };
166 B debug_get_field()
const {
return field; };
169 static const int TG = 4;
170 static const U_32 sizeof_field =
sizeof(B);
172 enum endian { big_endian, little_endian, not_initialized };
173 typedef unsigned char group[TG];
178 template <
class T>
void limitint_from(T a);
179 template <
class T> T max_val_of(T x);
180 template <
class T>
void limitint_unstack_to(T &a);
185 static endian used_endian;
186 static const U_I bytesize =
sizeof(B);
187 static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
188 static U_8 zeroed_field[ZEROED_SIZE];
190 static void setup_endian();
210 template <
class B>
limitint<B> operator << (const limitint<B> & a, U_32 bit);
219 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
230 #ifndef INFININT_BASE_TYPE 231 #error INFININT_BASE_TYPE not defined cannot instantiate template 260 char *ptr = (
char *)&field;
262 int_tools_bitfield bf;
266 lu = x.
read((
char *)&a, 1);
269 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Reached end of file before all data could be read"));
278 int_tools_expand_byte(a, bf);
279 for(S_I i = 0; i < 8; ++i)
282 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
293 if(skip.field > bytesize)
297 lu = x.
read(ptr, skip.field);
299 if(used_endian == not_initialized)
301 if(used_endian == little_endian)
302 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
304 field >>= (bytesize - skip.field)*8;
315 unsigned char last_width;
318 unsigned char *ptr, *fin;
321 if(used_endian == not_initialized)
324 if(used_endian == little_endian)
327 ptr = (
unsigned char *)(&field) + (bytesize - 1);
328 fin = (
unsigned char *)(&field) - 1;
333 ptr = (
unsigned char *)(&field);
334 fin = (
unsigned char *)(&field) + bytesize;
337 while(ptr != fin && *ptr == 0)
348 euclide(width, (
const B)(TG), width, justification);
349 if(justification != 0)
353 euclide(width, (
const B)(8), width, pos);
357 last_width = 0x80 >> 7;
362 U_16 pos_s = (U_16)(0xFFFF & pos);
363 last_width = 0x80 >> (pos_s - 1);
369 if(width > ZEROED_SIZE)
371 x.
write((
char *)zeroed_field, ZEROED_SIZE);
372 width -= ZEROED_SIZE;
376 x.
write((
char *)zeroed_field, width);
382 x.
write((
char *)&last_width, 1);
386 if(justification != 0)
388 justification = TG - justification;
389 if(justification > ZEROED_SIZE)
392 x.
write((
char *)zeroed_field, justification);
397 x.
write((
char *)zeroed_field, 1);
401 x.
write((
char *)ptr, 1);
408 B res = field + arg.field;
409 if(res < field || res < arg.field)
419 if(field < arg.field)
420 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
431 static const B max_power = bytesize*8 - 1;
433 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
434 if(total > max_power)
441 total = field*arg.field;
442 if(field != 0 && arg.field != 0)
443 if(total < field || total < arg.field)
452 for(T count = 0; count < exponent; ++count)
461 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
470 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
478 if(bit >= sizeof_field*8)
493 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
501 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
527 return U_32(field % arg);
532 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
546 x = int_tools_rotate_right_one_bit(x);
559 static const T max_T = max_val_of(a);
562 if(field < (B)(step) && (T)(field) < step)
591 B index = position.field;
599 return (
unsigned char)(tmp & 0xFF);
605 used_endian = big_endian;
607 used_endian = little_endian;
609 (void)memset(zeroed_field, 0, ZEROED_SIZE);
615 if(used_endian == not_initialized)
624 case not_initialized:
690 template <
class B>
limitint<B> operator << (const limitint<B> & a, U_32 bit)
are defined here basic integer types that tend to be portable
class generic_file is defined here as well as class fichierthe generic_file interface is widely used ...
bool integers_system_is_big_endian()
returns true if the system is big endian, false else
exception used when a limitint overflow is detected, the maximum value of the limitint has been excee...
U_I read(char *a, U_I size)
read data from the generic_file
defines the interaction between libdar and the user.Three classes are defined
exception used when arithmetic error is detected when operating on infinint
contains all the excetion class thrown by libdar
exception used to signal range error
exception used to signal a bug. A bug is triggered when reaching some code that should never be reach...
this is the interface class from which all other data transfer classes inherit
void write(const char *a, U_I size)
write data to the generic_file
this is the base class of object that can be allocated on a memory pool
the arbitrary large positive integer class
libdar namespace encapsulate all libdar symbols