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
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/memory_.h"
00046 #include "wizard/resource_.h"
00047 #include "wizard/utility.h"
00048 #if defined(WIZARDSTOOLKIT_HAVE_MACH_O_DYLD_H)
00049 #include <mach-o/dyld.h>
00050 #endif
00051
00052
00053
00054
00055 static const char
00056 Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00057
00058
00059
00060
00061 static int
00062 IsDirectory(const char *);
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 WizardExport void AppendFileExtension(const char *extension,char *filename)
00092 {
00093 char
00094 root[MaxTextExtent];
00095
00096 assert(extension != (char *) NULL);
00097 assert(filename != (char *) NULL);
00098 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
00099 if ((*extension == '\0') || (*filename == '\0'))
00100 return;
00101 GetPathComponent(filename,RootPath,root);
00102 (void) CopyWizardString(filename,root,MaxTextExtent);
00103 (void) ConcatenateWizardString(filename,".",MaxTextExtent);
00104 (void) ConcatenateWizardString(filename,extension,MaxTextExtent);
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 WizardExport unsigned char *Base64Decode(const char *source,size_t *length)
00134 {
00135 int
00136 state;
00137
00138 register const char
00139 *p,
00140 *q;
00141
00142 register size_t
00143 i;
00144
00145 unsigned char
00146 *decode;
00147
00148 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00149 assert(source != (char *) NULL);
00150 assert(length != (size_t *) NULL);
00151 *length=0;
00152 decode=(unsigned char *) AcquireQuantumMemory(strlen(source)/4+4,
00153 3*sizeof(*decode));
00154 if (decode == (unsigned char *) NULL)
00155 return((unsigned char *) NULL);
00156 i=0;
00157 state=0;
00158 for (p=source; *p != '\0'; p++)
00159 {
00160 if (isspace((int) ((unsigned char) *p)) != 0)
00161 continue;
00162 if (*p == '=')
00163 break;
00164 q=strchr(Base64,*p);
00165 if (q == (char *) NULL)
00166 {
00167 decode=(unsigned char *) RelinquishWizardMemory(decode);
00168 return((unsigned char *) NULL);
00169 }
00170 switch (state)
00171 {
00172 case 0:
00173 {
00174 decode[i]=(q-Base64) << 2;
00175 state++;
00176 break;
00177 }
00178 case 1:
00179 {
00180 decode[i++]|=(q-Base64) >> 4;
00181 decode[i]=((q-Base64) & 0x0f) << 4;
00182 state++;
00183 break;
00184 }
00185 case 2:
00186 {
00187 decode[i++]|=(q-Base64) >> 2;
00188 decode[i]=((q-Base64) & 0x03) << 6;
00189 state++;
00190 break;
00191 }
00192 case 3:
00193 {
00194 decode[i++]|=(q-Base64);
00195 state=0;
00196 break;
00197 }
00198 }
00199 }
00200
00201
00202
00203 if (*p != '=')
00204 {
00205 if (state != 0)
00206 {
00207 decode=(unsigned char *) RelinquishWizardMemory(decode);
00208 return((unsigned char *) NULL);
00209 }
00210 }
00211 else
00212 {
00213 p++;
00214 switch (state)
00215 {
00216 case 0:
00217 case 1:
00218 {
00219
00220
00221
00222 decode=(unsigned char *) RelinquishWizardMemory(decode);
00223 return((unsigned char *) NULL);
00224 }
00225 case 2:
00226 {
00227 for ( ; *p != '\0'; p++)
00228 if (isspace((int) ((unsigned char) *p)) == 0)
00229 break;
00230 if (*p != '=')
00231 {
00232 decode=(unsigned char *) RelinquishWizardMemory(decode);
00233 return((unsigned char *) NULL);
00234 }
00235 p++;
00236 }
00237 case 3:
00238 {
00239 for ( ; *p != '\0'; p++)
00240 if (isspace((int) ((unsigned char) *p)) == 0)
00241 {
00242 decode=(unsigned char *) RelinquishWizardMemory(decode);
00243 return((unsigned char *) NULL);
00244 }
00245 if ((int) decode[i] != 0)
00246 {
00247 decode=(unsigned char *) RelinquishWizardMemory(decode);
00248 return((unsigned char *) NULL);
00249 }
00250 }
00251 }
00252 }
00253 *length=i;
00254 return(decode);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 WizardExport char *Base64Encode(const unsigned char *blob,
00288 const size_t blob_length,size_t *encode_length)
00289 {
00290 char
00291 *encode;
00292
00293 register const unsigned char
00294 *p;
00295
00296 register size_t
00297 i;
00298
00299 size_t
00300 quantum,
00301 remainder;
00302
00303 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00304 assert(blob != (const unsigned char *) NULL);
00305 assert(blob_length != 0);
00306 assert(encode_length != (size_t *) NULL);
00307 *encode_length=0;
00308 quantum=4*blob_length/3+4;
00309 encode=(char *) AcquireQuantumMemory(quantum,sizeof(*encode));
00310 if (encode == (char *) NULL)
00311 return((char *) NULL);
00312 i=0;
00313 for (p=blob; p < (blob+blob_length-2); p+=3)
00314 {
00315 encode[i++]=Base64[(int) (*p >> 2)];
00316 encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
00317 encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
00318 encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
00319 }
00320 remainder=blob_length % 3;
00321 if (remainder != 0)
00322 {
00323 ssize_t
00324 j;
00325
00326 unsigned char
00327 code[3];
00328
00329 code[0]='\0';
00330 code[1]='\0';
00331 code[2]='\0';
00332 for (j=0; j < (ssize_t) remainder; j++)
00333 code[j]=(*p++);
00334 encode[i++]=Base64[(int) (code[0] >> 2)];
00335 encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
00336 if (remainder == 1)
00337 encode[i++]='=';
00338 else
00339 encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
00340 encode[i++]='=';
00341 }
00342 *encode_length=i;
00343 encode[i++]='\0';
00344 assert(i <= quantum);
00345 return(encode);
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 WizardExport void ChopPathComponents(char *path,const size_t components)
00374 {
00375 register ssize_t
00376 i;
00377
00378 for (i=0; i < (ssize_t) components; i++)
00379 GetPathComponent(path,HeadPath,path);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 WizardExport void GetPathComponent(const char *path,PathType type,
00411 char *component)
00412 {
00413 char
00414 filesystem[MaxTextExtent],
00415 subnode[MaxTextExtent],
00416 *q;
00417
00418 register char
00419 *p;
00420
00421
00422
00423
00424 assert(path != (const char *) NULL);
00425 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",path);
00426 assert(component != (const char *) NULL);
00427 if (*path == '\0')
00428 {
00429 *component='\0';
00430 return;
00431 }
00432 (void) CopyWizardString(component,path,MaxTextExtent);
00433 *filesystem='\0';
00434 for (p=component; *p != '\0'; p++)
00435 if ((*p == ':') && (IsDirectory(path) < 0) &&
00436 (IsAccessible(path) == WizardFalse))
00437 {
00438
00439
00440
00441 (void) CopyWizardString(filesystem,component,(size_t)
00442 (p-component+1));
00443 if (IsDirectory(filesystem) < 0)
00444 *filesystem='\0';
00445 else
00446 for (q=component; *q != '\0'; q++)
00447 *q=(*++p);
00448 break;
00449 }
00450 *subnode='\0';
00451 p=component;
00452 if (*p != '\0')
00453 p=component+strlen(component)-1;
00454 if ((*p == ']') && (strchr(component,'[') != (char *) NULL))
00455 {
00456
00457
00458
00459 for (q=p-1; q > component; q--)
00460 if (*q == '[')
00461 break;
00462 if (*q == '[')
00463 {
00464 (void) CopyWizardString(subnode,q+1,MaxTextExtent);
00465 subnode[p-q-1]='\0';
00466 *q='\0';
00467 }
00468 }
00469 p=component;
00470 if (*p != '\0')
00471 for (p=component+(strlen(component)-1); p > component; p--)
00472 if (IsBasenameSeparator(*p))
00473 break;
00474 switch (type)
00475 {
00476 case FilesystemPath:
00477 {
00478 (void) CopyWizardString(component,filesystem,MaxTextExtent);
00479 break;
00480 }
00481 case RootPath:
00482 {
00483 for (p=component+(strlen(component)-1); p > component; p--)
00484 {
00485 if (IsBasenameSeparator(*p) != WizardFalse)
00486 break;
00487 if (*p == '.')
00488 break;
00489 }
00490 if (*p == '.')
00491 *p='\0';
00492 break;
00493 }
00494 case HeadPath:
00495 {
00496 *p='\0';
00497 break;
00498 }
00499 case TailPath:
00500 {
00501 if (IsBasenameSeparator(*p) != WizardFalse)
00502 (void) CopyWizardMemory((unsigned char *) component,
00503 (const unsigned char *) (p+1),strlen(p+1)+1);
00504 break;
00505 }
00506 case BasePath:
00507 {
00508 if (IsBasenameSeparator(*p) != WizardFalse)
00509 (void) CopyWizardString(component,p+1,MaxTextExtent);
00510 for (p=component+(strlen(component)-1); p > component; p--)
00511 if (*p == '.')
00512 {
00513 *p='\0';
00514 break;
00515 }
00516 break;
00517 }
00518 case ExtensionPath:
00519 {
00520 if (IsBasenameSeparator(*p) != WizardFalse)
00521 (void) CopyWizardString(component,p+1,MaxTextExtent);
00522 p=component;
00523 if (*p != '\0')
00524 for (p=component+strlen(component)-1; p > component; p--)
00525 if (*p == '.')
00526 break;
00527 *component='\0';
00528 if (*p == '.')
00529 (void) CopyWizardString(component,p+1,MaxTextExtent);
00530 p=strchr(component,'?');
00531 if (p != (char *) NULL)
00532 *p='\0';
00533 break;
00534 }
00535 case SubnodePath:
00536 {
00537 (void) CopyWizardString(component,subnode,MaxTextExtent);
00538 break;
00539 }
00540 case CanonicalPath:
00541 case UndefinedPath:
00542 break;
00543 }
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 WizardExport char **GetPathComponents(const char *path,
00572 size_t *number_components)
00573 {
00574 char
00575 **components;
00576
00577 register char
00578 *q;
00579
00580 register const char
00581 *p;
00582
00583 register ssize_t
00584 i;
00585
00586 if (path == (char *) NULL)
00587 return((char **) NULL);
00588 *number_components=1;
00589 for (p=path; *p != '\0'; p++)
00590 if (IsBasenameSeparator(*p))
00591 (*number_components)++;
00592 components=(char **) AcquireQuantumMemory((size_t) (*number_components+1),
00593 sizeof(*components));
00594 if (components == (char **) NULL)
00595 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00596 p=path;
00597 for (i=0; i < (ssize_t) *number_components; i++)
00598 {
00599 for (q=(char *) p; *q != '\0'; q++)
00600 if (IsBasenameSeparator(*q))
00601 break;
00602 components[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
00603 sizeof(*components));
00604 if (components[i] == (char *) NULL)
00605 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00606 (void) CopyWizardString(components[i],p,(size_t) (q-p+1));
00607 p=q+1;
00608 }
00609 components[i]=(char *) NULL;
00610 return(components);
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 WizardExport WizardBooleanType GetExecutionPath(char *path,const size_t extent)
00639 {
00640 *path='\0';
00641 (void) getcwd(path,(unsigned long) extent);
00642 #if defined(WIZARDSTOOLKIT_HAVE_GETPID) && defined(WIZARDSTOOLKIT_HAVE_READLINK) && defined(PATH_MAX)
00643 {
00644 char
00645 link_path[MaxTextExtent],
00646 real_path[PATH_MAX+1];
00647
00648 int
00649 length;
00650
00651 (void) FormatWizardString(link_path,MaxTextExtent,"/proc/%.20g/exe",
00652 (double) getpid());
00653 length=readlink(link_path,real_path,PATH_MAX);
00654 if (length == -1)
00655 {
00656 (void) FormatWizardString(link_path,MaxTextExtent,"/proc/%.20g/file",
00657 (double) getpid());
00658 length=readlink(link_path,real_path,PATH_MAX);
00659 }
00660 if ((length > 0) && ((size_t) length <= PATH_MAX))
00661 {
00662 real_path[length]='\0';
00663 (void) CopyWizardString(path,real_path,extent);
00664 }
00665 }
00666 #endif
00667 #if defined(WIZARDSTOOLKIT_HAVE__NSGETEXECUTABLEPATH)
00668 {
00669
00670 char
00671 executable_path[PATH_MAX << 1],
00672 real_path[PATH_MAX+1];
00673
00674 size_t
00675 length;
00676
00677 length=sizeof(executable_path);
00678 if ((_NSGetExecutablePath(executable_path,&length) == 0) &&
00679 (realpath(executable_path,real_path) != (char *) NULL))
00680 (void) CopyWizardString(path,real_path,extent);
00681 }
00682 #endif
00683 #if defined(WIZARDSTOOLKIT_HAVE_GETEXECNAME)
00684 {
00685 const char
00686 *execution_path;
00687
00688 execution_path=(const char *) getexecname();
00689 if (execution_path != (const char *) NULL)
00690 {
00691 if (*execution_path != *DirectorySeparator)
00692 (void) ConcatenateWizardString(path,DirectorySeparator,extent);
00693 (void) ConcatenateWizardString(path,execution_path,extent);
00694 }
00695 }
00696 #endif
00697 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00698 NTGetExecutionPath(path,extent);
00699 #endif
00700 #if defined(__GNU__)
00701 {
00702 char
00703 *program_name,
00704 *execution_path;
00705
00706 ssize_t
00707 count;
00708
00709 count=0;
00710 execution_path=(char *) NULL;
00711 program_name=program_invocation_name;
00712 if (*program_invocation_name != '/')
00713 {
00714 size_t
00715 extent;
00716
00717 extent=strlen(cwd)+strlen(program_name)+1;
00718 program_name=AcquireQuantumMemory(extent,sizeof(*program_name));
00719 if (program_name == (char *) NULL)
00720 program_name=program_invocation_name;
00721 else
00722 count=FormatWizardString(program_name,extent,"%s/%s",cwd,
00723 program_invocation_name);
00724 }
00725 if (count != -1)
00726 {
00727 execution_path=realpath(program_name,NULL);
00728 if (execution_path != (char *) NULL)
00729 (void) CopyWizardString(path,execution_path,extent);
00730 }
00731 if (program_name != program_invocation_name)
00732 program_name=(char *) RelinquishWizardMemory(program_name);
00733 execution_path=(char *) RelinquishWizardMemory(execution_path);
00734 }
00735 #endif
00736 return(IsAccessible(path));
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 WizardExport WizardBooleanType IsAccessible(const char *path)
00763 {
00764 int
00765 status;
00766
00767 struct stat
00768 file_info;
00769
00770 if ((path == (const char *) NULL) || (*path == '\0'))
00771 return(WizardFalse);
00772 status=stat(path,&file_info);
00773 if (status != 0)
00774 return(WizardFalse);
00775 if (S_ISREG(file_info.st_mode) == 0)
00776 return(WizardFalse);
00777 if (access(path,F_OK) != 0)
00778 return(WizardFalse);
00779 return(WizardTrue);
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 static int IsDirectory(const char *path)
00807 {
00808 #if !defined(X_OK)
00809 #define X_OK 1
00810 #endif
00811
00812 int
00813 status;
00814
00815 struct stat
00816 file_info;
00817
00818 if ((path == (const char *) NULL) || (*path == '\0'))
00819 return(WizardFalse);
00820 status=stat(path,&file_info);
00821 if (status != 0)
00822 return(-1);
00823 if (S_ISDIR(file_info.st_mode) == 0)
00824 return(0);
00825 if (access(path,X_OK) != 0)
00826 return(0);
00827 return(1);
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 WizardExport WizardBooleanType IsWizardTrue(const char *value)
00857 {
00858 if (value == (char *) NULL)
00859 return(WizardFalse);
00860 if (LocaleCompare(value,"true") == 0)
00861 return(WizardTrue);
00862 if (LocaleCompare(value,"on") == 0)
00863 return(WizardTrue);
00864 if (LocaleCompare(value,"yes") == 0)
00865 return(WizardTrue);
00866 if (LocaleCompare(value,"1") == 0)
00867 return(WizardTrue);
00868 return(WizardFalse);
00869 }
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 WizardExport const char *ParseWizardTime(const char *timestamp,time_t *target)
00898 {
00899 char
00900 *q;
00901
00902 double
00903 value;
00904
00905 ssize_t
00906 timezone;
00907
00908 register const char
00909 *p;
00910
00911 register ssize_t
00912 i;
00913
00914 static char
00915 separators[] = "--T::-:";
00916
00917 struct tm
00918 gm_time,
00919 local_time,
00920 target_time;
00921
00922 *target=time((time_t *) NULL);
00923 #if defined(WIZARDSTOOLKIT_HAVE_LOCALTIME_R)
00924 (void) localtime_r(target,&local_time);
00925 #else
00926 (void) memcpy(&local_time,localtime(target),sizeof(local_time));
00927 #endif
00928 #if defined(WIZARDSTOOLKIT_HAVE_GMTIME_R)
00929 (void) gmtime_r(target,&gm_time);
00930 #else
00931 (void) memcpy(&gm_time,gmtime(target),sizeof(gm_time));
00932 #endif
00933 timezone=(ssize_t) ((local_time.tm_min-gm_time.tm_min)/60+local_time.tm_hour-
00934 gm_time.tm_hour+24*((local_time.tm_year-gm_time.tm_year) != 0 ?
00935 (local_time.tm_year-gm_time.tm_year) : (local_time.tm_yday-
00936 gm_time.tm_yday)));
00937 (void) ResetWizardMemory(&target_time,0,sizeof(target_time));
00938 p=timestamp;
00939 for (i=0; ; i++)
00940 {
00941 value=strtod(p,&q);
00942 if (*q != separators[i])
00943 break;
00944 switch (i)
00945 {
00946 case 0: target_time.tm_year=(int) (value+0.5)-1900; break;
00947 case 1: target_time.tm_mon=(int) (value+0.5)-1; break;
00948 case 2: target_time.tm_mday=(int) (value+0.5); break;
00949 case 3: target_time.tm_hour=(int) (value+0.5); break;
00950 case 4: target_time.tm_min=(int) (value+0.5); break;
00951 case 5: target_time.tm_sec=(int) (value+0.5); break;
00952 case 6: timezone+=(int) (value+0.5); break;
00953 default: break;
00954 }
00955 p=q;
00956 if (*q == '\0')
00957 break;
00958 p++;
00959 }
00960 *target=mktime(&target_time)-3600*timezone;
00961 return(p);
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 #if defined(WIZARDSTOOLKIT_HAVE__WFOPEN)
00991 static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16)
00992 {
00993 register const unsigned char
00994 *p;
00995
00996 if (utf16 != (wchar_t *) NULL)
00997 {
00998 register wchar_t
00999 *q;
01000
01001 wchar_t
01002 c;
01003
01004
01005
01006
01007 q=utf16;
01008 for (p=utf8; *p != '\0'; p++)
01009 {
01010 if ((*p & 0x80) == 0)
01011 *q=(*p);
01012 else
01013 if ((*p & 0xE0) == 0xC0)
01014 {
01015 c=(*p);
01016 *q=(c & 0x1F) << 6;
01017 p++;
01018 if ((*p & 0xC0) != 0x80)
01019 return(0);
01020 *q|=(*p & 0x3F);
01021 }
01022 else
01023 if ((*p & 0xF0) == 0xE0)
01024 {
01025 c=(*p);
01026 *q=c << 12;
01027 p++;
01028 if ((*p & 0xC0) != 0x80)
01029 return(0);
01030 c=(*p);
01031 *q|=(c & 0x3F) << 6;
01032 p++;
01033 if ((*p & 0xC0) != 0x80)
01034 return(0);
01035 *q|=(*p & 0x3F);
01036 }
01037 else
01038 return(0);
01039 q++;
01040 }
01041 *q++='\0';
01042 return(q-utf16);
01043 }
01044
01045
01046
01047 for (p=utf8; *p != '\0'; p++)
01048 {
01049 if ((*p & 0x80) == 0)
01050 ;
01051 else
01052 if ((*p & 0xE0) == 0xC0)
01053 {
01054 p++;
01055 if ((*p & 0xC0) != 0x80)
01056 return(0);
01057 }
01058 else
01059 if ((*p & 0xF0) == 0xE0)
01060 {
01061 p++;
01062 if ((*p & 0xC0) != 0x80)
01063 return(0);
01064 p++;
01065 if ((*p & 0xC0) != 0x80)
01066 return(0);
01067 }
01068 else
01069 return(0);
01070 }
01071 return(p-utf8);
01072 }
01073
01074 static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
01075 {
01076 size_t
01077 length;
01078
01079 wchar_t
01080 *utf16;
01081
01082 length=UTF8ToUTF16(source,(wchar_t *) NULL);
01083 if (length == 0)
01084 {
01085 register ssize_t
01086 i;
01087
01088
01089
01090
01091 length=strlen(source);
01092 utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01093 if (utf16 == (wchar_t *) NULL)
01094 return((wchar_t *) NULL);
01095 for (i=0; i <= (ssize_t) length; i++)
01096 utf16[i]=source[i];
01097 return(utf16);
01098 }
01099 utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01100 if (utf16 == (wchar_t *) NULL)
01101 return((wchar_t *) NULL);
01102 length=UTF8ToUTF16(source,utf16);
01103 return(utf16);
01104 }
01105 #endif
01106
01107 WizardExport FILE *WizardOpenStream(const char *path,const char *mode)
01108 {
01109 FILE
01110 *file;
01111
01112 if ((path == (const char *) NULL) || (mode == (const char *) NULL))
01113 {
01114 errno=EINVAL;
01115 return((FILE *) NULL);
01116 }
01117 file=(FILE *) NULL;
01118 #if defined(WIZARDSTOOLKIT_HAVE__WFOPEN)
01119 {
01120 wchar_t
01121 *unicode_mode,
01122 *unicode_path;
01123
01124 unicode_path=ConvertUTF8ToUTF16(path);
01125 if (unicode_path == (wchar_t *) NULL)
01126 return((FILE *) NULL);
01127 unicode_mode=ConvertUTF8ToUTF16(mode);
01128 if (unicode_path == (wchar_t *) NULL)
01129 {
01130 unicode_path=(wchar_t *) RelinquishWizardMemory(unicode_path);
01131 return((FILE *) NULL);
01132 }
01133 file=_wfopen(unicode_path,unicode_mode);
01134 unicode_mode=(wchar_t *) RelinquishWizardMemory(unicode_mode);
01135 unicode_path=(wchar_t *) RelinquishWizardMemory(unicode_path);
01136 }
01137 #endif
01138 if (file == (FILE *) NULL)
01139 file=fopen(path,mode);
01140 return(file);
01141 }