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; };
168 static const int TG = 4;
169 static const U_32 sizeof_field =
sizeof(B);
171 enum endian { big_endian, little_endian, not_initialized };
172 typedef unsigned char group[TG];
177 template <
class T>
void limitint_from(T a);
178 template <
class T> T max_val_of(T x);
179 template <
class T>
void limitint_unstack_to(T &a);
184 static endian used_endian;
185 static const U_I bytesize =
sizeof(B);
186 static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
187 static U_8 zeroed_field[ZEROED_SIZE];
189 static void setup_endian();
197 template <
class B> limitint<B> operator - (
const limitint<B> &,
const limitint<B> &);
198 template <
class B>
inline limitint<B> operator - (
const limitint<B> & a, U_I b)
199 {
return a - limitint<B>(b); }
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> 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_32 bit);
208 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit);
209 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit);
210 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit);
211 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit);
212 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit);
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);
218 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
224 template <
class B>
inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
226 euclide(a, limitint<B>(b), q, r);
229 #ifndef INFININT_BASE_TYPE
230 #error INFININT_BASE_TYPE not defined cannot instantiate template
232 typedef limitint<INFININT_BASE_TYPE> infinint;
245 template <
class B>
typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
248 template <
class B> limitint<B>::limitint(generic_file & x)
254 template <
class B>
void limitint<B>::build_from_file(generic_file & x)
258 limitint<B> skip = 0;
259 char *ptr = (
char *)&field;
261 int_tools_bitfield bf;
265 lu = x.read((
char *)&a, 1);
268 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Reached end of file before all data could be read"));
277 int_tools_expand_byte(a, bf);
278 for(S_I i = 0; i < 8; ++i)
281 throw Erange(
"limitint::build_from_file(generic_file)", gettext(
"Badly formed \"infinint\" or not supported format"));
292 if(skip.field > bytesize)
296 lu = x.read(ptr, skip.field);
298 if(used_endian == not_initialized)
300 if(used_endian == little_endian)
301 int_tools_swap_bytes((
unsigned char *)ptr, skip.field);
303 field >>= (bytesize - skip.field)*8;
310 template <
class B>
void limitint<B>::dump(generic_file & x)
const
314 unsigned char last_width;
317 unsigned char *ptr, *fin;
320 if(used_endian == not_initialized)
323 if(used_endian == little_endian)
326 ptr = (
unsigned char *)(&field) + (bytesize - 1);
327 fin = (
unsigned char *)(&field) - 1;
332 ptr = (
unsigned char *)(&field);
333 fin = (
unsigned char *)(&field) + bytesize;
336 while(ptr != fin && *ptr == 0)
347 euclide(width, (
const B)(TG), width, justification);
348 if(justification != 0)
352 euclide(width, (
const B)(8), width, pos);
356 last_width = 0x80 >> 7;
361 U_16 pos_s = (U_16)(0xFFFF & pos);
362 last_width = 0x80 >> (pos_s - 1);
368 if(width > ZEROED_SIZE)
370 x.write((
char *)zeroed_field, ZEROED_SIZE);
371 width -= ZEROED_SIZE;
375 x.write((
char *)zeroed_field, width);
381 x.write((
char *)&last_width, 1);
385 if(justification != 0)
387 justification = TG - justification;
388 if(justification > ZEROED_SIZE)
391 x.write((
char *)zeroed_field, justification);
396 x.write((
char *)zeroed_field, 1);
400 x.write((
char *)ptr, 1);
407 B res = field + arg.field;
408 if(res < field || res < arg.field)
416 template <
class B> limitint<B> & limitint<B>::operator -= (
const limitint & arg)
418 if(field < arg.field)
419 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
428 template <
class B> limitint<B> & limitint<B>::operator *= (
const limitint & arg)
430 static const B max_power = bytesize*8 - 1;
432 B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1;
433 if(total > max_power)
440 total = field*arg.field;
441 if(field != 0 && arg.field != 0)
442 if(total < field || total < arg.field)
448 template <
class B>
template<
class T> limitint<B> limitint<B>::power(
const T & exponent)
const
451 for(T count = 0; count < exponent; ++count)
457 template <
class B> limitint<B> & limitint<B>::operator /= (
const limitint & arg)
460 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
466 template <
class B> limitint<B> & limitint<B>::operator %= (
const limitint & arg)
469 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
475 template <
class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
477 if(bit >= sizeof_field*8)
484 template <
class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
490 template <
class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
492 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
498 template <
class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
500 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
506 template <
class B> limitint<B> & limitint<B>::operator &= (
const limitint & arg)
512 template <
class B> limitint<B> & limitint<B>::operator |= (
const limitint & arg)
518 template <
class B> limitint<B> & limitint<B>::operator ^= (
const limitint & arg)
524 template <
class B> U_32 limitint<B>::operator % (U_32 arg)
const
526 return U_32(field % arg);
529 template <
class B>
template <
class T>
void limitint<B>::limitint_from(T a)
531 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
537 template <
class B>
template <
class T> T limitint<B>::max_val_of(T x)
545 x = int_tools_rotate_right_one_bit(x);
552 template <
class B>
template <
class T>
void limitint<B>::limitint_unstack_to(T &a)
558 static const T max_T = max_val_of(a);
561 if(field < (B)(step) && (T)(field) < step)
573 template <
class B> limitint<B> limitint<B>::get_storage_size()
const
584 return limitint<B>(ret);
587 template <
class B>
unsigned char limitint<B>::operator [] (
const limitint & position)
const
590 B index = position.field;
598 return (
unsigned char)(tmp & 0xFF);
601 template <
class B>
void limitint<B>::setup_endian()
604 used_endian = big_endian;
606 used_endian = little_endian;
608 (void)memset(zeroed_field, 0, ZEROED_SIZE);
612 template <
class B>
bool limitint<B>::is_system_big_endian()
614 if(used_endian == not_initialized)
623 case not_initialized:
635 template <
class B> limitint<B> operator + (
const limitint<B> & a,
const limitint<B> & b)
643 template <
class B> limitint<B> operator - (
const limitint<B> & a,
const limitint<B> & b)
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, U_32 bit)
682 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit)
689 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
696 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit)
703 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit)
710 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit)
717 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit)
724 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit)
731 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit)
738 template <
class B> limitint<B> operator ^ (
const limitint<B> & a,
const limitint<B> & 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
defines the interaction between libdar and the user.Three classes are defined
contains all the excetion class thrown by libdar
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
this is the base class of object that can be allocated on a memory pool
endian
type used to return the endian nature of the current system