00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
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 
00057 static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
00058 
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     
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     
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     
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     
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 
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     
00756     gettimeofday(&tv, NULL);
00757 
00758     
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     
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     
00868     FriBidiStrIndex len = in_str.length();
00869     if (len <= 0) {
00870         out_str = "";
00871         return true;
00872     }
00873 
00874     
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         
00882         len = fribidi_charset_to_unicode(char_set_num, (char *)in_str.c_str(), len, logical);
00883 
00884         
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                     
00920                     fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC,
00921                             embedding_levels, len, join_types, visual);
00922                 }
00923 
00924                 
00925                 if (embedding_levels) free(embedding_levels);
00926                 if (join_types) free(join_types);
00927             }
00928 
00929             
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     
00942     if (logical) free(logical);
00943     if (visual)  free(visual);
00944     if (ostr)    free(ostr);
00945 
00946     return ret;
00947 #else
00948     
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 += "&"; break;
00963              case '<': dest += "<"; break;
00964              case '>': dest += ">"; break;
00965              case '"': dest += """; break;
00966              case '\'': dest += "'"; break;
00967 
00968              default:
00969                   dest += c;
00970                   break;
00971          }
00972     }
00973 
00974     return dest;
00975 }