WizardsToolkit  1.0.7
string.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                  SSSSS   TTTTT  RRRR   IIIII  N   N   GGGG                  %
00007 %                  SS        T    R   R    I    NN  N  G                      %
00008 %                   SSS      T    RRRR     I    N N N  G GGG                  %
00009 %                     SS     T    R R      I    N  NN  G   G                  %
00010 %                  SSSSS     T    R  R   IIIII  N   N   GGGG                  %
00011 %                                                                             %
00012 %                                                                             %
00013 %                        Wizard's Toolkit String Methods                      %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                               March 2003                                    %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.wizards-toolkit.org/script/license.php                        %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Inc.,de declarations.
00042 */
00043 #include "wizard/studio.h"
00044 #include "wizard/blob.h"
00045 #include "wizard/cipher.h"
00046 #include "wizard/crc64.h"
00047 #include "wizard/exception.h"
00048 #include "wizard/exception-private.h"
00049 #include "wizard/memory_.h"
00050 #include "wizard/string_.h"
00051 #include "wizard/utility-private.h"
00052 
00053 /*
00054   Structure declarations.
00055 */
00056 struct _StringInfo
00057 {
00058   char
00059     path[MaxTextExtent];
00060 
00061   unsigned char
00062     *datum;
00063 
00064   size_t
00065     length;
00066 
00067   time_t
00068     timestamp;
00069 
00070   size_t
00071     signature;
00072 };
00073 
00074 /*
00075   Static declarations.
00076 */
00077 #if !defined(WIZARDSTOOLKIT_HAVE_STRCASECMP) || !defined(WIZARDSTOOLKIT_HAVE_STRNCASECMP)
00078 static const unsigned char
00079   AsciiMap[] =
00080   {
00081     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00082     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
00083     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
00084     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
00085     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
00086     0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
00087     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
00088     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
00089     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
00090     0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
00091     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
00092     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
00093     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
00094     0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
00095     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
00096     0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
00097     0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
00098     0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
00099     0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
00100     0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
00101     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
00102     0xfc, 0xfd, 0xfe, 0xff,
00103   };
00104 #endif
00105 
00106 /*
00107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00108 %                                                                             %
00109 %                                                                             %
00110 %                                                                             %
00111 %   A c q u i r e S t r i n g                                                 %
00112 %                                                                             %
00113 %                                                                             %
00114 %                                                                             %
00115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00116 %
00117 %  AcquireString() allocates memory for a string and copies the source string
00118 %  to that memory location (and returns it).
00119 %
00120 %  The format of the AcquireString method is:
00121 %
00122 %      char *AcquireString(const char *source)
00123 %
00124 %  A description of each parameter follows:
00125 %
00126 %    o source: A character string.
00127 %
00128 */
00129 WizardExport char *AcquireString(const char *source)
00130 {
00131   char
00132     *destination;
00133 
00134   size_t
00135     length;
00136 
00137   length=0;
00138   if (source != (char *) NULL)
00139     length+=strlen(source);
00140   if (~length < MaxTextExtent)
00141     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00142   destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
00143     sizeof(*destination));
00144   if (destination == (char *) NULL)
00145     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00146   *destination='\0';
00147   if (source != (char *) NULL)
00148     (void) memcpy(destination,source,length*sizeof(*destination));
00149   destination[length]='\0';
00150   return(destination);
00151 }
00152 
00153 /*
00154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00155 %                                                                             %
00156 %                                                                             %
00157 %                                                                             %
00158 %   A c q u i r e S t r i n g I n f o                                         %
00159 %                                                                             %
00160 %                                                                             %
00161 %                                                                             %
00162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00163 %
00164 %  AcquireStringInfo() allocates the StringInfo structure.
00165 %
00166 %  The format of the AcquireStringInfo method is:
00167 %
00168 %      StringInfo *AcquireStringInfo(const size_t length)
00169 %
00170 %  A description of each parameter follows:
00171 %
00172 %    o length: The string length.
00173 %
00174 */
00175 WizardExport StringInfo *AcquireStringInfo(const size_t length)
00176 {
00177   StringInfo
00178     *string_info;
00179 
00180   string_info=(StringInfo *) AcquireWizardMemory(sizeof(*string_info));
00181   if (string_info == (StringInfo *) NULL)
00182     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00183   (void) ResetWizardMemory(string_info,0,sizeof(*string_info));
00184   string_info->timestamp=time((time_t *) NULL);
00185   string_info->signature=WizardSignature;
00186   string_info->length=length;
00187   if (string_info->length != 0)
00188     {
00189       string_info->datum=(unsigned char *) NULL;
00190       if (~string_info->length >= (MaxCipherBlocksize-1))
00191         string_info->datum=(unsigned char *) AcquireQuantumMemory(
00192           string_info->length+MaxCipherBlocksize,sizeof(*string_info->datum));
00193       if (string_info->datum == (unsigned char *) NULL)
00194         ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00195     }
00196   return(string_info);
00197 }
00198 
00199 /*
00200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00201 %                                                                             %
00202 %                                                                             %
00203 %                                                                             %
00204 %   B l o b T o S t r i n g I n f o                                           %
00205 %                                                                             %
00206 %                                                                             %
00207 %                                                                             %
00208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00209 %
00210 %  BlobToStringInfo() returns the contents of a blob as a string.
00211 %
00212 %  The format of the BlobToStringInfo method is:
00213 %
00214 %      StringInfo *BlobToStringInfo(const void *blob,const size_t length)
00215 %
00216 %  A description of each parameter follows:
00217 %
00218 %    o blob: the blob.
00219 %
00220 %    o length: the length of the blob.
00221 %
00222 */
00223 WizardExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
00224 {
00225   StringInfo
00226     *string_info;
00227 
00228   string_info=AcquireStringInfo(0);
00229   string_info->length=length;
00230   if (~string_info->length >= (MaxTextExtent-1))
00231     string_info->datum=(unsigned char *) AcquireQuantumMemory(
00232       string_info->length+MaxTextExtent,sizeof(*string_info->datum));
00233   if (string_info->datum == (unsigned char *) NULL)
00234     {
00235       string_info=DestroyStringInfo(string_info);
00236       return((StringInfo *) NULL);
00237     }
00238   if (blob != (const void *) NULL)
00239     (void) memcpy(string_info->datum,blob,length);
00240   return(string_info);
00241 }
00242 
00243 /*
00244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00245 %                                                                             %
00246 %                                                                             %
00247 %                                                                             %
00248 %   C l o n e S t r i n g                                                     %
00249 %                                                                             %
00250 %                                                                             %
00251 %                                                                             %
00252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00253 %
00254 %  CloneString() allocates memory for the destination string and copies
00255 %  the source string to that memory location.
00256 %
00257 %  The format of the CloneString method is:
00258 %
00259 %      char *CloneString(char **destination,const char *source)
00260 %
00261 %  A description of each parameter follows:
00262 %
00263 %    o destination:  A pointer to a character string.
00264 %
00265 %    o source: A character string.
00266 %
00267 */
00268 WizardExport char *CloneString(char **destination,const char *source)
00269 {
00270   size_t
00271     length;
00272 
00273   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00274   WizardAssert(StringDomain,destination != (char **) NULL);
00275   if (source == (const char *) NULL)
00276     {
00277       if (*destination != (char *) NULL)
00278         *destination=DestroyString(*destination);
00279       return(*destination);
00280     }
00281   if (*destination == (char *) NULL)
00282     {
00283       *destination=AcquireString(source);
00284       return(*destination);
00285     }
00286   length=strlen(source);
00287   if (~length < MaxTextExtent)
00288     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00289   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
00290     sizeof(**destination));
00291   if (*destination == (char *) NULL)
00292     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00293   if (length != 0)
00294     (void) memcpy(*destination,source,length*sizeof(**destination));
00295   (*destination)[length]='\0';
00296   return(*destination);
00297 }
00298 
00299 /*
00300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00301 %                                                                             %
00302 %                                                                             %
00303 %                                                                             %
00304 %   C l o n e S t r i n g I n f o                                             %
00305 %                                                                             %
00306 %                                                                             %
00307 %                                                                             %
00308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00309 %
00310 %  CloneStringInfo() clones a copy of the StringInfo structure.
00311 %
00312 %  The format of the CloneStringInfo method is:
00313 %
00314 %      StringInfo *CloneStringInfo(const StringInfo *string_info)
00315 %
00316 %  A description of each parameter follows:
00317 %
00318 %    o string_info: The string info.
00319 %
00320 */
00321 WizardExport StringInfo *CloneStringInfo(const StringInfo *string_info)
00322 {
00323   StringInfo
00324     *clone_info;
00325 
00326   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00327   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
00328   WizardAssert(StringDomain,string_info->signature == WizardSignature);
00329   clone_info=AcquireStringInfo(string_info->length);
00330   if (string_info->length != 0)
00331     (void) memcpy(clone_info->datum,string_info->datum,string_info->length+
00332       MaxCipherBlocksize);
00333   return(clone_info);
00334 }
00335 
00336 /*
00337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00338 %                                                                             %
00339 %                                                                             %
00340 %                                                                             %
00341 %   C o m p a r e S t r i n g I n f o                                         %
00342 %                                                                             %
00343 %                                                                             %
00344 %                                                                             %
00345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00346 %
00347 %  CompareStringInfo() compares the two datums target and source.  It returns
00348 %  an integer less than, equal to, or greater than zero if target is found,
00349 %  respectively, to be less than, to match, or be greater than source.
00350 %
00351 %  The format of the CompareStringInfo method is:
00352 %
00353 %      int CompareStringInfo(const StringInfo *target,const StringInfo *source)
00354 %
00355 %  A description of each parameter follows:
00356 %
00357 %    o target: The target string.
00358 %
00359 %    o source: The source string.
00360 %
00361 */
00362 
00363 static inline size_t WizardMin(const size_t x,const size_t y)
00364 {
00365   if (x < y)
00366     return(x);
00367   return(y);
00368 }
00369 
00370 WizardExport int CompareStringInfo(const StringInfo *target,
00371   const StringInfo *source)
00372 {
00373   int
00374     status;
00375 
00376   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00377   WizardAssert(StringDomain,target != (StringInfo *) NULL);
00378   WizardAssert(StringDomain,target->signature == WizardSignature);
00379   WizardAssert(StringDomain,source != (StringInfo *) NULL);
00380   WizardAssert(StringDomain,source->signature == WizardSignature);
00381   status=memcmp(target->datum,source->datum,WizardMin(target->length,
00382     source->length));
00383   if (status != 0)
00384     return(status);
00385   if (target->length == source->length)
00386     return(0);
00387   return(target->length < source->length ? -1 : 1);
00388 }
00389 
00390 /*
00391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00392 %                                                                             %
00393 %                                                                             %
00394 %                                                                             %
00395 %   C o n c a t e n a t e S t r i n g                                         %
00396 %                                                                             %
00397 %                                                                             %
00398 %                                                                             %
00399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00400 %
00401 %  ConcatenateString() appends a copy of string source, including the
00402 %  terminating null character, to the end of string destination.
00403 %
00404 %  The format of the ConcatenateString method is:
00405 %
00406 %      WizardBooleanType ConcatenateString(char **destination,
00407 %        const char *source)
00408 %
00409 %  A description of each parameter follows:
00410 %
00411 %    o destination:  A pointer to a character string.
00412 %
00413 %    o source: A character string.
00414 %
00415 */
00416 WizardExport WizardBooleanType ConcatenateString(char **destination,
00417   const char *source)
00418 {
00419   size_t
00420     destination_length,
00421     length,
00422     source_length;
00423 
00424   assert(destination != (char **) NULL);
00425   if (source == (const char *) NULL)
00426     return(WizardTrue);
00427   if (*destination == (char *) NULL)
00428     {
00429       *destination=AcquireString(source);
00430       return(WizardTrue);
00431     }
00432   destination_length=strlen(*destination);
00433   source_length=strlen(source);
00434   length=destination_length;
00435   if (~length < source_length)
00436     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00437   length+=source_length;
00438   if (~length < MaxTextExtent)
00439     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00440   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
00441     sizeof(**destination));
00442   if (*destination == (char *) NULL)
00443     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00444   if (source_length != 0)
00445     (void) memcpy((*destination)+destination_length,source,source_length);
00446   (*destination)[length]='\0';
00447   return(WizardTrue);
00448 }
00449 
00450 /*
00451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00452 %                                                                             %
00453 %                                                                             %
00454 %                                                                             %
00455 %   C o n c a t e n a t e W i z a r d S t r i n g                             %
00456 %                                                                             %
00457 %                                                                             %
00458 %                                                                             %
00459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00460 %
00461 %  ConcatenateWizardString() concatenates the source string to the destination
00462 %  string.  The destination buffer is always null-terminated even if the
00463 %  string must be truncated.
00464 %
00465 %  The format of the ConcatenateWizardString method is:
00466 %
00467 %      size_t ConcatenateWizardString(char *destination,const char *source,
00468 %        const size_t length)
00469 %
00470 %  A description of each parameter follows:
00471 %
00472 %    o destination: The destination string.
00473 %
00474 %    o source: The source string.
00475 %
00476 %    o length: The length of the destination string.
00477 %
00478 */
00479 WizardExport size_t ConcatenateWizardString(char *destination,
00480   const char *source,const size_t length)
00481 {
00482 #if !defined(WIZARDSTOOLKIT_HAVE_STRLCAT)
00483   register char
00484     *q;
00485 
00486   register const char
00487     *p;
00488 
00489   register size_t
00490     i;
00491 
00492   size_t
00493     count;
00494 
00495   assert(destination != (char *) NULL);
00496   assert(source != (const char *) NULL);
00497   assert(length >= 1);
00498   p=source;
00499   q=destination;
00500   i=length;
00501   while ((i-- != 0) && (*q != '\0'))
00502     q++;
00503   count=(size_t) (q-destination);
00504   i=length-count;
00505   if (i == 0)
00506     return(count+strlen(p));
00507   while (*p != '\0')
00508   {
00509     if (i != 1)
00510       {
00511         *q++=(*p);
00512         i--;
00513       }
00514     p++;
00515   }
00516   *q='\0';
00517   return(count+(p-source));
00518 #else
00519   return(strlcat(destination,source,length));
00520 #endif
00521 }
00522 
00523 /*
00524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00525 %                                                                             %
00526 %                                                                             %
00527 %                                                                             %
00528 %   C o n f i g u r e F i l e T o S t r i n g I n f o                         %
00529 %                                                                             %
00530 %                                                                             %
00531 %                                                                             %
00532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00533 %
00534 %  ConfigureFileToStringInfo() returns the contents of a configure file as a
00535 %  string.
00536 %
00537 %  The format of the ConfigureFileToStringInfo method is:
00538 %
00539 %      StringInfo *ConfigureFileToStringInfo(const char *filename)
00540 %        ExceptionInfo *exception)
00541 %
00542 %  A description of each parameter follows:
00543 %
00544 %    o filename: The filename.
00545 %
00546 */
00547 WizardExport StringInfo *ConfigureFileToStringInfo(const char *filename)
00548 {
00549   char
00550     *string;
00551 
00552   int
00553     file;
00554 
00555   WizardOffsetType
00556     offset;
00557 
00558   size_t
00559     length;
00560 
00561   StringInfo
00562     *string_info;
00563 
00564   void
00565     *map;
00566 
00567   WizardAssert(StringDomain,filename != (const char *) NULL);
00568   file=open_utf8(filename,O_RDONLY | O_BINARY,0);
00569   if (file == -1)
00570     return((StringInfo *) NULL);
00571   offset=(WizardOffsetType) lseek(file,0,SEEK_END);
00572   if ((offset < 0) || (offset != (WizardOffsetType) ((ssize_t) offset)))
00573     {
00574       file=close(file)-1;
00575       return((StringInfo *) NULL);
00576     }
00577   length=(size_t) offset;
00578   string=(char *) NULL;
00579   if (~length >= (MaxCipherBlocksize-1))
00580     string=(char *) AcquireQuantumMemory(length+MaxCipherBlocksize,
00581       sizeof(*string));
00582   if (string == (char *) NULL)
00583     {
00584       file=close(file)-1;
00585       return((StringInfo *) NULL);
00586     }
00587   map=MapBlob(file,ReadMode,0,length);
00588   if (map != (void *) NULL)
00589     {
00590       (void) memcpy(string,map,length);
00591       (void) UnmapBlob(map,length);
00592     }
00593   else
00594     {
00595       register size_t
00596         i;
00597 
00598       ssize_t
00599         count;
00600 
00601       (void) lseek(file,0,SEEK_SET);
00602       for (i=0; i < length; i+=count)
00603       {
00604         count=read(file,string+i,(size_t) WizardMin(length-i,(size_t)
00605           SSIZE_MAX));
00606         if (count <= 0)
00607           {
00608             count=0;
00609             if (errno != EINTR)
00610               break;
00611           }
00612       }
00613       if (i < length)
00614         {
00615           file=close(file)-1;
00616           string=(char *) RelinquishWizardMemory(string);
00617           return((StringInfo *) NULL);
00618         }
00619     }
00620   string[length]='\0';
00621   file=close(file)-1;
00622   string_info=AcquireStringInfo(0);
00623   (void) CopyWizardString(string_info->path,filename,MaxTextExtent);
00624   string_info->length=length;
00625   string_info->datum=(unsigned char *) string;
00626   return(string_info);
00627 }
00628 
00629 /*
00630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00631 %                                                                             %
00632 %                                                                             %
00633 %                                                                             %
00634 %   C o n s t a n t S t r i n g                                               %
00635 %                                                                             %
00636 %                                                                             %
00637 %                                                                             %
00638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00639 %
00640 %  ConstantString() allocates memory for a string and copies the source string
00641 %  to that memory location (and returns it).  Use it for strings that you do
00642 %  do not expect to change over its lifetime.
00643 %
00644 %  The format of the ConstantString method is:
00645 %
00646 %      char *ConstantString(const char *source)
00647 %
00648 %  A description of each parameter follows:
00649 %
00650 %    o source: A character string.
00651 %
00652 */
00653 WizardExport char *ConstantString(const char *source)
00654 {
00655   char
00656     *destination;
00657 
00658   size_t
00659     length;
00660 
00661   length=0;
00662   if (source != (char *) NULL)
00663     length+=strlen(source);
00664   destination=(char *) NULL;
00665   if (~length >= 1UL)
00666     destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
00667   if (destination == (char *) NULL)
00668     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00669   *destination='\0';
00670   if (source != (char *) NULL)
00671     (void) memcpy(destination,source,length*sizeof(*destination));
00672   destination[length]='\0';
00673   return(destination);
00674 }
00675 
00676 /*
00677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00678 %                                                                             %
00679 %                                                                             %
00680 %                                                                             %
00681 %   C o n c a t e n a t e S t r i n g I n f o                                 %
00682 %                                                                             %
00683 %                                                                             %
00684 %                                                                             %
00685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00686 %
00687 %  ConcatenateStringInfo() concatenates the source string to the destination
00688 %  string.
00689 %
00690 %  The format of the ConcatentateStringInfo method is:
00691 %
00692 %      void ConcatentateStringInfo(StringInfo *string_info,
00693 %        const StringInfo *source)
00694 %
00695 %  A description of each parameter follows:
00696 %
00697 %    o string_info: The string info.
00698 %
00699 %    o source: The source string.
00700 %
00701 */
00702 WizardExport void ConcatenateStringInfo(StringInfo *string_info,
00703   const StringInfo *source)
00704 {
00705   size_t
00706     length;
00707 
00708   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00709   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
00710   WizardAssert(StringDomain,string_info->signature == WizardSignature);
00711   WizardAssert(StringDomain,source != (const StringInfo *) NULL);
00712   length=string_info->length;
00713   if (~length < source->length)
00714     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00715   SetStringInfoLength(string_info,string_info->length+source->length);
00716   (void) memcpy(string_info->datum+length,source->datum,source->length);
00717 }
00718 
00719 /*
00720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00721 %                                                                             %
00722 %                                                                             %
00723 %                                                                             %
00724 %   C o p y W i z a r d S t r i n g                                           %
00725 %                                                                             %
00726 %                                                                             %
00727 %                                                                             %
00728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00729 %
00730 %  CopyWizardString() copies the source string to the destination string.  The
00731 %  destination buffer is always null-terminated even if the string must be
00732 %  truncated.  The return value is the minimum of the  ource string length
00733 %  or the length parameter.
00734 %
00735 %  The format of the CopyWizardString method is:
00736 %
00737 %      size_t CopyWizardString(const char *destination,char *source,
00738 %        const size_t length)
00739 %
00740 %  A description of each parameter follows:
00741 %
00742 %    o destination: The destination string.
00743 %
00744 %    o source: The source string.
00745 %
00746 %    o length: The length of the destination string.
00747 %
00748 */
00749 WizardExport size_t CopyWizardString(char *destination,const char *source,
00750   const size_t length)
00751 {
00752   register char
00753     *q;
00754 
00755   register const char
00756     *p;
00757 
00758   register size_t
00759     n;
00760 
00761   if (source == (const char *) NULL)
00762     return(0);
00763   p=source;
00764   q=destination;
00765   for (n=length; n > 4; n-=4)
00766   {
00767     *q=(*p++);
00768     if (*q == '\0')
00769       return((size_t) (p-source-1));
00770     q++;
00771     *q=(*p++);
00772     if (*q == '\0')
00773       return((size_t) (p-source-1));
00774     q++;
00775     *q=(*p++);
00776     if (*q == '\0')
00777       return((size_t) (p-source-1));
00778     q++;
00779     *q=(*p++);
00780     if (*q == '\0')
00781       return((size_t) (p-source-1));
00782     q++;
00783   }
00784   if (n != 0)
00785     for (n--; n != 0; n--)
00786     {
00787       *q=(*p++);
00788       if (*q == '\0')
00789         return((size_t) (p-source-1));
00790       q++;
00791     }
00792   if (length != 0)
00793     *q='\0';
00794   return((size_t) (p-source-1));
00795 }
00796 
00797 /*
00798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00799 %                                                                             %
00800 %                                                                             %
00801 %                                                                             %
00802 %   D e s t r o y S t r i n g                                                 %
00803 %                                                                             %
00804 %                                                                             %
00805 %                                                                             %
00806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00807 %
00808 %  DestroyString() destorys memory associated with a string.
00809 %
00810 %  The format of the DestroyString method is:
00811 %
00812 %      char *DestroyString(char *string)
00813 %
00814 %  A description of each parameter follows:
00815 %
00816 %    o string: The string.
00817 %
00818 */
00819 WizardExport char *DestroyString(char *string)
00820 {
00821   return((char *) RelinquishWizardMemory(string));
00822 }
00823 
00824 /*
00825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00826 %                                                                             %
00827 %                                                                             %
00828 %                                                                             %
00829 %   D e s t r o y S t r i n g I n f o                                         %
00830 %                                                                             %
00831 %                                                                             %
00832 %                                                                             %
00833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00834 %
00835 %  DestroyStringInfo() zeros memory associated with the StringInfo structure.
00836 %
00837 %  The format of the DestroyStringInfo method is:
00838 %
00839 %      StringInfo *DestroyStringInfo(StringInfo *string_info)
00840 %
00841 %  A description of each parameter follows:
00842 %
00843 %    o string_info: The string info.
00844 %
00845 */
00846 WizardExport StringInfo *DestroyStringInfo(StringInfo *string_info)
00847 {
00848   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00849   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
00850   WizardAssert(StringDomain,string_info->signature == WizardSignature);
00851   if (string_info->datum != (unsigned char *) NULL)
00852     string_info->datum=(unsigned char *) RelinquishWizardMemory(
00853       string_info->datum);
00854   string_info->signature=(~WizardSignature);
00855   string_info=(StringInfo *) RelinquishWizardMemory(string_info);
00856   return(string_info);
00857 }
00858 
00859 /*
00860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00861 %                                                                             %
00862 %                                                                             %
00863 %                                                                             %
00864 %   D e s t r o y S t r i n g L i s t                                         %
00865 %                                                                             %
00866 %                                                                             %
00867 %                                                                             %
00868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00869 %
00870 %  DestroyStringList() zeros memory associated with a string list.
00871 %
00872 %  The format of the DestroyStringList method is:
00873 %
00874 %      char **DestroyStringList(char **list)
00875 %
00876 %  A description of each parameter follows:
00877 %
00878 %    o list: The string list.
00879 %
00880 */
00881 WizardExport char **DestroyStringList(char **list)
00882 {
00883   register ssize_t
00884     i;
00885 
00886   assert(list != (char **) NULL);
00887   for (i=0; list[i] != (char *) NULL; i++)
00888     list[i]=DestroyString(list[i]);
00889   list=(char **) RelinquishWizardMemory(list);
00890   return(list);
00891 }
00892 
00893 /*
00894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00895 %                                                                             %
00896 %                                                                             %
00897 %                                                                             %
00898 %   F i l e T o S t r i n g                                                   %
00899 %                                                                             %
00900 %                                                                             %
00901 %                                                                             %
00902 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00903 %
00904 %  FileToString() returns the contents of a file as a string.
00905 %
00906 %  The format of the FileToString method is:
00907 %
00908 %      char *FileToString(const char *filename,const size_t extent,
00909 %        ExceptionInfo *exception)
00910 %
00911 %  A description of each parameter follows:
00912 %
00913 %    o filename: The filename.
00914 %
00915 %    o extent: Maximum length of the string.
00916 %
00917 %    o exception: Return any errors or warnings in this structure.
00918 %
00919 */
00920 WizardExport char *FileToString(const char *filename,const size_t extent,
00921   ExceptionInfo *exception)
00922 {
00923   size_t
00924     length;
00925 
00926   WizardAssert(StringDomain,filename != (const char *) NULL);
00927   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
00928   WizardAssert(StringDomain,exception != (ExceptionInfo *) NULL);
00929   return((char *) FileToBlob(filename,extent,&length,exception));
00930 }
00931 
00932 /*
00933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00934 %                                                                             %
00935 %                                                                             %
00936 %                                                                             %
00937 %   F i l e T o S t r i n g I n f o                                           %
00938 %                                                                             %
00939 %                                                                             %
00940 %                                                                             %
00941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00942 %
00943 %  FileToStringInfo() returns the contents of a file as a string.
00944 %
00945 %  The format of the FileToStringInfo method is:
00946 %
00947 %      StringInfo *FileToStringInfo(const char *filename,const size_t extent,
00948 %        ExceptionInfo *exception)
00949 %
00950 %  A description of each parameter follows:
00951 %
00952 %    o filename: The filename.
00953 %
00954 %    o extent: Maximum length of the string.
00955 %
00956 %    o exception: Return any errors or warnings in this structure.
00957 %
00958 */
00959 WizardExport StringInfo *FileToStringInfo(const char *filename,
00960   const size_t extent,ExceptionInfo *exception)
00961 {
00962   StringInfo
00963     *string_info;
00964 
00965   WizardAssert(StringDomain,filename != (const char *) NULL);
00966   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
00967   WizardAssert(StringDomain,exception != (ExceptionInfo *) NULL);
00968   string_info=AcquireStringInfo(0);
00969   (void) CopyWizardString(string_info->path,filename,MaxTextExtent);
00970   string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
00971   if (string_info->datum == (unsigned char *) NULL)
00972     {
00973       string_info=DestroyStringInfo(string_info);
00974       return((StringInfo *) NULL);
00975     }
00976   return(string_info);
00977 }
00978 
00979 /*
00980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00981 %                                                                             %
00982 %                                                                             %
00983 %                                                                             %
00984 %  F o r m a t W i z a r d S i z e                                            %
00985 %                                                                             %
00986 %                                                                             %
00987 %                                                                             %
00988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00989 %
00990 %  FormatWizardSize() converts a size to a human readable format, for example,
00991 %  14k, 234m, 2.7g, or 3.0t.  Scaling is done by repetitively dividing by
00992 %  1000.
00993 %
00994 %  The format of the FormatWizardSize method is:
00995 %
00996 %      ssize_t FormatWizardSize(const WizardSizeType size,char *format)
00997 %
00998 %  A description of each parameter follows:
00999 %
01000 %    o size:  convert this size to a human readable format.
01001 %
01002 %    o bi:  use power of two rather than power of ten.
01003 %
01004 %    o format:  human readable format.
01005 %
01006 */
01007 WizardExport ssize_t FormatWizardSize(const WizardSizeType size,
01008   const WizardBooleanType bi,char *format)
01009 {
01010   const char
01011     **units;
01012 
01013   double
01014     bytes,
01015     length;
01016 
01017   ssize_t
01018     count;
01019 
01020   register ssize_t
01021     i,
01022     j;
01023 
01024   static const char
01025     *bi_units[] =
01026     {
01027       "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
01028     },
01029     *traditional_units[] =
01030     {
01031       "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
01032     };
01033 
01034   bytes=1000.0;
01035   units=traditional_units;
01036   if (bi != WizardFalse)
01037     {
01038       bytes=1024.0;
01039       units=bi_units;
01040     }
01041 #if defined(_MSC_VER) && (_MSC_VER == 1200)
01042   length=(double) ((WizardOffsetType) size);
01043 #else
01044   length=(double) size;
01045 #endif
01046   for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
01047     length/=bytes;
01048   for (j=2; j < 12; j++)
01049   {
01050     count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
01051       units[i]);
01052     if (strchr(format,'+') == (char *) NULL)
01053       break;
01054   }
01055   return(count);
01056 }
01057 
01058 /*
01059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01060 %                                                                             %
01061 %                                                                             %
01062 %                                                                             %
01063 %  F o r m a t W i z a r d T i m e                                            %
01064 %                                                                             %
01065 %                                                                             %
01066 %                                                                             %
01067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01068 %
01069 %  FormatWizardTime() returns the specified time in the Internet date/time
01070 %  format and the length of the timestamp.
01071 %
01072 %  The format of the FormatWizardTime method is:
01073 %
01074 %      ssize_t FormatWizardTime(const time_t time,const size_t length,
01075 %        char *timestamp)
01076 %
01077 %  A description of each parameter follows.
01078 %
01079 %   o time:  the time since the Epoch (00:00:00 UTC, January 1, 1970),
01080 %     measured in seconds.
01081 %
01082 %   o length: The maximum length of the string.
01083 %
01084 %   o timestamp:  Return the Internet date/time here.
01085 %
01086 */
01087 WizardExport ssize_t FormatWizardTime(const time_t time,const size_t length,
01088   char *timestamp)
01089 {
01090   ssize_t
01091     count;
01092 
01093   struct tm
01094     gm_time,
01095     local_time;
01096 
01097   time_t
01098     timezone;
01099 
01100   assert(timestamp != (char *) NULL);
01101 #if defined(WIZARDSTOOLKIT_HAVE_LOCALTIME_R)
01102   (void) localtime_r(&time,&local_time);
01103 #else
01104   {
01105     struct tm
01106       *my_time;
01107 
01108     my_time=localtime(&time);
01109     if (my_time != (struct tm *) NULL)
01110       (void) memcpy(&local_time,my_time,sizeof(local_time));
01111   }
01112 #endif
01113 #if defined(WIZARDSTOOLKIT_HAVE_GMTIME_R)
01114   (void) gmtime_r(&time,&gm_time);
01115 #else
01116   {
01117     struct tm
01118       *my_time;
01119 
01120     my_time=gmtime(&time);
01121     if (my_time != (struct tm *) NULL)
01122       (void) memcpy(&gm_time,my_time,sizeof(gm_time));
01123   }
01124 #endif
01125   timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
01126     local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
01127     gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
01128     (local_time.tm_yday-gm_time.tm_yday)));
01129   count=FormatLocaleString(timestamp,length,
01130     "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
01131     local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
01132     local_time.tm_min,local_time.tm_sec,(long) timezone);
01133   return(count);
01134 }
01135 
01136 /*
01137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01138 %                                                                             %
01139 %                                                                             %
01140 %                                                                             %
01141 %   G e t E n v i r o n m e n t V a l u e                                     %
01142 %                                                                             %
01143 %                                                                             %
01144 %                                                                             %
01145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01146 %
01147 %  GetEnvironmentValue() returns the environment string that matches the
01148 %  specified name.
01149 %
01150 %  The format of the GetEnvironmentValue method is:
01151 %
01152 %      char *GetEnvironmentValue(const char *name)
01153 %
01154 %  A description of each parameter follows:
01155 %
01156 %    o name: the environment name.
01157 %
01158 */
01159 WizardExport char *GetEnvironmentValue(const char *name)
01160 {
01161   const char
01162     *environment;
01163 
01164   environment=getenv(name);
01165   if (environment == (const char *) NULL)
01166     return((char *) NULL);
01167   return(ConstantString(environment));
01168 }
01169 
01170 /*
01171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01172 %                                                                             %
01173 %                                                                             %
01174 %                                                                             %
01175 %   G e t S t r i n g I n f o C R C                                           %
01176 %                                                                             %
01177 %                                                                             %
01178 %                                                                             %
01179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01180 %
01181 %  GetStringInfoCRC() returns the CRC-64 of a string.
01182 %
01183 %  The format of the GetStringInfo method is:
01184 %
01185 %      WizardSizeType GetStringInfo(const StringInfo *string_info)
01186 %
01187 %  A description of each parameter follows:
01188 %
01189 %    o string_info: The string info.
01190 %
01191 */
01192 WizardExport WizardSizeType GetStringInfoCRC(const StringInfo *string_info)
01193 {
01194   CRC64Info
01195     *crc_info;
01196 
01197   WizardSizeType
01198     crc;
01199 
01200   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01201   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01202   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01203   crc_info=AcquireCRC64Info();
01204   InitializeCRC64(crc_info);
01205   UpdateCRC64(crc_info,string_info);
01206   FinalizeCRC64(crc_info);
01207   crc=GetCRC64CyclicRedundancyCheck(crc_info);
01208   crc_info=DestroyCRC64Info(crc_info);
01209   return(crc);
01210 }
01211 
01212 /*
01213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01214 %                                                                             %
01215 %                                                                             %
01216 %                                                                             %
01217 %   G e t S t r i n g I n f o D a t u m                                       %
01218 %                                                                             %
01219 %                                                                             %
01220 %                                                                             %
01221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01222 %
01223 %  GetStringInfoDatum() returns the datum associated with the string.
01224 %
01225 %  The format of the GetStringInfoDatum method is:
01226 %
01227 %      unsigned char *GetStringInfoDatum(const StringInfo *string_info)
01228 %
01229 %  A description of each parameter follows:
01230 %
01231 %    o string_info: the string info.
01232 %
01233 */
01234 WizardExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
01235 {
01236   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01237   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01238   return(string_info->datum);
01239 }
01240 
01241 /*
01242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01243 %                                                                             %
01244 %                                                                             %
01245 %                                                                             %
01246 %   G e t S t r i n g I n f o L e n g t h                                     %
01247 %                                                                             %
01248 %                                                                             %
01249 %                                                                             %
01250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01251 %
01252 %  GetStringInfoLength() returns the string length.
01253 %
01254 %  The format of the GetStringInfoLength method is:
01255 %
01256 %      size_t GetStringInfoLength(const StringInfo *string_info)
01257 %
01258 %  A description of each parameter follows:
01259 %
01260 %    o string_info: the string info.
01261 %
01262 */
01263 WizardExport size_t GetStringInfoLength(const StringInfo *string_info)
01264 {
01265   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01266   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01267   return(string_info->length);
01268 }
01269 
01270 /*
01271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01272 %                                                                             %
01273 %                                                                             %
01274 %                                                                             %
01275 %   G e t S t r i n g I n f o P a t h                                         %
01276 %                                                                             %
01277 %                                                                             %
01278 %                                                                             %
01279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01280 %
01281 %  GetStringInfoPath() returns the path associated with the string.
01282 %
01283 %  The format of the GetStringInfoPath method is:
01284 %
01285 %      const char *GetStringInfoPath(const StringInfo *string_info)
01286 %
01287 %  A description of each parameter follows:
01288 %
01289 %    o string_info: the string info.
01290 %
01291 */
01292 WizardExport const char *GetStringInfoPath(const StringInfo *string_info)
01293 {
01294   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01295   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01296   return(string_info->path);
01297 }
01298 
01299 /*
01300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01301 %                                                                             %
01302 %                                                                             %
01303 %                                                                             %
01304 %   H e x S t r i n g T o S t r i n g I n f o                                 %
01305 %                                                                             %
01306 %                                                                             %
01307 %                                                                             %
01308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01309 %
01310 %  HexStringToStringInfo() converts a string to a StringInfo type.
01311 %
01312 %  The format of the HexStringToStringInfo method is:
01313 %
01314 %      StringInfo *HexStringToStringInfo(const char *string)
01315 %
01316 %  A description of each parameter follows:
01317 %
01318 %    o string:  The string.
01319 %
01320 */
01321 WizardExport StringInfo *HexStringToStringInfo(const char *string)
01322 {
01323   register const unsigned char
01324     *p;
01325 
01326   register ssize_t
01327     i;
01328 
01329   register unsigned char
01330     *q;
01331 
01332   unsigned char
01333     hex_digits[256];
01334 
01335   StringInfo
01336     *string_info;
01337 
01338   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01339   WizardAssert(StringDomain,string != (const char *) NULL);
01340   string_info=AcquireStringInfo(strlen(string)/2);
01341   (void) ResetWizardMemory(hex_digits,0,sizeof(hex_digits));
01342   hex_digits[(int) '0']=0;
01343   hex_digits[(int) '1']=1;
01344   hex_digits[(int) '2']=2;
01345   hex_digits[(int) '3']=3;
01346   hex_digits[(int) '4']=4;
01347   hex_digits[(int) '5']=5;
01348   hex_digits[(int) '6']=6;
01349   hex_digits[(int) '7']=7;
01350   hex_digits[(int) '8']=8;
01351   hex_digits[(int) '9']=9;
01352   hex_digits[(int) 'a']=10;
01353   hex_digits[(int) 'b']=11;
01354   hex_digits[(int) 'c']=12;
01355   hex_digits[(int) 'd']=13;
01356   hex_digits[(int) 'e']=14;
01357   hex_digits[(int) 'f']=15;
01358   hex_digits[(int) 'A']=10;
01359   hex_digits[(int) 'B']=11;
01360   hex_digits[(int) 'C']=12;
01361   hex_digits[(int) 'D']=13;
01362   hex_digits[(int) 'E']=14;
01363   hex_digits[(int) 'F']=15;
01364   p=(unsigned char *) string;
01365   q=string_info->datum;
01366   for (i=0; i < (ssize_t) string_info->length; i++)
01367   {
01368     *q=hex_digits[*p++] << 4;
01369     *q|=hex_digits[*p++];
01370     q++;
01371   }
01372   return(string_info);
01373 }
01374 
01375 /*
01376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01377 %                                                                             %
01378 %                                                                             %
01379 %                                                                             %
01380 +   I n t e r p r e t S i P r e f i x V a l u e                               %
01381 %                                                                             %
01382 %                                                                             %
01383 %                                                                             %
01384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01385 %
01386 %  InterpretSiPrefixValue() converts the initial portion of the string to a
01387 %  double representation.  It also recognizes SI prefixes (e.g. B, KB, MiB,
01388 %  etc.).
01389 %
01390 %  The format of the InterpretSiPrefixValue method is:
01391 %
01392 %      double InterpretSiPrefixValue(const char *value,char **sentinal)
01393 %
01394 %  A description of each parameter follows:
01395 %
01396 %    o value: the string value.
01397 %
01398 %    o sentinal:  if sentinal is not NULL, return a pointer to the character
01399 %      after the last character used in the conversion.
01400 %
01401 */
01402 WizardExport double InterpretSiPrefixValue(const char *restrict string,
01403   char **restrict sentinal)
01404 {
01405   char
01406     *q;
01407 
01408   double
01409     value;
01410 
01411   value=InterpretSiPrefixValue(string,&q);
01412   if (q != string)
01413     {
01414       if ((*q >= 'E') && (*q <= 'z'))
01415         {
01416           double
01417             e;
01418 
01419           switch ((int) ((unsigned char) *q))
01420           {
01421             case 'y': e=(-24.0); break;
01422             case 'z': e=(-21.0); break;
01423             case 'a': e=(-18.0); break;
01424             case 'f': e=(-15.0); break;
01425             case 'p': e=(-12.0); break;
01426             case 'n': e=(-9.0); break;
01427             case 'u': e=(-6.0); break;
01428             case 'm': e=(-3.0); break;
01429             case 'c': e=(-2.0); break;
01430             case 'd': e=(-1.0); break;
01431             case 'h': e=2.0; break;
01432             case 'k': e=3.0; break;
01433             case 'K': e=3.0; break;
01434             case 'M': e=6.0; break;
01435             case 'G': e=9.0; break;
01436             case 'T': e=12.0; break;
01437             case 'P': e=15.0; break;
01438             case 'E': e=18.0; break;
01439             case 'Z': e=21.0; break;
01440             case 'Y': e=24.0; break;
01441             default: e=0.0; break;
01442           }
01443           if (e >= WizardEpsilon)
01444             {
01445               if (q[1] == 'i')
01446                 {
01447                   value*=pow(2.0,e/0.3);
01448                   q+=2;
01449                 }
01450               else
01451                 {
01452                   value*=pow(10.0,e);
01453                   q++;
01454                 }
01455             }
01456         }
01457       if (*q == 'B')
01458         q++;
01459     }
01460   if (sentinal != (char **) NULL)
01461     *sentinal=q;
01462   return(value);
01463 }
01464 
01465 /*
01466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01467 %                                                                             %
01468 %                                                                             %
01469 %                                                                             %
01470 %   L o c a l e C o m p a r e                                                 %
01471 %                                                                             %
01472 %                                                                             %
01473 %                                                                             %
01474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01475 %
01476 %  LocaleCompare() performs a case-insensitive comparison of two strings
01477 %  byte-by-byte, according to the ordering of the current locale encoding.
01478 %  LocaleCompare returns an integer greater than, equal to, or less than 0,
01479 %  if the string pointed to by p is greater than, equal to, or less than the
01480 %  string pointed to by q respectively.  The sign of a non-zero return value
01481 %  is determined by the sign of the difference between the values of the first
01482 %  pair of bytes that differ in the strings being compared.
01483 %
01484 %  The format of the LocaleCompare method is:
01485 %
01486 %      int LocaleCompare(const char *p,const char *q)
01487 %
01488 %  A description of each parameter follows:
01489 %
01490 %    o p: A pointer to a character string.
01491 %
01492 %    o q: A pointer to a character string to compare to p.
01493 %
01494 */
01495 WizardExport int LocaleCompare(const char *p,const char *q)
01496 {
01497   if ((p == (char *) NULL) && (q == (char *) NULL))
01498     return(0);
01499   if (p == (char *) NULL)
01500     return(-1);
01501   if (q == (char *) NULL)
01502     return(1);
01503 #if defined(WIZARDSTOOLKIT_HAVE_STRCASECMP)
01504   return(strcasecmp(p,q));
01505 #else
01506   {
01507     register int
01508       c,
01509       d;
01510 
01511     for ( ; ; )
01512     {
01513       c=(int) *((unsigned char *) p);
01514       d=(int) *((unsigned char *) q);
01515       if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
01516         break;
01517       p++;
01518       q++;
01519     }
01520     return(AsciiMap[c]-(int) AsciiMap[d]);
01521   }
01522 #endif
01523 }
01524 
01525 /*
01526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01527 %                                                                             %
01528 %                                                                             %
01529 %                                                                             %
01530 %   L o c a l e L o w e r                                                     %
01531 %                                                                             %
01532 %                                                                             %
01533 %                                                                             %
01534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01535 %
01536 %  LocaleLower() transforms all of the characters in the supplied
01537 %  null-terminated string, changing all uppercase letters to lowercase.
01538 %
01539 %  The format of the LocaleLower method is:
01540 %
01541 %      void LocaleLower(char *string)
01542 %
01543 %  A description of each parameter follows:
01544 %
01545 %    o string: A pointer to the string to convert to lower-case Locale.
01546 %
01547 */
01548 WizardExport void LocaleLower(char *string)
01549 {
01550   register char
01551     *q;
01552 
01553   assert(string != (char *) NULL);
01554   for (q=string; *q != '\0'; q++)
01555     *q=(char) tolower((int) *q);
01556 }
01557 
01558 /*
01559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01560 %                                                                             %
01561 %                                                                             %
01562 %                                                                             %
01563 %   L o c a l e N C o m p a r e                                               %
01564 %                                                                             %
01565 %                                                                             %
01566 %                                                                             %
01567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01568 %
01569 %  LocaleNCompare() performs a case-insensitive comparison of two
01570 %  strings byte-by-byte, according to the ordering of the current locale
01571 %  encoding. LocaleNCompare returns an integer greater than, equal to, or
01572 %  less than 0, if the string pointed to by p is greater than, equal to, or
01573 %  less than the string pointed to by q respectively.  The sign of a non-zero
01574 %  return value is determined by the sign of the difference between the
01575 %  values of the first pair of bytes that differ in the strings being
01576 %  compared.  The LocaleNCompare method makes the same comparison as
01577 %  LocaleCompare but looks at a maximum of n bytes.  Bytes following a
01578 %  null byte are not compared.
01579 %
01580 %  The format of the LocaleNCompare method is:
01581 %
01582 %      int LocaleNCompare(const char *p,const char *q,const size_t n)
01583 %
01584 %  A description of each parameter follows:
01585 %
01586 %    o p: A pointer to a character string.
01587 %
01588 %    o q: A pointer to a character string to compare to p.
01589 %
01590 %    o length: The number of characters to compare in strings p and q.
01591 %
01592 */
01593 WizardExport int LocaleNCompare(const char *p,const char *q,const size_t length)
01594 {
01595   if ((p == (char *) NULL) && (q == (char *) NULL))
01596     return(0);
01597   if (p == (char *) NULL)
01598     return(-1);
01599   if (q == (char *) NULL)
01600     return(1);
01601 #if defined(WIZARDSTOOLKIT_HAVE_STRNCASECMP)
01602   return(strncasecmp(p,q,length));
01603 #else
01604   {
01605     register int
01606       c,
01607       d;
01608 
01609     register size_t
01610       i;
01611 
01612     for (i=length; i != 0; i--)
01613     {
01614       c=(int) *((unsigned char *) p);
01615       d=(int) *((unsigned char *) q);
01616       if (AsciiMap[c] != AsciiMap[d])
01617         return(AsciiMap[c]-(int) AsciiMap[d]);
01618       if (c == 0)
01619         return(0);
01620       p++;
01621       q++;
01622     }
01623     return(0);
01624   }
01625 #endif
01626 }
01627 
01628 /*
01629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01630 %                                                                             %
01631 %                                                                             %
01632 %                                                                             %
01633 %   P r i n t W i z a r d S t r i n g                                         %
01634 %                                                                             %
01635 %                                                                             %
01636 %                                                                             %
01637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01638 %
01639 %  PrintWizardString() prints the string to the specified file.
01640 %
01641 %  The format of the PrintWizardString method is:
01642 %
01643 %      ssize_t PrintWizardString(FILE *,const char *format,...)
01644 %
01645 %  A description of each parameter follows:
01646 %
01647 %    o file: print to this file.
01648 %
01649 %   o format:  A string describing the format to use to write the remaining
01650 %     arguments.
01651 %
01652 */
01653 WizardExport ssize_t PrintWizardString(FILE *file,const char *format,...)
01654 {
01655   char
01656     string[MaxTextExtent];
01657 
01658   ssize_t
01659     length;
01660 
01661   va_list
01662     operands;
01663 
01664   va_start(operands,format);
01665   length=FormatLocaleStringList(string,MaxTextExtent,format,operands);
01666   va_end(operands);
01667   if (length < 0)
01668     return(-1);
01669   return((ssize_t) fwrite(string,(size_t) length,1,file));
01670 }
01671 
01672 /*
01673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01674 %                                                                             %
01675 %                                                                             %
01676 %                                                                             %
01677 %   P r i n t S t r i n g I n f o                                             %
01678 %                                                                             %
01679 %                                                                             %
01680 %                                                                             %
01681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01682 %
01683 %  PrintStringInfo() prints the string.
01684 %
01685 %  The format of the PrintStringInfo method is:
01686 %
01687 %      void PrintStringInfo(FILE *file,const char *id,
01688 %        const StringInfo *string_info)
01689 %
01690 %  A description of each parameter follows:
01691 %
01692 %    o id: The string id.
01693 %
01694 %    o string_info: The string info.
01695 %
01696 */
01697 WizardExport void PrintStringInfo(FILE *file,const char *id,
01698   const StringInfo *string_info)
01699 {
01700   register unsigned char
01701     *p,
01702     *q;
01703 
01704   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01705   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01706   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01707   q=string_info->datum+string_info->length;
01708   for (p=string_info->datum; p < q; p++)
01709   {
01710     if (((int) *p < 32) && (isspace((int) ((unsigned char) *p)) == 0))
01711       break;
01712     if (isascii((int) ((unsigned char) *p)) == 0)
01713       break;
01714   }
01715   (void) PrintWizardString(file,"%s(%.20g): ",id,(double) string_info->length);
01716   if (p == q)
01717     for (p=string_info->datum; p < q; p++)
01718       (void) PrintWizardString(file,"%c",(int) *p);
01719   else
01720     for (p=string_info->datum; p < q; p++)
01721       (void) PrintWizardString(file,"%02lx",(unsigned long) *p);
01722   (void) PrintWizardString(file,"\n");
01723 }
01724 
01725 /*
01726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01727 %                                                                             %
01728 %                                                                             %
01729 %                                                                             %
01730 %   R e s e t S t r i n g I n f o                                             %
01731 %                                                                             %
01732 %                                                                             %
01733 %                                                                             %
01734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01735 %
01736 %  ResetStringInfo() reset the string to all null bytes.
01737 %
01738 %  The format of the ResetStringInfo method is:
01739 %
01740 %      void ResetStringInfo(StringInfo *string_info)
01741 %
01742 %  A description of each parameter follows:
01743 %
01744 %    o string_info: The string info.
01745 %
01746 */
01747 WizardExport void ResetStringInfo(StringInfo *string_info)
01748 {
01749   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01750   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01751   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01752   (void) ResetWizardMemory(string_info->datum,0,string_info->length);
01753 }
01754 
01755 /*
01756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01757 %                                                                             %
01758 %                                                                             %
01759 %                                                                             %
01760 %   S e t S t r i n g I n f o                                                 %
01761 %                                                                             %
01762 %                                                                             %
01763 %                                                                             %
01764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01765 %
01766 %  SetStringInfo() copies the source string to the destination string.
01767 %
01768 %  The format of the SetStringInfo method is:
01769 %
01770 %      void SetStringInfo(StringInfo *string_info,const StringInfo *source)
01771 %
01772 %  A description of each parameter follows:
01773 %
01774 %    o string_info: The string info.
01775 %
01776 %    o source: The source string.
01777 %
01778 */
01779 WizardExport void SetStringInfo(StringInfo *string_info,
01780   const StringInfo *source)
01781 {
01782   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01783   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01784   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01785   WizardAssert(StringDomain,source != (StringInfo *) NULL);
01786   WizardAssert(StringDomain,source->signature == WizardSignature);
01787   if (string_info->length == 0)
01788     return;
01789   (void) ResetWizardMemory(string_info->datum,0,string_info->length);
01790   (void) memcpy(string_info->datum,source->datum,
01791     WizardMin(string_info->length,source->length));
01792 }
01793 
01794 /*
01795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01796 %                                                                             %
01797 %                                                                             %
01798 %                                                                             %
01799 %   S e t S t r i n g I n f o D a t u m                                       %
01800 %                                                                             %
01801 %                                                                             %
01802 %                                                                             %
01803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01804 %
01805 %  SetStringInfoDatum() copies bytes from the source string for the length of
01806 %  the destination string.
01807 %
01808 %  The format of the SetStringInfoDatum method is:
01809 %
01810 %      void SetStringInfoDatum(StringInfo *string_info,
01811 %        const unsigned char *source)
01812 %
01813 %  A description of each parameter follows:
01814 %
01815 %    o string_info: The string info.
01816 %
01817 %    o source: The source string.
01818 %
01819 */
01820 WizardExport void SetStringInfoDatum(StringInfo *string_info,
01821   const unsigned char *source)
01822 {
01823   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01824   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01825   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01826   if (string_info->length != 0)
01827     (void) memcpy(string_info->datum,source,string_info->length);
01828 }
01829 
01830 /*
01831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01832 %                                                                             %
01833 %                                                                             %
01834 %                                                                             %
01835 %   S e t S t r i n g I n f o L e n g t h                                     %
01836 %                                                                             %
01837 %                                                                             %
01838 %                                                                             %
01839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01840 %
01841 %  SetStringInfoLength() set the string length to the specified value.
01842 %
01843 %  The format of the SetStringInfoLength method is:
01844 %
01845 %      void SetStringInfoLength(StringInfo *string_info,const size_t length)
01846 %
01847 %  A description of each parameter follows:
01848 %
01849 %    o string_info: The string info.
01850 %
01851 %    o length: The string length.
01852 %
01853 */
01854 WizardExport void SetStringInfoLength(StringInfo *string_info,
01855   const size_t length)
01856 {
01857   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01858   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01859   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01860   string_info->length=length;
01861   if (~length < MaxCipherBlocksize)
01862     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
01863   if (string_info->datum == (unsigned char *) NULL)
01864     string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
01865       MaxCipherBlocksize,sizeof(*string_info->datum));
01866   else
01867     string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
01868       length+MaxCipherBlocksize,sizeof(*string_info->datum));
01869   if (string_info->datum == (unsigned char *) NULL)
01870     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
01871 }
01872 
01873 /*
01874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01875 %                                                                             %
01876 %                                                                             %
01877 %                                                                             %
01878 %   S e t S t r i n g I n f o D a t u m                                       %
01879 %                                                                             %
01880 %                                                                             %
01881 %                                                                             %
01882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01883 %
01884 %  SetStringInfoPath() sets the path associated with the string.
01885 %
01886 %  The format of the SetStringInfoPath method is:
01887 %
01888 %      void SetStringInfoPath(StringInfo *string_info,const char *path)
01889 %
01890 %  A description of each parameter follows:
01891 %
01892 %    o string_info: The string info.
01893 %
01894 %    o path: The path.
01895 %
01896 */
01897 WizardExport void SetStringInfoPath(StringInfo *string_info,const char *path)
01898 {
01899   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01900   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01901   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01902   WizardAssert(StringDomain,path != (const char *) NULL);
01903   (void) CopyWizardString(string_info->path,path,MaxTextExtent);
01904 }
01905 
01906 /*
01907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01908 %                                                                             %
01909 %                                                                             %
01910 %                                                                             %
01911 %   S p l i t S t r i n g I n f o                                             %
01912 %                                                                             %
01913 %                                                                             %
01914 %                                                                             %
01915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01916 %
01917 %  SplitStringInfo() splits a string into two and returns it.
01918 %
01919 %  The format of the SplitStringInfo method is:
01920 %
01921 %      StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
01922 %
01923 %  A description of each parameter follows:
01924 %
01925 %    o string_info: The string info.
01926 %
01927 */
01928 WizardExport StringInfo *SplitStringInfo(StringInfo *string_info,
01929   const size_t offset)
01930 {
01931   StringInfo
01932     *split_info;
01933 
01934   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01935   WizardAssert(StringDomain,string_info != (StringInfo *) NULL);
01936   WizardAssert(StringDomain,string_info->signature == WizardSignature);
01937   if (offset > string_info->length)
01938     return((StringInfo *) NULL);
01939   split_info=AcquireStringInfo(offset);
01940   SetStringInfo(split_info,string_info);
01941   (void) memmove(string_info->datum,string_info->datum+offset,
01942     string_info->length-offset+MaxCipherBlocksize);
01943   SetStringInfoLength(string_info,string_info->length-offset);
01944   return(split_info);
01945 }
01946 
01947 /*
01948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01949 %                                                                             %
01950 %                                                                             %
01951 %                                                                             %
01952 %   S t r i n g I n f o T o H e x S t r i n g                                 %
01953 %                                                                             %
01954 %                                                                             %
01955 %                                                                             %
01956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01957 %
01958 %  StringInfoToHexString() converts a string info string to a C string.
01959 %
01960 %  The format of the StringInfoToHexString method is:
01961 %
01962 %      char *StringInfoToHexString(const StringInfo *string_info)
01963 %
01964 %  A description of each parameter follows:
01965 %
01966 %    o string_info: The string.
01967 %
01968 */
01969 WizardExport char *StringInfoToHexString(const StringInfo *string_info)
01970 {
01971   char
01972     *string;
01973 
01974   register const unsigned char
01975     *p;
01976 
01977   register ssize_t
01978     i;
01979 
01980   register unsigned char
01981     *q;
01982 
01983   size_t
01984     length;
01985 
01986   unsigned char
01987     hex_digits[16];
01988 
01989   length=string_info->length;
01990   if (~length < MaxTextExtent)
01991     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
01992   string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
01993   if (string == (char *) NULL)
01994     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
01995   hex_digits[0]='0';
01996   hex_digits[1]='1';
01997   hex_digits[2]='2';
01998   hex_digits[3]='3';
01999   hex_digits[4]='4';
02000   hex_digits[5]='5';
02001   hex_digits[6]='6';
02002   hex_digits[7]='7';
02003   hex_digits[8]='8';
02004   hex_digits[9]='9';
02005   hex_digits[10]='a';
02006   hex_digits[11]='b';
02007   hex_digits[12]='c';
02008   hex_digits[13]='d';
02009   hex_digits[14]='e';
02010   hex_digits[15]='f';
02011   p=string_info->datum;
02012   q=(unsigned char *) string;
02013   for (i=0; i < (ssize_t) string_info->length; i++)
02014   {
02015     *q++=hex_digits[(*p >> 4) & 0x0f]; 
02016     *q++=hex_digits[*p & 0x0f]; 
02017     p++;
02018   }
02019   *q='\0';
02020   return(string);
02021 }
02022 
02023 /*
02024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02025 %                                                                             %
02026 %                                                                             %
02027 %                                                                             %
02028 %   S t r i n g I n f o T o S t r i n g                                       %
02029 %                                                                             %
02030 %                                                                             %
02031 %                                                                             %
02032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02033 %
02034 %  StringInfoToString() converts a string info string to a C string.
02035 %
02036 %  The format of the StringInfoToString method is:
02037 %
02038 %      char *StringInfoToString(const StringInfo *string_info)
02039 %
02040 %  A description of each parameter follows:
02041 %
02042 %    o string_info: The string.
02043 %
02044 */
02045 WizardExport char *StringInfoToString(const StringInfo *string_info)
02046 {
02047   char
02048     *string;
02049 
02050   size_t
02051     length;
02052 
02053   string=(char *) NULL;
02054   length=string_info->length;
02055   if (~length >= (MaxTextExtent-1))
02056     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
02057   if (string == (char *) NULL)
02058     return((char *) NULL);
02059   (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
02060   string[length]='\0';
02061   return(string);
02062 }
02063 
02064 /*
02065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02066 %                                                                             %
02067 %                                                                             %
02068 %                                                                             %
02069 %  S t r i n g T o A r g v                                                    %
02070 %                                                                             %
02071 %                                                                             %
02072 %                                                                             %
02073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02074 %
02075 %  StringToArgv() converts a text string into command line arguments.
02076 %
02077 %  The format of the StringToArgv method is:
02078 %
02079 %      char **StringToArgv(const char *text,int *argc)
02080 %
02081 %  A description of each parameter follows:
02082 %
02083 %    o argv:  Method StringToArgv returns the string list unless an error
02084 %      occurs, otherwise NULL.
02085 %
02086 %    o text:  Specifies the string to segment into a list.
02087 %
02088 %    o argc:  This integer pointer returns the number of arguments in the
02089 %      list.
02090 %
02091 */
02092 WizardExport char **StringToArgv(const char *text,int *argc)
02093 {
02094   char
02095     **argv;
02096 
02097   register const char
02098     *p,
02099     *q;
02100 
02101   register ssize_t
02102     i;
02103 
02104   *argc=0;
02105   if (text == (char *) NULL)
02106     return((char **) NULL);
02107   /*
02108     Determine the number of arguments.
02109   */
02110   for (p=text; *p != '\0'; )
02111   {
02112     while (isspace((int) ((unsigned char) *p)) != 0)
02113       p++;
02114     if (*p == '\0')
02115       break;
02116     (*argc)++;
02117     if (*p == '"')
02118       for (p++; (*p != '"') && (*p != '\0'); p++) ;
02119     if (*p == '\'')
02120       for (p++; (*p != '\'') && (*p != '\0'); p++) ;
02121     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
02122       p++;
02123   }
02124   argv=(char **) AcquireQuantumMemory((size_t) (*argc+1),sizeof(*argv));
02125   if (argv == (char **) NULL)
02126     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
02127   /*
02128     Convert string to an ASCII list.
02129   */
02130   p=(char *) text;
02131   for (i=0; i < (ssize_t) *argc; i++)
02132   {
02133     while (isspace((int) ((unsigned char) *p)) != 0)
02134       p++;
02135     q=p;
02136     if (*q == '"')
02137       {
02138         p++;
02139         for (q++; (*q != '"') && (*q != '\0'); q++) ;
02140       }
02141     else
02142       if (*q == '\'')
02143         {
02144           p++;
02145           for (q++; (*q != '\'') && (*q != '\0'); q++) ;
02146         }
02147       else
02148         while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
02149           q++;
02150     argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
02151       sizeof(**argv));
02152     if (argv[i] == (char *) NULL)
02153       {
02154         for (i--; i >= 0; i--)
02155           argv[i]=(char *) RelinquishWizardMemory(argv[i]);
02156         argv=(char **) RelinquishWizardMemory(argv);
02157         ThrowFatalException(StringFatalError,"memory allocation failed `%s'");
02158       }
02159     (void) memcpy(argv[i],p,(size_t) (q-p));
02160     argv[i][q-p]='\0';
02161     p=q;
02162     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
02163       p++;
02164   }
02165   argv[i]=(char *) NULL;
02166   return(argv);
02167 }
02168 
02169 /*
02170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02171 %                                                                             %
02172 %                                                                             %
02173 %                                                                             %
02174 %   S t r i n g T o S t r i n g I n f o                                       %
02175 %                                                                             %
02176 %                                                                             %
02177 %                                                                             %
02178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02179 %
02180 %  StringToStringInfo() converts a string to a StringInfo type.
02181 %
02182 %  The format of the StringToStringInfo method is:
02183 %
02184 %      StringInfo *StringToStringInfo(const char *string)
02185 %
02186 %  A description of each parameter follows:
02187 %
02188 %    o string:  The string.
02189 %
02190 */
02191 WizardExport StringInfo *StringToStringInfo(const char *string)
02192 {
02193   StringInfo
02194     *string_info;
02195 
02196   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
02197   WizardAssert(StringDomain,string != (const char *) NULL);
02198   string_info=AcquireStringInfo(strlen(string));
02199   SetStringInfoDatum(string_info,(const unsigned char *) string);
02200   return(string_info);
02201 }
02202 
02203 /*
02204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02205 %                                                                             %
02206 %                                                                             %
02207 %                                                                             %
02208 %   S t r i p S t r i n g                                                     %
02209 %                                                                             %
02210 %                                                                             %
02211 %                                                                             %
02212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02213 %
02214 %  StripString() strips any whitespace or quotes from the beginning and end of
02215 %  a string of characters.
02216 %
02217 %  The format of the StripString method is:
02218 %
02219 %      void StripString(char *message)
02220 %
02221 %  A description of each parameter follows:
02222 %
02223 %    o message: Specifies an array of characters.
02224 %
02225 */
02226 WizardExport void StripString(char *message)
02227 {
02228   register char
02229     *p,
02230     *q;
02231 
02232   size_t
02233     length;
02234 
02235   assert(message != (char *) NULL);
02236   if (*message == '\0')
02237     return;
02238   length=strlen(message);
02239   p=message;
02240   while (isspace((int) ((unsigned char) *p)) != 0)
02241     p++;
02242   if ((*p == '\'') || (*p == '"'))
02243     p++;
02244   q=message+length-1;
02245   while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
02246     q--;
02247   if (q > p)
02248     if ((*q == '\'') || (*q == '"'))
02249       q--;
02250   (void) memmove(message,p,(size_t) (q-p+1));
02251   message[q-p+1]='\0';
02252   for (p=message; *p != '\0'; p++)
02253     if (*p == '\n')
02254       *p=' ';
02255 }
02256 
02257 /*
02258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02259 %                                                                             %
02260 %                                                                             %
02261 %                                                                             %
02262 %   S u b s t i t u t e S t r i n g                                           %
02263 %                                                                             %
02264 %                                                                             %
02265 %                                                                             %
02266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02267 %
02268 %  SubstituteString() performs string substitution on a string, replacing the
02269 %  string with the substituted version. Buffer must be allocated from the heap.
02270 %  If the string is matched and status, WizardTrue is returned otherwise
02271 %  WizardFalse.
02272 %
02273 %  The format of the SubstituteString method is:
02274 %
02275 %      WizardBooleanType SubstituteString(char **string,const char *search,
02276 %        const char *replace)
02277 %
02278 %  A description of each parameter follows:
02279 %
02280 %    o string: the string to perform replacements on;  replaced with new
02281 %      allocation if a replacement is made.
02282 %
02283 %    o search: search for this string.
02284 %
02285 %    o replace: replace any matches with this string.
02286 %
02287 */
02288 WizardExport WizardBooleanType SubstituteString(char **string,
02289   const char *search,const char *replace)
02290 {
02291   WizardBooleanType
02292     status;
02293 
02294   register char
02295     *p;
02296 
02297   size_t
02298     extent,
02299     replace_extent,
02300     search_extent;
02301 
02302   ssize_t
02303     offset;
02304 
02305   status=WizardFalse;
02306   search_extent=0,
02307   replace_extent=0;
02308   for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
02309   {
02310     if (search_extent == 0)
02311       search_extent=strlen(search);
02312     if (strncmp(p,search,search_extent) != 0)
02313       continue;
02314     /*
02315       We found a match.
02316     */
02317     status=WizardTrue;
02318     if (replace_extent == 0)
02319       replace_extent=strlen(replace);
02320     if (replace_extent > search_extent)
02321       {
02322         /*
02323           Make room for the replacement string.
02324         */
02325         offset=(ssize_t) (p-(*string));
02326         extent=strlen(*string)+replace_extent-search_extent+1;
02327         *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
02328           sizeof(*p));
02329         if (*string == (char *) NULL)
02330           ThrowFatalException(ResourceFatalError,
02331             "memory allocation failed `%s'");
02332         p=(*string)+offset;
02333       }
02334     /*
02335       Replace string.
02336     */
02337     if (search_extent != replace_extent)
02338       (void) CopyWizardMemory(p+replace_extent,p+search_extent,
02339         strlen(p+search_extent)+1);
02340     (void) CopyWizardMemory(p,replace,replace_extent);
02341     p+=replace_extent-1;
02342   }
02343   return(status);
02344 }