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();
198 template <
class B> limitint<B> operator - (
const limitint<B> &,
const limitint<B> &);
199 template <
class B>
inline limitint<B> operator - (
const limitint<B> & a, U_I b)
200 {
return a - limitint<B>(b); }
201 template <
class B> limitint<B> operator * (
const limitint<B> &,
const limitint<B> &);
202 template <
class B>
inline limitint<B> operator * (
const limitint<B> & a, U_I b)
203 {
return a * limitint<B>(b); }
204 template <
class B> limitint<B> operator / (
const limitint<B> &,
const limitint<B> &);
205 template <
class B> limitint<B> operator / (
const limitint<B> & a, U_I b)
206 {
return a / limitint<B>(b); }
207 template <
class B> limitint<B> operator % (
const limitint<B> &,
const limitint<B> &);
208 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit);
209 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit);
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);
219 template <
class T>
inline void euclide(T a, T b, T & q, T &r)
225 template <
class B>
inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
227 euclide(a, limitint<B>(b), q, r);
230 #ifndef INFININT_BASE_TYPE
231 #error INFININT_BASE_TYPE not defined cannot instantiate template
233 typedef limitint<INFININT_BASE_TYPE> infinint;
246 template <
class B>
typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
249 template <
class B> limitint<B>::limitint(generic_file & x)
255 template <
class B>
void limitint<B>::build_from_file(generic_file & x)
259 limitint<B> skip = 0;
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;
311 template <
class B>
void limitint<B>::dump(generic_file & x)
const
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)
417 template <
class B> limitint<B> & limitint<B>::operator -= (
const limitint & arg)
419 if(field < arg.field)
420 throw Erange(
"limitint::operator", gettext(
"Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
429 template <
class B> limitint<B> & limitint<B>::operator *= (
const limitint & arg)
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)
449 template <
class B>
template<
class T> limitint<B> limitint<B>::power(
const T & exponent)
const
452 for(T count = 0; count < exponent; ++count)
458 template <
class B> limitint<B> & limitint<B>::operator /= (
const limitint & arg)
461 throw Einfinint(
"limitint.cpp : operator /=", gettext(
"Division by zero"));
467 template <
class B> limitint<B> & limitint<B>::operator %= (
const limitint & arg)
470 throw Einfinint(
"limitint.cpp : operator %=", gettext(
"Division by zero"));
476 template <
class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
478 if(bit >= sizeof_field*8)
485 template <
class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
491 template <
class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
493 if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
499 template <
class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
501 if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
507 template <
class B> limitint<B> & limitint<B>::operator &= (
const limitint & arg)
513 template <
class B> limitint<B> & limitint<B>::operator |= (
const limitint & arg)
519 template <
class B> limitint<B> & limitint<B>::operator ^= (
const limitint & arg)
525 template <
class B> U_32 limitint<B>::operator % (U_32 arg)
const
527 return U_32(field % arg);
530 template <
class B>
template <
class T>
void limitint<B>::limitint_from(T a)
532 if(
sizeof(a) <= bytesize || a <= (T)(max_value))
538 template <
class B>
template <
class T> T limitint<B>::max_val_of(T x)
546 x = int_tools_rotate_right_one_bit(x);
553 template <
class B>
template <
class T>
void limitint<B>::limitint_unstack_to(T &a)
559 static const T max_T = max_val_of(a);
562 if(field < (B)(step) && (T)(field) < step)
574 template <
class B> limitint<B> limitint<B>::get_storage_size()
const
585 return limitint<B>(ret);
588 template <
class B>
unsigned char limitint<B>::operator [] (
const limitint & position)
const
591 B index = position.field;
599 return (
unsigned char)(tmp & 0xFF);
602 template <
class B>
void limitint<B>::setup_endian()
605 used_endian = big_endian;
607 used_endian = little_endian;
609 (void)memset(zeroed_field, 0, ZEROED_SIZE);
613 template <
class B>
bool limitint<B>::is_system_big_endian()
615 if(used_endian == not_initialized)
624 case not_initialized:
636 template <
class B> limitint<B> operator + (
const limitint<B> & a,
const limitint<B> & b)
644 template <
class B> limitint<B> operator - (
const limitint<B> & a,
const limitint<B> & b)
652 template <
class B> limitint<B> operator * (
const limitint<B> & a,
const limitint<B> & b)
660 template <
class B> limitint<B> operator / (
const limitint<B> & a,
const limitint<B> & b)
668 template <
class B> limitint<B> operator % (
const limitint<B> & a,
const limitint<B> & b)
676 template <
class B> limitint<B> operator >> (
const limitint<B> & a, U_32 bit)
683 template <
class B> limitint<B> operator >> (
const limitint<B> & a,
const limitint<B> & bit)
690 template <
class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
697 template <
class B> limitint<B> operator << (const limitint<B> & a,
const limitint<B> & bit)
704 template <
class B> limitint<B> operator & (
const limitint<B> & a, U_32 bit)
711 template <
class B> limitint<B> operator & (
const limitint<B> & a,
const limitint<B> & bit)
718 template <
class B> limitint<B> operator | (
const limitint<B> & a, U_32 bit)
725 template <
class B> limitint<B> operator | (
const limitint<B> & a,
const limitint<B> & bit)
732 template <
class B> limitint<B> operator ^ (
const limitint<B> & a, U_32 bit)
739 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
endian
type used to return the endian nature of the current system
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
libdar namespace encapsulate all libdar symbols