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 }