Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

tools.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmstools/tools.h"
00034 #include "mmstools/mmsmutex.h"
00035 #include "mmsconfig/mmsconfigdata.h"
00036 #include "mmstools/mmserror.h"
00037 
00038 #include <algorithm>
00039 
00040 extern "C" {
00041 #ifdef __HAVE_WORDEXP__
00042 #include <wordexp.h>
00043 #endif
00044 #include <string.h>
00045 #include <errno.h>
00046 #include <sys/stat.h>
00047 #include <stdlib.h>
00048 #ifdef __HAVE_BACKTRACE__
00049 #include <execinfo.h>
00050 #endif
00051 #ifdef __HAVE_FRIBIDI__
00052 #include <fribidi/fribidi.h>
00053 #endif
00054 }
00055 
00056 /* Once-only initialisation of the key */
00057 static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
00058 /* contains the key to the thread specific memory */
00059 static pthread_key_t  key_iam;
00060 static pthread_key_t  key_logfile;
00061 #ifdef __ENABLE_LOG__
00062 static MMSConfigData  config;
00063 #endif
00064 static FILE           *fp=NULL;
00065 static MMSMutex       debugMsgMutex;
00066 
00067 
00068 string substituteEnvVars(string input) {
00069 #ifdef __HAVE_WORDEXP__
00070     wordexp_t p;
00071     char **w;
00072     string output = "";
00073     if (input != "") {
00074         wordexp(input.c_str(), &p, 0);
00075         w = p.we_wordv;
00076         for (unsigned i=0; i<p.we_wordc; i++)
00077             if (i==0) {
00078                 output = w[i];
00079                 break;
00080             }
00081         wordfree(&p);
00082     }
00083     return output;
00084 #else
00085 #warning "wordexp not found: substituteEnvVars() has no effect"
00086     return input;
00087 #endif
00088 }
00089 
00090 string maskChars(string str) {
00091     string  ret;
00092     for (unsigned i=0; i<str.size(); i++) {
00093         if (str.at(i) == '\'')
00094             ret = ret + "''";
00095         else
00096             ret = ret + str.at(i);
00097     }
00098     return ret;
00099 }
00100 
00101 string *strToUpr(string *src) {
00102     for(string::iterator i=src->begin(); i!= src->end(); i++) {
00103 
00104         if((*i >= 'a') && (*i <= 'z'))
00105             (*i)-=32;
00106     }
00107 
00108     return src;
00109 }
00110 
00111 string strToUpr(string src) {
00112     string s;
00113     s=src;
00114     strToUpr(&s);
00115     return s;
00116 }
00117 
00118 string *strToLwr(string *src) {
00119     for(string::iterator i=src->begin(); i!= src->end(); i++) {
00120 
00121         if((*i >= 'A') && (*i <= 'Z'))
00122             (*i)+=32;
00123     }
00124 
00125     return src;
00126 }
00127 
00128 string strToLwr(string src) {
00129     string s;
00130     s=src;
00131     strToLwr(&s);
00132     return s;
00133 }
00134 
00135 int hexToInt(const char *in) {
00136     int ret=0;
00137 
00138     /* working with first char */
00139     if (*in>='0' && *in<='9')
00140         ret+=((int)*in-'0')*16;
00141     else
00142     if (*in>='A' && *in<='F')
00143         ret+=((int)*in-'A'+10)*16;
00144     else
00145     if (*in>='a' && *in<='f')
00146         ret+=((int)*in-'a'+10)*16;
00147 
00148     /* working with second char */
00149     in++;
00150     if (*in>='0' && *in<='9')
00151         ret+=(int)*in-'0';
00152     else
00153     if (*in>='A' && *in<='F')
00154         ret+=(int)*in-'A'+10;
00155     else
00156     if (*in>='a' && *in<='f')
00157         ret+=(int)*in-'a'+10;
00158 
00159     return ret;
00160 }
00161 
00162 string ucharToHex(unsigned char in) {
00163     char buf[3];
00164     sprintf(buf, "%02x", in);
00165     return buf;
00166 }
00167 
00168 string getSimpleTimeString() {
00169     string timstr;
00170 
00171     getCurrentTimeString(NULL,NULL,&timstr,NULL);
00172 
00173     return timstr;
00174 }
00175 
00176 bool getCurrentTimeBuffer(char *dtbuf, char *datebuf, char *timebuf, time_t *clock) {
00177     struct  tm newtime;
00178     time_t  aclock;
00179 
00180     /* get current date and time */
00181     time(&aclock);
00182     if (clock) {
00183         if (*clock)
00184             aclock=*clock;
00185         else
00186             *clock=aclock;
00187     }
00188     localtime_r(&aclock, &newtime);
00189 
00190     if (dtbuf)
00191         sprintf(dtbuf,"%04d-%02d-%02d %02d:%02d:%02d",
00192                         newtime.tm_year+1900,
00193                         newtime.tm_mon+1,
00194                         newtime.tm_mday,
00195                         newtime.tm_hour,
00196                         newtime.tm_min,
00197                         newtime.tm_sec
00198                         );
00199 
00200     if (datebuf)
00201         sprintf(datebuf,"%04d-%02d-%02d",
00202                         newtime.tm_year+1900,
00203                         newtime.tm_mon+1,
00204                         newtime.tm_mday
00205                         );
00206 
00207     if (timebuf)
00208         sprintf(timebuf,"%02d:%02d:%02d",
00209                         newtime.tm_hour,
00210                         newtime.tm_min,
00211                         newtime.tm_sec
00212                         );
00213 
00214     return true;
00215 }
00216 
00217 bool getCurrentTimeString(string *dtstr, string *datestr, string *timestr, time_t *clock) {
00218     char    dtbuf[20];
00219     char    datebuf[11];
00220     char    timebuf[9];
00221 
00222     if (getCurrentTimeBuffer((dtstr)?dtbuf:NULL,
00223                              (datestr)?datebuf:NULL,
00224                              (timestr)?timebuf:NULL,
00225                              clock)) {
00226         if (dtstr) *dtstr=dtbuf;
00227         if (datestr) *datestr=datebuf;
00228         if (timestr) *timestr=timebuf;
00229         return true;
00230     }
00231     else
00232         return false;
00233 }
00234 
00235 string getDayOfWeek(time_t *clock) {
00236     struct  tm newtime;
00237     time_t  aclock;
00238 
00239     /* get current date and time */
00240     time(&aclock);
00241     if (clock) {
00242         if (*clock)
00243             aclock=*clock;
00244         else
00245             *clock=aclock;
00246     }
00247     localtime_r(&aclock, &newtime);
00248 
00249     switch (newtime.tm_wday) {
00250         case 0:
00251             return "Sunday";
00252         case 1:
00253             return "Monday";
00254         case 2:
00255             return "Tuesday";
00256         case 3:
00257             return "Wednesday";
00258         case 4:
00259             return "Thursday";
00260         case 5:
00261             return "Friday";
00262         case 6:
00263             return "Saturday";
00264     }
00265 
00266     return "";
00267 }
00268 
00269 static void bufferDestroy(void *buffer) {
00270     free(buffer);
00271 }
00272 
00273 static void bufferKeyAlloc() {
00274     pthread_key_create(&key_iam, bufferDestroy);
00275     pthread_key_create(&key_logfile, bufferDestroy);
00276 }
00277 
00278 void initLogging(char *Iam, char *logfile) {
00279     char *dest;
00280     pthread_once(&buffer_key_once, bufferKeyAlloc);
00281 
00282     dest = (char *)pthread_getspecific(key_iam);
00283     if (dest == NULL)
00284         pthread_setspecific(key_iam, malloc(100));
00285 
00286     dest = (char *)pthread_getspecific(key_iam);
00287     memset(dest,0,100);
00288     strncpy(dest,Iam,99);
00289 
00290     dest = (char *)pthread_getspecific(key_logfile);
00291     if (dest == NULL)
00292         pthread_setspecific(key_logfile, malloc(1000));
00293     dest = (char *)pthread_getspecific(key_logfile);
00294     memset(dest,0,1000);
00295     strncpy(dest,logfile,999);
00296 
00297 }
00298 
00299 
00300 void writeMessage(const char *ctrl,...) {
00301     char *iam;
00302     char *logname;
00303     char currTimebuffer[128];
00304     FILE *File;
00305     char line[10000];
00306 
00307     va_list marker;
00308     va_start(marker, ctrl);
00309 
00310     iam     = (char *)pthread_getspecific(key_iam);
00311     logname = (char *)pthread_getspecific(key_logfile);
00312 
00313     if(logname == NULL) {
00314         logname = (char*)"/var/log/disko/logfile";
00315     }
00316     if(iam == NULL) {
00317         iam = (char*)"unkown";
00318     }
00319 
00320     getCurrentTimeBuffer(currTimebuffer);
00321 
00322     if ((File=fopen(logname,"at"))) {
00323 
00324         fprintf (File,"%s  ",currTimebuffer);
00325         vsprintf(line,ctrl,marker);
00326         if(line[0]!='[')
00327             fprintf(File,"[%s]: ",iam);
00328 
00329         fprintf (File,"%s",line);
00330 
00331         fprintf (File,"\n");
00332 
00333         fflush(File);
00334         fclose(File);
00335     }
00336 
00337     va_end(marker);
00338 
00339 }
00340 
00341 int strToInt(string s) {
00342     return atoi(s.c_str());
00343 }
00344 
00345 unsigned int strToUInt(string s){
00346     return (unsigned int)atoi(s.c_str());
00347 }
00348 
00349 
00350 string iToStr(int i) {
00351     char mychar[24];
00352     string mystr;
00353 
00354     sprintf(mychar,"%d",i);
00355     mystr = mychar;
00356     return mystr;
00357 }
00358 
00359 /* ToDo: get the maximum number of digits for this */
00360 string fToStr(double i) {
00361     char mychar[1024];
00362     string mystr;
00363 
00364     sprintf(mychar,"%f",i);
00365     mystr = mychar;
00366     return mystr;
00367 }
00368 
00369 
00370 char *scanForString(char *buf, char *toFind, char **ret,
00371                     int offset, unsigned int length) {
00372     char            *ptr;
00373     char            *tmp;
00374     unsigned int    reallen;
00375 
00376     if ((ptr = strstr(buf, toFind))) {
00377         if (ret) {
00378             tmp = ptr + strlen(toFind);
00379             reallen = strlen(tmp);
00380             if ((int)reallen>=offset) {
00381                 tmp+=offset;
00382                 reallen-=offset;
00383             }
00384             else {
00385                 tmp+=reallen;
00386                 reallen=0;
00387             }
00388             if (!length)
00389                 length = reallen;
00390             else
00391                 if (reallen<length) length=reallen;
00392             *ret = (char *)malloc(length+1);
00393             memcpy(*ret, tmp, length);
00394             (*ret)[length]=0;
00395         }
00396     }
00397 
00398     return ptr;
00399 }
00400 
00401 char *scanForString(char *buf, char *toFind, string *ret,
00402                     int offset, unsigned int length) {
00403     char    *rbuf;
00404     char    *tmpret;
00405 
00406     if (ret) *ret="";
00407     if ((rbuf = scanForString(buf, toFind, &tmpret, offset, length))) {
00408         if (tmpret) {
00409             if (ret) *ret = tmpret;
00410             free(tmpret);
00411         }
00412     }
00413 
00414     return rbuf;
00415 }
00416 
00417 string scanForString(string buf, string toFind, string *ret,
00418                     int offset, unsigned int length) {
00419     int             ptr;
00420     string          tmp;
00421     unsigned int    reallen;
00422 
00423     if ((ptr=buf.find(toFind))>=0) {
00424         if (ret) {
00425             tmp=buf.substr(ptr + toFind.size());
00426             reallen = tmp.size();
00427             if ((int)reallen>=offset) {
00428                 tmp=tmp.substr(offset);
00429                 reallen-=offset;
00430             }
00431             else {
00432                 tmp=tmp.substr(reallen);
00433                 reallen=0;
00434             }
00435             if (!length)
00436                 length = reallen;
00437             else
00438                 if (reallen<length) length=reallen;
00439             *ret = tmp.substr(0, length);
00440         }
00441 
00442         return buf.substr(ptr);
00443     }
00444 
00445     return "";
00446 }
00447 
00448 void split(string str, string delim, vector<string> &results, bool allowEmpty) {
00449   size_t cutAt;
00450   while((cutAt = str.find_first_of(delim)) != str.npos) {
00451     if(cutAt > 0 || allowEmpty) {
00452       results.push_back(str.substr(0,cutAt));
00453     }
00454     str = str.substr(cutAt+1);
00455   }
00456   if(str.length() > 0 || allowEmpty) {
00457     results.push_back(str);
00458   }
00459 }
00460 
00461 void msleep(unsigned long msec) {
00462     if (msec > 0)
00463         usleep(msec * 1000);
00464 }
00465 
00466 
00467 bool scanString(string toscan, string frontkey, string backkey,
00468                 unsigned int offset, unsigned int length, string *result, unsigned int *nextpos) {
00469     int pos;
00470 
00471     if (frontkey != "") {
00472         pos = (int)toscan.find(frontkey);
00473         if (pos<0)
00474             return false;
00475         toscan = toscan.substr(pos + frontkey.size());
00476         if (nextpos)
00477             (*nextpos)+=pos + frontkey.size();
00478     }
00479     if (backkey != "") {
00480         pos = (int)toscan.find(backkey);
00481         if (pos<0)
00482             return false;
00483         else {
00484             toscan = toscan.substr(0, pos);
00485             if (nextpos)
00486                 (*nextpos)+=pos + backkey.size();
00487             if (frontkey != "") {
00488                 while (1) {
00489                     pos = (int)toscan.find(frontkey);
00490                     if (pos<0)
00491                         break;
00492                     toscan = toscan.substr(pos + frontkey.size());
00493                 }
00494             }
00495         }
00496     }
00497 
00498     if (length) {
00499         if (toscan.size() >= offset + length)
00500             *result = toscan.substr(offset, length);
00501         else
00502             return false;
00503     }
00504     else
00505         if (offset) {
00506             if (toscan.size() >= offset)
00507                 *result = toscan.substr(offset);
00508             else
00509                 return false;
00510         }
00511         else
00512             *result = toscan;
00513 
00514     return true;
00515 }
00516 
00517 
00518 string cpToStr(char *str) {
00519     string ret = str;
00520     return ret;
00521 }
00522 
00523 
00524 string cToStr(char chr) {
00525     char my[2];
00526     my[0]=chr;
00527     my[1]=0;
00528 
00529     string ret = my;
00530 
00531     return ret;
00532 }
00533 
00534 void trim(string& str)
00535 {
00536   string::size_type pos = str.find_last_not_of(' ');
00537   if(pos != string::npos) {
00538     str.erase(pos + 1);
00539     pos = str.find_first_not_of(' ');
00540     if(pos != string::npos) str.erase(0, pos);
00541   }
00542   else str.erase(str.begin(), str.end());
00543 }
00544 
00545 bool strToBool(string s) {
00546     if(s.empty())
00547         return false;
00548 
00549     if(strcasecmp(s.c_str(), "true") == 0)
00550         return true;
00551     else
00552         return false;
00553 }
00554 
00555 bool dblSlash(char a, char b) { return (a == '/') && (b == '/'); }
00556 void fixPathStr(string &path) {
00557     std::string::iterator it = std::unique(path.begin(), path.end(), dblSlash);
00558     path.resize(std::distance(path.begin(), it));
00559 }
00560 
00561 void executeCmd(string cmd, pid_t *cpid) {
00562     pid_t pid;
00563     int i,y;
00564     int argc;
00565     char *argv[256];
00566     char buffer[4096];
00567 
00568 
00569     for (i=0;i<256;i++)
00570         argv[i]=NULL;
00571     argc=0;
00572     sprintf(buffer,"%s",cmd.c_str());
00573     DEBUGOUT("\n%s\n",buffer);
00574     argv[0]=buffer;
00575 
00576     i=0;
00577     while ((buffer[i]!=0)&&(argc<256)) {
00578         while(buffer[i]==' ')
00579             i++;
00580 
00581         if(buffer[i]==0)
00582             break;
00583 
00584         if(buffer[i]=='\'') {
00585             i++;
00586             y=i;
00587             while ((buffer[i]!='\'')&&(buffer[i]!=0))
00588                 i++;
00589 
00590             if (buffer[i]=='\'') {
00591                 buffer[i]=0;
00592                 i++;
00593             }
00594         } else if (buffer[i]=='"') {
00595             i++;
00596             y=i;
00597             while ((buffer[i]!='"')&&(buffer[i]!=0))
00598                 i++;
00599 
00600             if (buffer[i]=='"') {
00601                 buffer[i]=0;
00602                 i++;
00603             }
00604         } else {
00605             y=i;
00606             while ((buffer[i]!=' ')&&(buffer[i]!=0))
00607                 i++;
00608 
00609             if (buffer[i]==' ') {
00610                 buffer[i]=0;
00611                 i++;
00612             }
00613         }
00614         argv[argc]=&buffer[y];
00615         argc++;
00616     }
00617 
00618 
00619     pid = fork();
00620         if(pid!=-1) {
00621         if(pid>0) {
00622             if (cpid) {
00623               (*cpid) = pid;
00624             }
00625             return;
00626         }
00627         if(pid==0) {
00628             unsetenv("LD_PRELOAD");
00629             execvp(argv[0],argv);
00630             printf("\nError while exec: %s",strerror(errno));
00631             printf("\nargv[0]: %s",argv[0]);
00632             printf("\nargv[1]: %s",argv[1]);
00633             exit(1);
00634         }
00635     }
00636 }
00637 
00638 
00639 bool file_exist( string filename ) {
00640     struct stat buffer ;
00641 
00642     if ( stat( filename.c_str(), &buffer ) == 0)
00643         return true;
00644 
00645     return false;
00646 }
00647 
00648 void writeDebugMessage(const char *identity, const char *filename, const int lineno, const char *msg, ...) {
00649 #ifdef __ENABLE_LOG__
00650     va_list     arglist;
00651     struct      timeval tv;
00652     char        timebuf[12];
00653     int         num;
00654     const char  *logfile = config.getLogfile().c_str();
00655 
00656     debugMsgMutex.lock();
00657     if(!strlen(logfile))
00658         fp = stderr;
00659     else if((fp=fopen(logfile, "a+"))==NULL)
00660         throw MMSError(errno, "Can't open logfile [" + string(strerror(errno)) + "]");
00661 
00662     gettimeofday(&tv, NULL);
00663     getCurrentTimeBuffer(NULL, NULL, timebuf, NULL);
00664 
00665     num = fprintf(fp, "%s:%02ld %010u %s: ", timebuf, tv.tv_usec/10000, (unsigned int)pthread_self(), identity);
00666     if(num) {
00667         va_start(arglist, (char *)msg);
00668         num = vfprintf(fp, msg, arglist);
00669         va_end(arglist);
00670     }
00671     if(num) num = fprintf(fp, " [%s:%d]\n", filename, lineno);
00672     if(!num)
00673         fprintf(stderr, "DISKO: Error writing to logfile\n");
00674 
00675     if(fp != stderr)
00676         fclose(fp);
00677     debugMsgMutex.unlock();
00678 
00679     return;
00680 #endif
00681 }
00682 
00683 void writeDebugMessage(const char *identity, const char *filename, const int lineno, const string &msg) {
00684 #ifdef __ENABLE_LOG__
00685     struct      timeval tv;
00686     char        timebuf[12];
00687     const char  *logfile = config.getLogfile().c_str();
00688 
00689     debugMsgMutex.lock();
00690     if(!strlen(logfile))
00691         fp = stderr;
00692     else if((fp=fopen(logfile, "a+"))==NULL)
00693         throw MMSError(errno, "Can't open logfile [" + string(strerror(errno)) + "]");
00694 
00695     gettimeofday(&tv, NULL);
00696     getCurrentTimeBuffer(NULL, NULL, timebuf, NULL);
00697 
00698     if(fprintf(fp, "%s:%02ld %010u %s: %s [%s:%d]\n", timebuf, tv.tv_usec/10000,
00699                (unsigned int)pthread_self(), identity, msg.c_str(), filename, lineno) == 0)
00700         fprintf(stderr, "DISKO: Error writing to logfile\n");
00701 
00702     if(fp != stderr)
00703         fclose(fp);
00704     debugMsgMutex.unlock();
00705 
00706     return;
00707 #endif
00708 }
00709 
00710 
00711 void writeMessage2Stdout(const char *identity, const char *filename, const int lineno, const char *msg, ...) {
00712     va_list arglist;
00713     struct  timeval tv;
00714     char    timebuf[12];
00715     int     num;
00716 
00717     gettimeofday(&tv, NULL);
00718     getCurrentTimeBuffer(NULL, NULL, timebuf, NULL);
00719 
00720     num = fprintf(stdout, "%s:%02ld %010u %s: ", timebuf, tv.tv_usec/10000, (unsigned int)pthread_self(), identity);
00721 
00722     if(num) {
00723         va_start(arglist, (char *)msg);
00724         num = vfprintf(stdout, msg, arglist);
00725         va_end(arglist);
00726     }
00727     if(num) num = fprintf(stdout, " [%s:%d]\n", filename, lineno);
00728     if(!num)
00729         fprintf(stderr, "DISKO: Error writing to stdout\n");
00730 
00731     return;
00732 }
00733 
00734 
00735 void writeMessage2Stdout(const char *identity, const char *filename, const int lineno, const string &msg) {
00736     struct  timeval tv;
00737     char    timebuf[12];
00738 
00739     gettimeofday(&tv, NULL);
00740     getCurrentTimeBuffer(NULL, NULL, timebuf, NULL);
00741 
00742     if(printf("%s:%02ld %010u %s: %s [%s:%d]\n", timebuf, tv.tv_usec/10000,
00743                (unsigned int)pthread_self(), identity, msg.c_str(), filename, lineno) == 0)
00744         fprintf(stderr, "DISKO: Error writing to logfile\n");
00745 
00746     return;
00747 }
00748 
00749 
00750 #define MAX_MTIMESTAMP  999999
00751 
00752 unsigned int getMTimeStamp() {
00753     struct  timeval tv;
00754 
00755     // get seconds and milli seconds
00756     gettimeofday(&tv, NULL);
00757 
00758     // build timestamp
00759     return ((tv.tv_sec % 1000) * 1000) + tv.tv_usec / 1000;
00760 }
00761 
00762 unsigned int getMDiff(unsigned int start_ts, unsigned int end_ts) {
00763     unsigned int diff;
00764     if (start_ts <= end_ts)
00765         diff = end_ts - start_ts;
00766     else
00767         diff = MAX_MTIMESTAMP - start_ts + 1 + end_ts;
00768 
00769     return diff;
00770 }
00771 
00772 int64_t timespecDiff(struct timespec *timeA, struct timespec *timeB) {
00773   return ((timeA->tv_sec * 1000000000) + timeA->tv_nsec) -
00774            ((timeB->tv_sec * 1000000000) + timeB->tv_nsec);
00775 }
00776 
00777 
00778 
00779 
00780 
00781 void rotateUCharBuffer180(unsigned char *buffer, int pitch, int w, int h) {
00782     for (int y = 0; y < (h + 1) / 2; y++) {
00783         unsigned char tmp;
00784         unsigned char *ptr1 = &buffer[y * pitch];
00785         unsigned char *ptr2 = &buffer[(h - 1 - y) * pitch];
00786         bool sameline = (ptr1 == ptr2);
00787         ptr2+= w - 1;
00788         for (int x = 0; x < ((!sameline) ? w : w / 2); x++) {
00789             tmp = *ptr2;
00790             *ptr2 = *ptr1;
00791             *ptr1 = tmp;
00792             ptr1++;
00793             ptr2--;
00794         }
00795     }
00796 }
00797 
00798 void rotateUShortIntBuffer180(unsigned short int *buffer, int pitch, int w, int h) {
00799     for (int y = 0; y < (h + 1) / 2; y++) {
00800         unsigned short int tmp;
00801         unsigned short int *ptr1 = (unsigned short int *)&((unsigned char *)buffer)[y * pitch];
00802         unsigned short int *ptr2 = (unsigned short int *)&((unsigned char *)buffer)[(h - 1 - y) * pitch];
00803         bool sameline = (ptr1 == ptr2);
00804         ptr2+= w - 1;
00805         for (int x = 0; x < ((!sameline) ? w : w / 2); x++) {
00806             tmp = *ptr2;
00807             *ptr2 = *ptr1;
00808             *ptr1 = tmp;
00809             ptr1++;
00810             ptr2--;
00811         }
00812     }
00813 }
00814 
00815 void rotateUIntBuffer180(unsigned int *buffer, int pitch, int w, int h) {
00816     for (int y = 0; y < (h + 1) / 2; y++) {
00817         unsigned int tmp;
00818         unsigned int *ptr1 = (unsigned int *)&((unsigned char *)buffer)[y * pitch];
00819         unsigned int *ptr2 = (unsigned int *)&((unsigned char *)buffer)[(h - 1 - y) * pitch];
00820         bool sameline = (ptr1 == ptr2);
00821         ptr2+= w - 1;
00822         for (int x = 0; x < ((!sameline) ? w : w / 2); x++) {
00823             tmp = *ptr2;
00824             *ptr2 = *ptr1;
00825             *ptr1 = tmp;
00826             ptr1++;
00827             ptr2--;
00828         }
00829     }
00830 }
00831 
00832 #ifdef __HAVE_BACKTRACE__
00833 void print_trace(char *prefix) {
00834     void    *array[10];
00835     size_t  size;
00836     char    **strings;
00837     size_t  i;
00838 
00839     size    = backtrace(array, 10);
00840     strings = backtrace_symbols(array, size);
00841 
00842     fprintf(stderr, "******************* %s ****************\n", prefix);
00843 
00844     for(i = 2; i < size; i++)
00845       fprintf(stderr, "%s\n", strings[i]);
00846 
00847     free(strings);
00848 }
00849 #endif
00850 
00851 
00852 
00853 bool convBidiString(const string &in_str, string &out_str, bool bArabic) {
00854 #ifdef __HAVE_FRIBIDI__
00855     bool ret = false;
00856     const char *char_set = "UTF-8";
00857     FriBidiCharSet char_set_num;
00858 
00859     // get charset and init
00860     if (!(char_set_num = fribidi_parse_charset((char *)char_set))) {
00861         printf("DISKO: FriBidi error, unrecognized character set '%s'\n", char_set);
00862         return false;
00863     }
00864     fribidi_set_mirroring(true);
00865     fribidi_set_reorder_nsm(false);
00866 
00867     // check input length
00868     FriBidiStrIndex len = in_str.length();
00869     if (len <= 0) {
00870         out_str = "";
00871         return true;
00872     }
00873 
00874     // allocate temp buffers
00875     int memsize = sizeof(FriBidiChar) * (len + 1);
00876     FriBidiChar *logical = (FriBidiChar *)malloc(memsize);
00877     FriBidiChar *visual  = (FriBidiChar *)malloc(memsize);
00878     char        *ostr    = (char *)malloc(memsize);
00879 
00880     if (logical && visual && ostr) {
00881         // convert input string into FriBidiChar buffer
00882         len = fribidi_charset_to_unicode(char_set_num, (char *)in_str.c_str(), len, logical);
00883 
00884         // create a bidi visual string
00885         FriBidiCharType base = FRIBIDI_TYPE_ON;
00886         if ((ret = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL))) {
00887 
00888             if (bArabic) {
00889                 FriBidiLevel *embedding_levels = (FriBidiLevel *)malloc(sizeof(FriBidiLevel) * len);
00890                 if (!embedding_levels) {
00891                     printf("DISKO: FriBidi error, embedding_levels malloc failed\n");
00892                     ret = false;
00893                 }
00894 
00895                 FriBidiCharType ctype = FRIBIDI_TYPE_AL;
00896                 FriBidiParType ptype = FRIBIDI_PAR_ON;
00897 
00898                 if (ret) {
00899                     if (!fribidi_get_par_embedding_levels(&ctype, len, &ptype, embedding_levels)) {
00900                         printf("DISKO: FriBidi error, fribidi_get_par_embedding_levels() failed\n");
00901                         ret = false;
00902                     }
00903                 }
00904 
00905                 FriBidiJoiningType *join_types = NULL;
00906                 if (ret) {
00907                     join_types = (FriBidiJoiningType *) malloc(sizeof(FriBidiJoiningType) * len);
00908                     if (!join_types) {
00909                         printf("DISKO: FriBidi error, join_types malloc failed\n");
00910                         ret = false;
00911                     }
00912                 }
00913 
00914                 if (ret) {
00915                     fribidi_get_joining_types(visual, len, join_types);
00916 
00917                     fribidi_join_arabic(&ctype, len, embedding_levels, join_types);
00918 
00919                     /* Actually modify the string */
00920                     fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC,
00921                             embedding_levels, len, join_types, visual);
00922                 }
00923 
00924                 /* clean up */
00925                 if (embedding_levels) free(embedding_levels);
00926                 if (join_types) free(join_types);
00927             }
00928 
00929             // convert it back to output string
00930             FriBidiStrIndex new_len = fribidi_unicode_to_charset(char_set_num, visual, len, ostr);
00931             if (new_len <= 0) {
00932                 printf("DISKO: FriBidi error, fribidi_unicode_to_charset() failed\n");
00933                 ret = false;
00934             }
00935             else {
00936                 out_str = ostr;
00937             }
00938         }
00939     }
00940 
00941     // free temp buffers
00942     if (logical) free(logical);
00943     if (visual)  free(visual);
00944     if (ostr)    free(ostr);
00945 
00946     return ret;
00947 #else
00948     // no bidi conversion lib
00949     return false;
00950 #endif
00951 }
00952 
00953 string XMLencode( const string &source ) {
00954     string dest;
00955 
00956     for( string::const_iterator iter = source.begin(); iter!=source.end(); iter++ )
00957     {
00958          unsigned char c = (unsigned char)*iter;
00959 
00960          switch( c )
00961          {
00962              case '&': dest += "&amp;"; break;
00963              case '<': dest += "&lt;"; break;
00964              case '>': dest += "&gt;"; break;
00965              case '"': dest += "&quot;"; break;
00966              case '\'': dest += "&apos;"; break;
00967 
00968              default:
00969                   dest += c;
00970                   break;
00971          }
00972     }
00973 
00974     return dest;
00975 }

Generated by doxygen