Disk ARchive  2.4.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
limitint.hpp
Go to the documentation of this file.
00001 /*********************************************************************/
00002 // dar - disk archive - a backup/restoration program
00003 // Copyright (C) 2002-2052 Denis Corbin
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 // to contact the author : http://dar.linux.free.fr/email.html
00020 /*********************************************************************/
00021 
00030 
00031 
00032 #ifndef LIMITINT_HPP
00033 #define LIMITINT_HPP
00034 
00035 #include "../my_config.h"
00036 
00037 extern "C"
00038 {
00039 #if HAVE_SYS_TYPES_H
00040 #include <sys/types.h>
00041 #endif
00042 
00043 #if HAVE_UNISTD_H
00044 #include <unistd.h>
00045 #endif
00046 
00047 #if HAVE_STRING_H
00048 #include <string.h>
00049 #endif
00050 
00051 #if HAVE_STRINGS_H
00052 #include <strings.h>
00053 #endif
00054 } // end extern "C"
00055 
00056 #include <typeinfo>
00057 #include "integers.hpp"
00058 #include "erreurs.hpp"
00059 #include "special_alloc.hpp"
00060 #include "int_tools.hpp"
00061 
00062 
00063 #define ZEROED_SIZE 50
00064 
00065 namespace libdar
00066 {
00067 
00070 
00071 
00072     class generic_file;
00073     class user_interaction;
00074 
00086 
00087     template<class B> class limitint
00088     {
00089     public :
00090 
00091 #if SIZEOF_OFF_T > SIZEOF_TIME_T
00092 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
00093         limitint(off_t a = 0)
00094             { limitint_from(a); };
00095 #else
00096         limitint(size_t a = 0)
00097             { limitint_from(a); };
00098 #endif
00099 #else
00100 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
00101         limitint(time_t a = 0)
00102             { limitint_from(a); };
00103 #else
00104         limitint(size_t a = 0)
00105             { limitint_from(a); };
00106 #endif
00107 #endif
00108 
00109             // read an limitint from a file
00110         limitint(user_interaction & dialog, S_I fd);
00111         limitint(generic_file & x);
00112 
00113         void dump(user_interaction & dialog, S_I fd) const; // write byte sequence to file
00114         void dump(generic_file &x) const; // write byte sequence to file
00115         void read(generic_file &f) { build_from_file(f); };
00116 
00117         limitint & operator += (const limitint & ref);
00118         limitint & operator -= (const limitint & ref);
00119         limitint & operator *= (const limitint & ref);
00120         template <class T> limitint power(const T & exponent) const;
00121         limitint & operator /= (const limitint & ref);
00122         limitint & operator %= (const limitint & ref);
00123         limitint & operator &= (const limitint & ref);
00124         limitint & operator |= (const limitint & ref);
00125         limitint & operator ^= (const limitint & ref);
00126         limitint & operator >>= (U_32 bit);
00127         limitint & operator >>= (limitint bit);
00128         limitint & operator <<= (U_32 bit);
00129         limitint & operator <<= (limitint bit);
00130         limitint operator ++(int a)
00131             { limitint ret = *this; ++(*this); return ret; };
00132         limitint operator --(int a)
00133             { limitint ret = *this; --(*this); return ret; };
00134         limitint & operator ++()
00135             { return *this += 1; };
00136         limitint & operator --()
00137             { return *this -= 1; };
00138 
00139         U_32 operator % (U_32 arg) const;
00140 
00141             // increment the argument up to a legal value for its storage type and decrement the object in consequence
00142             // note that the initial value of the argument is not ignored !
00143             // when the object is null the value of the argument stays the same as before
00144         template <class T>void unstack(T &v)
00145         { limitint_unstack_to(v); }
00146 
00147         limitint get_storage_size() const;
00148             // it returns number of byte of information necessary to store the integer
00149 
00150         unsigned char operator [] (const limitint & position) const;
00151             // return in big endian order the information bytes storing the integer
00152 
00153 
00154         bool operator < (const limitint &x) const { return field < x.field; };
00155         bool operator == (const limitint &x) const { return field == x.field; };
00156         bool operator > (const limitint &x) const { return field > x.field; };
00157         bool operator <= (const limitint &x) const { return field <= x.field; };
00158         bool operator != (const limitint &x) const { return field != x.field; };
00159         bool operator >= (const limitint &x) const { return field >= x.field; };
00160 
00161         static bool is_system_big_endian();
00162 
00163 #ifdef LIBDAR_SPECIAL_ALLOC
00164         USE_SPECIAL_ALLOC(limitint);
00165 #endif
00166 
00167         B debug_get_max() const { return max_value; };
00168         B debug_get_bytesize() const { return bytesize; };
00169 
00170     private :
00171         static const int TG = 4;
00172         static const U_32 sizeof_field = sizeof(B); // number of bytes
00173 
00174         enum endian { big_endian, little_endian, not_initialized };
00175         typedef unsigned char group[TG];
00176 
00177         B field;
00178 
00179         void build_from_file(generic_file & x);
00180         template <class T> void limitint_from(T a);
00181         template <class T> T max_val_of(T x);
00182         template <class T> void limitint_unstack_to(T &a);
00183 
00185             // static statments
00186             //
00187         static endian used_endian;
00188         static const U_I bytesize = sizeof(B);
00189         static const B max_value = ~B(0) > 0 ? ~B(0) : ~(B(1) << (bytesize*8 - 1));
00190         static U_8 zeroed_field[ZEROED_SIZE];
00191 
00192         static void setup_endian();
00193     };
00194 
00195     template <class B> U_8 limitint<B>::zeroed_field[ZEROED_SIZE];
00196 
00197     template <class B> limitint<B> operator + (const limitint<B> &, const limitint<B> &);
00198     template <class B> inline limitint<B> operator + (const limitint<B> & a, U_I b)
00199     { return a + limitint<B>(b); }
00200     template <class B> limitint<B> operator - (const limitint<B> &, const limitint<B> &);
00201     template <class B> inline limitint<B> operator - (const limitint<B> & a, U_I b)
00202     { return a - limitint<B>(b); }
00203     template <class B> limitint<B> operator * (const limitint<B> &, const limitint<B> &);
00204     template <class B> inline limitint<B> operator * (const limitint<B> & a, U_I b)
00205     { return a * limitint<B>(b); }
00206     template <class B> limitint<B> operator / (const limitint<B> &, const limitint<B> &);
00207     template <class B> limitint<B> operator / (const limitint<B> & a, U_I b)
00208     { return a / limitint<B>(b); }
00209     template <class B> limitint<B> operator % (const limitint<B> &, const limitint<B> &);
00210     template <class B> limitint<B> operator >> (const limitint<B> & a, U_32 bit);
00211     template <class B> limitint<B> operator >> (const limitint<B> & a, const limitint<B> & bit);
00212     template <class B> limitint<B> operator << (const limitint<B> & a, U_32 bit);
00213     template <class B> limitint<B> operator << (const limitint<B> & a, const limitint<B> & bit);
00214     template <class B> limitint<B> operator & (const limitint<B> & a, U_32  bit);
00215     template <class B> limitint<B> operator & (const limitint<B> & a, const limitint<B> & bit);
00216     template <class B> limitint<B> operator | (const limitint<B> & a, U_32  bit);
00217     template <class B> limitint<B> operator | (const limitint<B> & a, const limitint<B> & bit);
00218     template <class B> limitint<B> operator ^ (const limitint<B> & a, U_32  bit);
00219     template <class B> limitint<B> operator ^ (const limitint<B> & a, const limitint<B> & bit);
00220 
00221     template <class T> inline void euclide(T a, T b, T & q, T &r)
00222     {
00223 
00224         q = a/b; r = a%b;
00225     }
00226 
00227     template <class B> inline void euclide(limitint<B> a, U_I b, limitint<B> & q, limitint<B> &r)
00228     {
00229         euclide(a, limitint<B>(b), q, r);
00230     }
00231 
00232 #ifndef INFININT_BASE_TYPE
00233 #error INFININT_BASE_TYPE not defined cannot instantiate template
00234 #else
00235     typedef limitint<INFININT_BASE_TYPE> infinint;
00236 #endif
00237 } // end of namespace
00241 
00242 #include "generic_file.hpp"
00243 #include "fichier.hpp"
00244 #include "user_interaction.hpp"
00245 
00246 namespace libdar
00247 {
00248 
00249     template <class B> typename limitint<B>::endian limitint<B>::used_endian = not_initialized;
00250 
00251 
00252 
00253     template <class B> limitint<B>::limitint(user_interaction & dialog, S_I fd)
00254     {
00255         fichier f = fichier(dialog, dup(fd));
00256         build_from_file(f);
00257     }
00258 
00259     template <class B> limitint<B>::limitint(generic_file & x)
00260     {
00261         build_from_file(x);
00262     }
00263 
00264     template <class B> void limitint<B>::dump(user_interaction & dialog, S_I fd) const
00265     {
00266         fichier f = fichier(dialog, dup(fd));
00267         dump(f);
00268     }
00269 
00270     template <class B> void limitint<B>::build_from_file(generic_file & x)
00271     {
00272         unsigned char a;
00273         bool fin = false;
00274         limitint<B> skip = 0;
00275         char *ptr = (char *)&field;
00276         S_I lu;
00277         int_tools_bitfield bf;
00278 
00279         while(!fin)
00280         {
00281             lu = x.read((char *)&a, 1);
00282 
00283             if(lu <= 0)
00284                 throw Erange("limitint::build_from_file(generic_file)", gettext("Reached end of file before all data could be read"));
00285 
00286             if(a == 0)
00287                 ++skip;
00288             else // end of size field
00289             {
00290                     // computing the size to read
00291                 U_I pos = 0;
00292 
00293                 int_tools_expand_byte(a, bf);
00294                 for(S_I i = 0; i < 8; ++i)
00295                     pos += bf[i];
00296                 if(pos != 1)
00297                     throw Erange("limitint::build_from_file(generic_file)", gettext("Badly formed \"infinint\" or not supported format")); // more than 1 bit is set to 1
00298 
00299                 pos = 0;
00300                 while(bf[pos] == 0)
00301                     ++pos;
00302                 pos += 1; // bf starts at zero, but bit zero means 1 TG of length
00303 
00304                 skip *= 8;
00305                 skip += pos;
00306                 skip *= TG;
00307 
00308                 if(skip.field > bytesize)
00309                     throw Elimitint();
00310 
00311                 field = 0; // important to also clear "unread" bytes by this call
00312                 lu = x.read(ptr, skip.field);
00313 
00314                 if(used_endian == not_initialized)
00315                     setup_endian();
00316                 if(used_endian == little_endian)
00317                     int_tools_swap_bytes((unsigned char *)ptr, skip.field);
00318                 else
00319                     field >>= (bytesize - skip.field)*8;
00320                 fin = true;
00321             }
00322         }
00323     }
00324 
00325 
00326     template <class B> void limitint<B>::dump(generic_file & x) const
00327     {
00328         B width = bytesize;
00329         B pos;
00330         unsigned char last_width;
00331         B justification;
00332         S_I direction = +1;
00333         unsigned char *ptr, *fin;
00334 
00335 
00336         if(used_endian == not_initialized)
00337             setup_endian();
00338 
00339         if(used_endian == little_endian)
00340         {
00341             direction = -1;
00342             ptr = (unsigned char *)(&field) + (bytesize - 1);
00343             fin = (unsigned char *)(&field) - 1;
00344         }
00345         else
00346         {
00347             direction = +1;
00348             ptr = (unsigned char *)(&field);
00349             fin = (unsigned char *)(&field) + bytesize;
00350         }
00351 
00352         while(ptr != fin && *ptr == 0)
00353         {
00354             ptr += direction;
00355             --width;
00356         }
00357         if(width == 0)
00358             width = 1; // minimum size of information is 1 byte
00359 
00360             // "width" is the informational field size in byte
00361             // TG is the width in TG, thus the number of bit that must have
00362             // the preamble
00363         euclide(width, (const B)(TG), width, justification);
00364         if(justification != 0)
00365                 // in case we need to add some bytes to have a width multiple of TG
00366             ++width;  // we need then one more group to have a width multiple of TG
00367 
00368         euclide(width, (const B)(8), width, pos);
00369         if(pos == 0)
00370         {
00371             width--; // division is exact, only last bit of the preambule is set
00372             last_width = 0x80 >> 7;
00373                 // as we add the last byte separately width gets shorter by 1 byte
00374         }
00375         else // division non exact, the last_width (last byte), make the rounding
00376         {
00377             U_16 pos_s = (U_16)(0xFFFF & pos);
00378             last_width = 0x80 >> (pos_s - 1);
00379         }
00380 
00381             // now we write the preamble except the last byte. All these are zeros.
00382 
00383         while(width != 0)
00384             if(width > ZEROED_SIZE)
00385             {
00386                 x.write((char *)zeroed_field, ZEROED_SIZE);
00387                 width -= ZEROED_SIZE;
00388             }
00389             else
00390             {
00391                 x.write((char *)zeroed_field, width);
00392                 width = 0;
00393             }
00394 
00395             // now we write the last byte of the preambule, which as only one bit set
00396 
00397         x.write((char *)&last_width, 1);
00398 
00399             // we need now to write some justification byte to have an informational field multiple of TG
00400 
00401         if(justification != 0)
00402         {
00403             justification = TG - justification;
00404             if(justification > ZEROED_SIZE)
00405                 throw SRC_BUG;
00406             else
00407                 x.write((char *)zeroed_field, justification);
00408         }
00409 
00410             // now we continue dumping the informational bytes:
00411         if(ptr == fin) // field is equal to zero
00412             x.write((char *)zeroed_field, 1);
00413         else // we have some bytes to write down
00414             while(ptr != fin)
00415             {
00416                 x.write((char *)ptr, 1);
00417                 ptr += direction;
00418             }
00419     }
00420 
00421     template<class B> limitint<B> & limitint<B>::operator += (const limitint & arg)
00422     {
00423         B res = field + arg.field;
00424         if(res < field || res < arg.field)
00425             throw Elimitint();
00426         else
00427             field = res;
00428 
00429         return *this;
00430     }
00431 
00432     template <class B> limitint<B> & limitint<B>::operator -= (const limitint & arg)
00433     {
00434         if(field < arg.field)
00435             throw Erange("limitint::operator", gettext("Subtracting an \"infinint\" greater than the first, \"infinint\" cannot be negative"));
00436 
00437             // now processing the operation
00438 
00439         field -= arg.field;
00440         return *this;
00441     }
00442 
00443 
00444     template <class B> limitint<B> & limitint<B>::operator *= (const limitint & arg)
00445     {
00446         static const B max_power = bytesize*8 - 1;
00447 
00448         B total = int_tools_higher_power_of_2(field) + int_tools_higher_power_of_2(arg.field) + 1; // for an explaination about "+2" see NOTES
00449         if(total > max_power) // this is a bit too much restrictive, but unless remaking bit by bit, the operation,
00450                 // I don't see how to simply (and fast) know the result has not overflowed.
00451                 // of course, it would be fast and easy to access the CPU flag register to check for overflow,
00452                 // but that would not be portable, and unfortunately I haven't found any standart C++ expression that
00453                 // could transparently access to it.
00454             throw Elimitint();
00455 
00456         total = field*arg.field;
00457         if(field != 0 && arg.field != 0)
00458             if(total < field || total < arg.field)
00459                 throw Elimitint();
00460         field = total;
00461         return *this;
00462     }
00463 
00464     template <class B> template<class T> limitint<B> limitint<B>::power(const T & exponent) const
00465     {
00466         limitint ret = 1;
00467         for(T count = 0; count < exponent; ++count)
00468             ret *= *this;
00469 
00470         return ret;
00471     }
00472 
00473     template <class B> limitint<B> & limitint<B>::operator /= (const limitint & arg)
00474     {
00475         if(arg == 0)
00476             throw Einfinint("limitint.cpp : operator /=", gettext("Division by zero"));
00477 
00478         field /= arg.field;
00479         return *this;
00480     }
00481 
00482     template <class B> limitint<B> & limitint<B>::operator %= (const limitint & arg)
00483     {
00484         if(arg == 0)
00485             throw Einfinint("limitint.cpp : operator %=", gettext("Division by zero"));
00486 
00487         field %= arg.field;
00488         return *this;
00489     }
00490 
00491     template <class B> limitint<B> & limitint<B>::operator >>= (U_32 bit)
00492     {
00493         if(bit >= sizeof_field*8)
00494             field = 0;
00495         else
00496             field >>= bit;
00497         return *this;
00498     }
00499 
00500     template <class B> limitint<B> & limitint<B>::operator >>= (limitint bit)
00501     {
00502         field >>= bit.field;
00503         return *this;
00504     }
00505 
00506     template <class B> limitint<B> & limitint<B>::operator <<= (U_32 bit)
00507     {
00508         if(bit + int_tools_higher_power_of_2(field) >= bytesize*8)
00509             throw Elimitint();
00510         field <<= bit;
00511         return *this;
00512     }
00513 
00514     template <class B> limitint<B> & limitint<B>::operator <<= (limitint bit)
00515     {
00516         if(bit.field + int_tools_higher_power_of_2(field) >= bytesize*8)
00517             throw Elimitint();
00518         field <<= bit.field;
00519         return *this;
00520     }
00521 
00522     template <class B> limitint<B> & limitint<B>::operator &= (const limitint & arg)
00523     {
00524         field &= arg.field;
00525         return *this;
00526     }
00527 
00528     template <class B> limitint<B> & limitint<B>::operator |= (const limitint & arg)
00529     {
00530         field |= arg.field;
00531         return *this;
00532     }
00533 
00534     template <class B> limitint<B> & limitint<B>::operator ^= (const limitint & arg)
00535     {
00536         field ^= arg.field;
00537         return *this;
00538     }
00539 
00540     template <class B> U_32 limitint<B>::operator % (U_32 arg) const
00541     {
00542         return U_32(field % arg);
00543     }
00544 
00545     template <class B> template <class T> void limitint<B>::limitint_from(T a)
00546     {
00547         if(sizeof(a) <= bytesize || a <= (T)(max_value))
00548             field = B(a);
00549         else
00550             throw Elimitint();
00551     }
00552 
00553     template <class B> template <class T> T limitint<B>::max_val_of(T x)
00554     {
00555         x = 0;
00556         x = ~x;
00557 
00558         if(x < 1) // T is a signed integer type, we are not comparing to zero to avoid compiler warning when the template is used against unsigned integers
00559         {
00560             x = 1;
00561             x = int_tools_rotate_right_one_bit(x);
00562             x = ~x;
00563         }
00564 
00565         return x;
00566     }
00567 
00568     template <class B> template <class T> void limitint<B>::limitint_unstack_to(T &a)
00569     {
00570 
00571             // T is supposed to be an unsigned "integer"
00572             // (ie.: sizeof returns the width of the storage bit field  and no sign bit is present)
00573             // Note : static here avoids the recalculation of max_T at each call
00574         static const T max_T = max_val_of(a);
00575         T step = max_T - a;
00576 
00577         if(field < (B)(step) && (T)(field) < step)
00578         {
00579             a += field;
00580             field = 0;
00581         }
00582         else
00583         {
00584             field -= step;
00585             a = max_T;
00586         }
00587     }
00588 
00589     template <class B> limitint<B> limitint<B>::get_storage_size() const
00590     {
00591         B tmp = field;
00592         B ret = 0;
00593 
00594         while(tmp != 0)
00595         {
00596             tmp >>= 8;
00597             ret++;
00598         }
00599 
00600         return limitint<B>(ret);
00601     }
00602 
00603     template <class B> unsigned char limitint<B>::operator [] (const limitint & position) const
00604     {
00605         B tmp = field;
00606         B index = position.field; // C++ has only class protection, not object protection
00607 
00608         while(index > 0)
00609         {
00610             tmp >>= 8;
00611             index--;
00612         }
00613 
00614         return (unsigned char)(tmp & 0xFF);
00615     }
00616 
00617     template <class B> void limitint<B>::setup_endian()
00618     {
00619         if(integers_system_is_big_endian())
00620             used_endian = big_endian;
00621         else
00622             used_endian = little_endian;
00623 
00624         (void)memset(zeroed_field, 0, ZEROED_SIZE);
00625     }
00626 
00627 
00628     template <class B> bool limitint<B>::is_system_big_endian()
00629     {
00630         if(used_endian == not_initialized)
00631             setup_endian();
00632 
00633         switch(used_endian)
00634         {
00635         case big_endian:
00636             return true;
00637         case little_endian:
00638             return false;
00639         case not_initialized:
00640             throw SRC_BUG;
00641         default:
00642             throw SRC_BUG;
00643         }
00644     }
00645 
00646 
00650 
00651     template <class B> limitint<B> operator + (const limitint<B> & a, const limitint<B> & b)
00652     {
00653         limitint<B> ret = a;
00654         ret += b;
00655 
00656         return ret;
00657     }
00658 
00659     template <class B> limitint<B> operator - (const limitint<B> & a, const limitint<B> & b)
00660     {
00661         limitint<B> ret = a;
00662         ret -= b;
00663 
00664         return ret;
00665     }
00666 
00667     template <class B> limitint<B> operator * (const limitint<B> & a, const limitint<B> & b)
00668     {
00669         limitint<B> ret = a;
00670         ret *= b;
00671 
00672         return ret;
00673     }
00674 
00675     template <class B> limitint<B> operator / (const limitint<B> & a, const limitint<B> & b)
00676     {
00677         limitint<B> ret = a;
00678         ret /= b;
00679 
00680         return ret;
00681     }
00682 
00683     template <class B> limitint<B> operator % (const limitint<B> & a, const limitint<B> & b)
00684     {
00685         limitint<B> ret = a;
00686         ret %= b;
00687 
00688         return ret;
00689     }
00690 
00691     template <class B> limitint<B> operator >> (const limitint<B> & a, U_32 bit)
00692     {
00693         limitint<B> ret = a;
00694         ret >>= bit;
00695         return ret;
00696     }
00697 
00698     template <class B> limitint<B> operator >> (const limitint<B> & a, const limitint<B> & bit)
00699     {
00700         limitint<B> ret = a;
00701         ret >>= bit;
00702         return ret;
00703     }
00704 
00705     template <class B> limitint<B> operator << (const limitint<B> & a, U_32 bit)
00706     {
00707         limitint<B> ret = a;
00708         ret <<= bit;
00709         return ret;
00710     }
00711 
00712     template <class B> limitint<B> operator << (const limitint<B> & a, const limitint<B> & bit)
00713     {
00714         limitint<B> ret = a;
00715         ret <<= bit;
00716         return ret;
00717     }
00718 
00719     template <class B> limitint<B> operator & (const limitint<B> & a, U_32 bit)
00720     {
00721         limitint<B> ret = a;
00722         ret &= bit;
00723         return ret;
00724     }
00725 
00726     template <class B> limitint<B> operator & (const limitint<B> & a, const limitint<B> & bit)
00727     {
00728         limitint<B> ret = a;
00729         ret &= bit;
00730         return ret;
00731     }
00732 
00733     template <class B> limitint<B> operator | (const limitint<B> & a, U_32 bit)
00734     {
00735         limitint<B> ret = a;
00736         ret |= bit;
00737         return ret;
00738     }
00739 
00740     template <class B> limitint<B> operator | (const limitint<B> & a, const limitint<B> & bit)
00741     {
00742         limitint<B> ret = a;
00743         ret |= bit;
00744         return ret;
00745     }
00746 
00747     template <class B> limitint<B> operator ^ (const limitint<B> & a, U_32 bit)
00748     {
00749         limitint<B> ret = a;
00750         ret ^= bit;
00751         return ret;
00752     }
00753 
00754     template <class B> limitint<B> operator ^ (const limitint<B> & a, const limitint<B> & bit)
00755     {
00756         limitint<B> ret = a;
00757         ret ^= bit;
00758         return ret;
00759     }
00760 
00762 
00763 } // end of namespace
00764 
00765 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines