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

Generated by doxygen