00001
00020 #include "config.h"
00021
00022 #include <stdexcept>
00023 #include <iostream>
00024 #include <string>
00025 #include <sstream>
00026
00027
00028 #include <cstdio>
00029
00030 #include <cstdlib>
00031
00032 #if HAVE_CSETJMP
00033 #include <csetjmp>
00034 #endif
00035
00036 #include <boost/shared_ptr.hpp>
00037
00038 #if HAVE_LOKI_FUNCTOR_H
00039
00040 #define LOKI_ENABLE_FUNCTION
00041 #define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
00042 #include <loki/Functor.h>
00043
00044 #endif // HAVE_LOKI_FUNCTOR_H
00045
00046 #ifndef UTILS_HPP_
00047 #define UTILS_HPP_
00048
00049 const char bitsPerByte = 8;
00050
00052 template <typename Integer> class HexInteger{
00053 private:
00054 Integer content;
00055 public:
00056 HexInteger(Integer newContent):
00057 content(newContent)
00058 {}
00059
00060 operator Integer() const{
00061 return content;
00062 }
00063 };
00064
00068 template <typename Integer> std::ostream &operator<<(
00069 std::ostream &aOstream,
00070 const HexInteger<Integer> &x
00071 ){
00072 std::ios::fmtflags oldAOstreamFlags = aOstream.flags();
00073 aOstream << std::showbase << std::hex << Integer(x);
00074 aOstream.flags(oldAOstreamFlags);
00075 return aOstream;
00076 }
00077
00082 struct null_deleter
00083 {
00084 void operator()(void const *) const
00085 {
00086 }
00087 };
00088
00092 class CArrayOfArrayDeleter{
00093 private:
00094 size_t size1;
00095
00096 public:
00099 CArrayOfArrayDeleter(size_t newSize1):
00100 size1(newSize1)
00101 {}
00102
00103 void operator()(void *array) const{
00104 void **arrayOfArray = static_cast<void**>(array);
00105 for(
00106 size_t i = 0;
00107 i < size1;
00108 i++
00109 ){
00110 free(arrayOfArray[i]);
00111 }
00112 free(arrayOfArray);
00113 }
00114 };
00115
00117 class CFileWrapper{
00118 private:
00119 boost::shared_ptr<FILE> file;
00120
00126 struct CFileDeleter{
00127 void operator()(FILE *file){
00128 if(file != NULL){
00129 int result = fclose(file);
00130 if(result == EOF){
00131 std::cerr << "ERROR: Closing file" << std::endl;
00132 }
00133 }
00134 }
00135 };
00136 public:
00137 CFileWrapper() {}
00138
00140 CFileWrapper(const char *filename, const char *mode){
00141 open(filename, mode);
00142 }
00143
00144 ~CFileWrapper() {}
00145
00147 void open(const char *filename, const char *mode){
00148 file = boost::shared_ptr<FILE>(
00149 fopen(filename, mode),
00150 CFileDeleter()
00151 );
00152 if(file.get() == NULL){
00153 throw std::runtime_error(
00154 std::string("Cannot open file \"") +
00155 filename +
00156 "\""
00157 );
00158 }
00159 }
00160
00161
00162 FILE *get(){
00163 return file.get();
00164 }
00165 };
00166
00167 #if HAVE_BOOST_SHARED_PTR_HPP
00168
00169 template <typename T> bool isEmpty(boost::shared_ptr<T> &p){
00170 return ( p == boost::shared_ptr<T>() );
00171 }
00172 #endif // HAVE_BOOST_SHARED_PTR_HPP
00173
00177 template <typename Integer> Integer roundDiv(
00178 Integer a,
00179 Integer b
00180 ){
00181 if(a < 0 || b <= 0){
00182 throw std::runtime_error(std::string(__PRETTY_FUNCTION__)+" is only for positive integers");
00183 }
00184
00185 Integer q = a/b;
00186 Integer r = a%b;
00187
00188 if(r < b/2){
00189 return q;
00190 }else if(r > b/2){
00191 return q+1;
00192 }else{
00193
00194 return q+(q%2);
00195 }
00196 }
00197
00199 template <typename T> std::istream &readBin(std::istream &inStream, T &field){
00200 return inStream.read(
00201 reinterpret_cast<char*>(&field),
00202 sizeof(field)
00203 );
00204 }
00205
00207 template <typename T> std::ostream &writeBin(std::ostream &outStream, T &field){
00208 return outStream.write(
00209 reinterpret_cast<char*>(&field),
00210 sizeof(field)
00211 );
00212 }
00213
00215 template <typename Integer> Integer checkedDivByMultiple(Integer a, Integer b){
00216 if(a % b != 0){
00217 throw std::runtime_error("\"divByMultiple\": divisor isn\'t a multiple of dividend");
00218 }
00219 return a / b;
00220 }
00221
00223 template <typename Integer> Integer checkedBitsToIntBytes(Integer bits){
00224 return checkedDivByMultiple(bits, Integer(bitsPerByte));
00225 }
00226
00230 template <typename Out> Out getBytes(const char *whereFrom, int numBytes){
00231 Out result = 0;
00232
00233 whereFrom += numBytes-1;
00234
00235 const unsigned char *curWhereFrom =
00236 reinterpret_cast<const unsigned char*>(whereFrom);
00237 for(
00238 ;
00239 numBytes > 0;
00240 --numBytes
00241 ){
00242 result <<= bitsPerByte;
00243 result += *curWhereFrom;
00244
00245 --curWhereFrom;
00246 }
00247 return result;
00248 }
00249
00253 template <typename In> void setBytes(char *whereTo, int numBytes, In newValue){
00254 unsigned char *curWhereTo =
00255 reinterpret_cast<unsigned char*>(whereTo);
00256 for(
00257 ;
00258 numBytes > 0;
00259 --numBytes
00260 ){
00261 *curWhereTo = 0xff & newValue;
00262 newValue >>= bitsPerByte;
00263
00264 ++curWhereTo;
00265 }
00266 }
00267
00269 template <typename In> std::string lexicalCastToStdString(In a){
00270 std::ostringstream tmpOut;
00271 tmpOut << a;
00272 return tmpOut.str();
00273 }
00274
00276 #define TODO_HERE(x) { \
00277 std::clog << std::string("TODO: ") + \
00278 "in function \"" + __PRETTY_FUNCTION__ + \
00279 "\", file \"" + __FILE__ + \
00280 "\" at line " + lexicalCastToStdString(__LINE__) << \
00281 std::endl; } \
00282 while(false)
00283
00285 #define TODO(x) { \
00286 std::clog << std::string("TODO: ") + \
00287 "in function \"" + __PRETTY_FUNCTION__ + \
00288 "\", file \"" + __FILE__ + \
00289 "\" at line " + lexicalCastToStdString(__LINE__) + \
00290 ": \n" + #x << std::endl; } \
00291 while(false)
00292
00294 #define TRACE(x) std::clog << "\"" << #x << "\" = \"" << x << "\"" << std::endl
00295
00297 #define ARRAY_SIZE(a) ( (sizeof( (a) )/sizeof( (a)[0])) )
00298
00299 #endif // UTILS_HPP_