35 #include "../my_config.h" 40 #include <sys/types.h> 63 #define ZEROED_SIZE 50 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); };
126 template <
class T>
limitint power(
const T & exponent)
const;
137 {
limitint ret = *
this; ++(*this);
return ret; };
139 {
limitint ret = *
this; --(*this);
return ret; };
141 {
return *
this += 1; };
143 {
return *
this -= 1; };
145 U_32 operator % (U_32 arg)
const;
150 template <
class T>
void unstack(T &v)
151 { limitint_unstack_to(v); }
156 unsigned char operator [] (
const limitint & position)
const;
159 bool is_zero()
const {
return field == 0; };
161 bool operator < (
const limitint &x)
const {
return field < x.field; };
162 bool operator == (
const limitint &x)
const {
return field == x.field; };
163 bool operator > (
const limitint &x)
const {
return field > x.field; };
164 bool operator <= (
const limitint &x)
const {
return field <= x.field; };
165 bool operator != (
const limitint &x)
const {
return field != x.field; };
166 bool operator >= (
const limitint &x)
const {
return field >= x.field; };
167 static bool is_system_big_endian();
169 B debug_get_max()
const {
return max_value; };
170 B debug_get_bytesize()
const {
return bytesize; };
171 B debug_get_field()
const {
return field; };
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 const int TG = 4;
186 static const U_32 sizeof_field =
sizeof(B);
188 enum endian { big_endian, little_endian, not_initialized };
189 using group =
unsigned char[TG];
191 static endian used_endian;
192 static const U_I bytesize =
sizeof(B);
193 static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
194 static U_8 zeroed_field[ZEROED_SIZE];
196 static void setup_endian();
216 template <
class B>
limitint<B> operator << (const limitint<B> & a, U_32 bit);
225 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
236 #ifndef INFININT_BASE_TYPE 237 #error INFININT_BASE_TYPE not defined cannot instantiate template 263 char *ptr = (
char *)&field;
265 int_tools_bitfield bf;
269 lu = x.
read((
char *)&a, 1);
272 throw Erange(
"limitint::build_from_file(proto_generic_file)", gettext(
"Reached end of file before all data could be read"));
281 int_tools_expand_byte(a, bf);
282 for(S_I i = 0; i < 8; ++i)
285 throw Erange(
"limitint::build_from_file(proto_generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
296 if(skip.field > bytesize)
300 lu = x.
read(ptr, skip.field);
302 if(used_endian == not_initialized)
304 if(used_endian == little_endian)
305 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
307 field >>= (bytesize - skip.field)*8;
318 unsigned char last_width;
321 unsigned char *ptr, *fin;
324 if(used_endian == not_initialized)
327 if(used_endian == little_endian)
330 ptr = (
unsigned char *)(&field) + (bytesize - 1);
331 fin = (
unsigned char *)(&field) - 1;
336 ptr = (
unsigned char *)(&field);
337 fin = (
unsigned char *)(&field) + bytesize;
340 while(ptr != fin && *ptr == 0)
351 euclide(width, (
const B)(TG), width, justification);
352 if(justification != 0)
356 euclide(width, (
const B)(8), width, pos);
360 last_width = 0x80 >> 7;
365 U_16 pos_s = (U_16)(0xFFFF & pos);
366 last_width = 0x80 >> (pos_s - 1);
372 if(width > ZEROED_SIZE)
374 x.
write((
char *)zeroed_field, ZEROED_SIZE);
375 width -= ZEROED_SIZE;
379 x.
write((
char *)zeroed_field, width);
385 x.
write((
char *)&last_width, 1);
389 if(justification != 0)
391 justification = TG - justification;
392 if(justification > ZEROED_SIZE)
395 x.
write((
char *)zeroed_field, justification);
400 x.
write((
char *)zeroed_field, 1);
404 x.
write((
char *)ptr, 1);
411 B res = field + arg.field;
412 if(res < field || res < arg.field)
422 if(field < arg.field)
423 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
434 static const B max_power = bytesize*8 - 1;
436 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
437 if(total > max_power)
444 total = field*arg.field;
445 if(field != 0 && arg.field != 0)
446 if(total < field || total < arg.field)
455 for(T count = 0; count < exponent; ++count)
464 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
473 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
481 if(bit >= sizeof_field*8)
496 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
504 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
530 return U_32(field % arg);
535 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
549 x = int_tools_rotate_right_one_bit(x);
562 static const T max_T = max_val_of(a);
565 if(field < (B)(step) && (T)(field) < step)
594 B index = position.field;
602 return (
unsigned char)(tmp & 0xFF);
608 used_endian = big_endian;
610 used_endian = little_endian;
612 (void)memset(zeroed_field, 0, ZEROED_SIZE);
618 if(used_endian == not_initialized)
627 case not_initialized:
693 template <
class B>
limitint<B> operator << (const limitint<B> & a, U_32 bit)
are defined here basic integer types that tend to be portable
ancestor class of generic_file
bool integers_system_is_big_endian()
returns true if the system is big endian, false else
precursor class of generic_file used to avoid cyclic dependencies with storage and infinint ...
exception used when a limitint overflow is detected, the maximum value of the limitint has been excee...
exception used when arithmetic error is detected when operating on infinint
contains all the excetion class thrown by libdar
virtual U_I read(char *a, U_I size)=0
read data from the proto_generic_file
exception used to signal range error
virtual void write(const char *a, U_I size)=0
write data to the proto_generic_file
the arbitrary large positive integer class
libdar namespace encapsulate all libdar symbols