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();
212 template <
class B>
limitint<B> operator << (const limitint<B> & a, U_32 bit);
221 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
232 #ifndef INFININT_BASE_TYPE 233 #error INFININT_BASE_TYPE not defined cannot instantiate template 255 fichier f = fichier(dialog, dup(fd));
266 fichier f = fichier(dialog, dup(fd));
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;
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)
434 if(field < arg.field)
435 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
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)
467 for(T count = 0; count < exponent; ++count)
476 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
485 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
493 if(bit >= sizeof_field*8)
508 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
516 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
542 return U_32(field % arg);
547 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
561 x = int_tools_rotate_right_one_bit(x);
574 static const T max_T = max_val_of(a);
577 if(field < (B)(step) && (T)(field) < step)
606 B index = position.field;
614 return (
unsigned char)(tmp & 0xFF);
620 used_endian = big_endian;
622 used_endian = little_endian;
624 (void)memset(zeroed_field, 0, ZEROED_SIZE);
630 if(used_endian == not_initialized)
639 case not_initialized:
705 template <
class B>
limitint<B> operator << (const limitint<B> & a, U_32 bit)
class fichier definition. This is a full implementation of a generic_file applied to a plain file ...
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
This is a pure virtual class that is used by libdar when interaction with the user is required...
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
re-definition of new and delete class operatorthis is a set of macro that makes the new and delete op...
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
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
the arbitrary large positive integer class
libdar namespace encapsulate all libdar symbols