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)
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...
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
contains all the excetion class thrown by libdar
this is the interface class from which all other data transfer classes inherit
endian
type used to return the endian nature of the current system