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 #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
00052 static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
00053
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
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
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
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
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
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
00745 gettimeofday(&tv, NULL);
00746
00747
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
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
00857 FriBidiStrIndex len = in_str.length();
00858 if (len <= 0) {
00859 out_str = "";
00860 return true;
00861 }
00862
00863
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
00871 len = fribidi_charset_to_unicode(char_set_num, (char *)in_str.c_str(), len, logical);
00872
00873
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
00909 fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC,
00910 embedding_levels, len, join_types, visual);
00911 }
00912
00913
00914 if (embedding_levels) free(embedding_levels);
00915 if (join_types) free(join_types);
00916 }
00917
00918
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
00931 if (logical) free(logical);
00932 if (visual) free(visual);
00933 if (ostr) free(ostr);
00934
00935 return ret;
00936 #else
00937
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 += "&"; break;
00952 case '<': dest += "<"; break;
00953 case '>': dest += ">"; break;
00954 case '"': dest += """; break;
00955 case '\'': dest += "'"; break;
00956
00957 default:
00958 dest += c;
00959 break;
00960 }
00961 }
00962
00963 return dest;
00964 }