% MagickCore String Methods %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% August 2003 %
% %
% %
-% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the license. You may %
#include "MagickCore/resource_.h"
#include "MagickCore/signature-private.h"
#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
#include "MagickCore/utility-private.h"
\f
/*
*/
#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
static const unsigned char
- asciimap[] =
+ AsciiMap[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% AcquireString() allocates memory for a string and copies the source string
-% to that memory location (and returns it).
+% AcquireString() returns an new extented string, containing a clone of the
+% given string.
+%
+% An extended string is the string length, plus an extra MaxTextExtent space
+% to allow for the string to be activally worked on.
+%
+% The returned string shoud be freed using DestoryString().
%
% The format of the AcquireString method is:
%
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% BlobToStringInfo() returns the contents of a blob as a string.
+% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
+% with MaxTextExtent extra space.
%
% The format of the BlobToStringInfo method is:
%
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% CloneString() allocates memory for the destination string and copies
-% the source string to that memory location.
+% CloneString() replaces or frees the destination string to make it
+% a clone of the input string plus MaxTextExtent more space so the string may
+% be worked on on.
%
-% If source is a NULL pointer the destination will also be set to a NULL
-% point (any existing string is freed). Otherwise the memory is allocated
-% (or resized) and the source string copied into it.
+% If source is a NULL pointer the destination string will be freed and set to
+% a NULL pointer. A pointer to the stored in the destination is also returned.
%
-% A pointer to the copy of the source string, or NULL is returned.
+% When finished the non-NULL string should be freed using DestoryString()
+% or using CloneString() with a NULL pointed for the source.
%
% The format of the CloneString method is:
%
size_t
length;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(destination != (char **) NULL);
if (source == (const char *) NULL)
{
StringInfo
*clone_info;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
clone_info=AcquireStringInfo(string_info->length);
int
status;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(target != (StringInfo *) NULL);
assert(target->signature == MagickSignature);
assert(source != (StringInfo *) NULL);
size_t
length;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
assert(source != (const StringInfo *) NULL);
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% ConstantString() allocates memory for a string and copies the source string
-% to that memory location (and returns it). Use it for strings that you do
-% do not expect to change over its lifetime.
+% ConstantString() allocates exactly the needed memory for a string and
+% copies the source string to that memory location. A NULL string pointer
+% will allocate an empty string containing just the NUL character.
+%
+% When finished the string should be freed using DestoryString()
%
% The format of the ConstantString method is:
%
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% CopyMagickString() copies the source string to the destination string. The
-% destination buffer is always null-terminated even if the string must be
-% truncated. The return value is the minimum of the source string length
-% or the length parameter.
+% CopyMagickString() copies the source string to the destination string, with
+% out exceeding the given pre-declared length.
+%
+% The destination buffer is always null-terminated even if the string must be
+% truncated. The return value is the minimum of the source string length or
+% the length parameter.
%
% The format of the CopyMagickString method is:
%
*/
MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
{
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
if (string_info->datum != (unsigned char *) NULL)
size_t
length;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(source != (const char *) NULL);
length=strlen(source);
for (p=source; *p != '\0'; p++)
#endif
for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
length/=bytes;
+ count=0;
for (j=2; j < 12; j++)
{
count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% LocaleNCompare() performs a case-insensitive comparison of two
-% strings byte-by-byte, according to the ordering of the current locale
-% encoding. LocaleNCompare returns an integer greater than, equal to, or
-% less than 0, if the string pointed to by p is greater than, equal to, or
-% less than the string pointed to by q respectively. The sign of a non-zero
-% return value is determined by the sign of the difference between the
-% values of the first pair of bytes that differ in the strings being
-% compared. The LocaleNCompare method makes the same comparison as
-% LocaleCompare but looks at a maximum of n bytes. Bytes following a
-% null byte are not compared.
+% LocaleNCompare() performs a case-insensitive comparison of two strings
+% byte-by-byte, according to the ordering of the current locale encoding.
+%
+% LocaleNCompare returns an integer greater than, equal to, or less than 0,
+% if the string pointed to by p is greater than, equal to, or less than the
+% string pointed to by q respectively. The sign of a non-zero return value
+% is determined by the sign of the difference between the values of the first
+% pair of bytes that differ in the strings being compared.
+%
+% The LocaleNCompare method makes the same comparison as LocaleCompare but
+% looks at a maximum of n bytes. Bytes following a null byte are not
+% compared.
%
% The format of the LocaleNCompare method is:
%
j;
assert(id != (const char *) NULL);
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
p=(char *) string_info->datum;
break;
p++;
}
+ (void) FormatLocaleFile(file,"%s(%.20g): ",id,(double) string_info->length);
if (i == string_info->length)
{
- (void) fputs((char *) string_info->datum,file);
+ for (i=0; i < string_info->length; i++)
+ (void) fputc(string_info->datum[i],file);
(void) fputc('\n',file);
return;
}
*/
MagickExport void ResetStringInfo(StringInfo *string_info)
{
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
(void) ResetMagickMemory(string_info->datum,0,string_info->length);
MagickExport void SetStringInfo(StringInfo *string_info,
const StringInfo *source)
{
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
assert(source != (StringInfo *) NULL);
MagickExport void SetStringInfoDatum(StringInfo *string_info,
const unsigned char *source)
{
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
if (string_info->length != 0)
MagickExport void SetStringInfoLength(StringInfo *string_info,
const size_t length)
{
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
if (~length < MaxTextExtent)
*/
MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
{
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
assert(path != (const char *) NULL);
StringInfo
*split_info;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string_info != (StringInfo *) NULL);
assert(string_info->signature == MagickSignature);
if (offset > string_info->length)
% %
% %
% %
+% S t r i n g I n f o T o H e x S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% StringInfoToHexString() converts a string info string to a C string.
+%
+% The format of the StringInfoToHexString method is:
+%
+% char *StringInfoToHexString(const StringInfo *string_info)
+%
+% A description of each parameter follows:
+%
+% o string_info: the string.
+%
+*/
+MagickExport char *StringInfoToHexString(const StringInfo *string_info)
+{
+ char
+ *string;
+
+ register const unsigned char
+ *p;
+
+ register ssize_t
+ i;
+
+ register unsigned char
+ *q;
+
+ size_t
+ length;
+
+ unsigned char
+ hex_digits[16];
+
+ length=string_info->length;
+ if (~length < MaxTextExtent)
+ ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
+ string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
+ if (string == (char *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
+ hex_digits[0]='0';
+ hex_digits[1]='1';
+ hex_digits[2]='2';
+ hex_digits[3]='3';
+ hex_digits[4]='4';
+ hex_digits[5]='5';
+ hex_digits[6]='6';
+ hex_digits[7]='7';
+ hex_digits[8]='8';
+ hex_digits[9]='9';
+ hex_digits[10]='a';
+ hex_digits[11]='b';
+ hex_digits[12]='c';
+ hex_digits[13]='d';
+ hex_digits[14]='e';
+ hex_digits[15]='f';
+ p=string_info->datum;
+ q=(unsigned char *) string;
+ for (i=0; i < (ssize_t) string_info->length; i++)
+ {
+ *q++=hex_digits[(*p >> 4) & 0x0f];
+ *q++=hex_digits[*p & 0x0f];
+ p++;
+ }
+ *q='\0';
+ return(string);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% S t r i n g T o A r g v %
% %
% %
% %
% %
% %
-% S t r i n g I n f o T o H e x S t r i n g %
+% S t r i n g T o A r r a y O f D o u b l e s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% StringInfoToHexString() converts a string info string to a C string.
+% StringToArrayOfDoubles() converts a string of space or comma separated
+% numbers into array of floating point numbers (doubles). Any number that
+% failes to parse properly will produce a syntax error. As will two commas
+% without a number between them. However a final comma at the end will
+% not be regarded as an error so as to simplify automatic list generation.
%
-% The format of the StringInfoToHexString method is:
+% A NULL value is returned on syntax or memory errors.
%
-% char *StringInfoToHexString(const StringInfo *string_info)
+% Use RelinquishMagickMemory() to free returned array when finished.
+%
+% The format of the StringToArrayOfDoubles method is:
+%
+% double *StringToArrayOfDoubles(const char *string,size_t *count)
%
% A description of each parameter follows:
%
-% o string_info: the string.
+% o string: the string containing the comma/space separated values.
+%
+% o count: returns number of arguments in returned array
+%
+% o exception: return any errors or warnings in this structure.
%
*/
-MagickExport char *StringInfoToHexString(const StringInfo *string_info)
+MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
+ ExceptionInfo *exception)
{
char
- *string;
+ *q;
- register const unsigned char
+ const char
*p;
+ double
+ *array;
+
register ssize_t
i;
- register unsigned char
- *q;
-
- size_t
- length;
-
- unsigned char
- hex_digits[16];
-
- length=string_info->length;
- if (~length < MaxTextExtent)
- ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
- string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
- if (string == (char *) NULL)
- ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
- hex_digits[0]='0';
- hex_digits[1]='1';
- hex_digits[2]='2';
- hex_digits[3]='3';
- hex_digits[4]='4';
- hex_digits[5]='5';
- hex_digits[6]='6';
- hex_digits[7]='7';
- hex_digits[8]='8';
- hex_digits[9]='9';
- hex_digits[10]='a';
- hex_digits[11]='b';
- hex_digits[12]='c';
- hex_digits[13]='d';
- hex_digits[14]='e';
- hex_digits[15]='f';
- p=string_info->datum;
- q=(unsigned char *) string;
- for (i=0; i < (ssize_t) string_info->length; i++)
+ /*
+ Determine count of values, and check syntax.
+ */
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ *count=0;
+ i=0;
+ p=string;
+ while (*p != '\0')
{
- *q++=hex_digits[(*p >> 4) & 0x0f];
- *q++=hex_digits[*p & 0x0f];
- p++;
+ (void) StringToDouble(p,&q); /* get value - ignores leading space */
+ if (p == q)
+ return((double *) NULL); /* no value found */
+ p=q;
+ i++; /* increment value count */
+ while (isspace((int) ((unsigned char) *p)) != 0)
+ p++; /* skip spaces */
+ if (*p == ',')
+ p++; /* skip comma */
+ while (isspace((int) ((unsigned char) *p)) != 0)
+ p++; /* and more spaces */
}
- *q='\0';
- return(string);
+ /*
+ Allocate floating point argument list.
+ */
+ *count=i;
+ array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
+ if (array == (double *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'","");
+ return((double *) NULL);
+ }
+ /*
+ Fill in the floating point values.
+ */
+ i=0;
+ p=string;
+ while ((*p != '\0') && (i < *count))
+ {
+ array[i++]=StringToDouble(p,&q);
+ p=q;
+ while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
+ p++;
+ }
+ return(array);
}
\f
/*
% %
% %
% %
-% S t r i n g T o k e n %
++ S t r i n g T o k e n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% StringToken() extracts a token a from the string.
+% StringToken() Looks for any one of given delimiters and splits the string
+% into two separate strings by replacing the delimiter character found with a
+% nul character.
+%
+% The given string pointer is changed to point to the string following the
+% delimiter character found, or NULL. A pointer to the start of the
+% string is returned, representing the token before the delimiter.
+%
+% In may ways this is equivent to the strtok() C library function, but with
+% multiple delimiter characters rather than a delimiter string.
%
% The format of the StringToken method is:
%
p=(*string);
if (p == (char *) NULL)
return((char *) NULL);
- for (q=p; ; )
+ q=p;
+ for ( ; ; )
{
c=(*p++);
r=delimiters;
StringInfo
*string_info;
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(string != (const char *) NULL);
string_info=AcquireStringInfo(strlen(string));
SetStringInfoDatum(string_info,(const unsigned char *) string);