📄 hnstringobj.cpp
字号:
double value;
char *endptr;
value = strtod(ptr, &endptr);
if ( endptr - ptr != string.length() ) {
HnAbort("invalid string for a double-precision number `%s'.",
(char *)string);
}
return value;
}
/*
* pack and unpack
*/
/*
* NOTE:
* packString() converts an arbitrary character string into an
* escaped unique form. The conversion syntax is as follows:
*
* invalid string -> %UNDEF
* empty string -> %EMPTY
*
* `%' character -> %%
* ` ' character -> +
* `{' character -> %(
* `}' character -> %(
*
* control characters -> %[0-9A-F][0-9A-F]
* `+' character -> %[0-9A-F][0-9A-F]
* `/', `=', `,' -> %[0-9A-F][0-9A-F]
* `[', `]', `~', `:' -> %[0-9A-F][0-9A-F]
*/
static void
escapeString(const char *ptr, HnString *string_return)
{
#ifdef DEBUG
struct timeval s, e;
gettimeofday(&s, NULL);
#endif
/*
* NOTE:
* The variable `string_return' is only appended not cleared.
*/
int maxLength;
char *bp;
static char *buffer = NULL;
/*
* special treatment for `%UNDEF' and '%EMPTY'
*/
if ( ptr == NULL ) {
string_return->append("%UNDEF");
return;
}
if ( ptr[0] == 0 ) {
string_return->append("%EMPTY");
return;
}
/*
* allocate buffer
*
* NOTE:
* The maxium length of the result is the three time length of
* the given string.
*/
maxLength = strlen(ptr) * 3;
if ( buffer == NULL ) {
if ( (buffer = (char *)malloc(maxLength + 1)) == NULL )
HnSysError("malloc");
}
else {
if ( (buffer = (char *)realloc(buffer, maxLength + 1)) == NULL )
HnSysError("realloc");
}
bp = buffer;
while ( *ptr != 0 ) {
if ( iscntrl((unsigned char)*ptr) ||
strchr("% {}+/=,[]~:", *ptr) != NULL ) {
switch ( *ptr ) {
case '%':
*bp++ = '%';
*bp++ = '%';
break;
case ' ':
*bp++ = '+';
break;
case '{':
*bp++ = '%';
*bp++ = '(';
break;
case '}':
*bp++ = '%';
*bp++ = ')';
break;
default:
sprintf(bp, "%%%02X", *ptr);
bp += 3;
break;
}
ptr ++;
}
else
*bp++ = *ptr++;
}
string_return->append(buffer, bp - buffer);
#ifdef DEBUG
gettimeofday(&e, NULL);
sumEscapeString +=
e.tv_sec * 1000 + e.tv_usec / 1000
- s.tv_sec * 1000 - s.tv_usec / 1000;
#endif
}
static void
unescapeString(const char *ptr, int n, HnString *string_return)
{
#ifdef DEBUG
struct timeval s, e;
gettimeofday(&s, NULL);
#endif
HnString &string = *string_return;
const char *start = ptr;
const char *end = ptr + n;
char *bp;
static char *buffer = NULL;
/*
* special treatment for `%UNDEF' and `%EMPTY'
*/
if ( strncmp(ptr, "%UNDEF", n) == 0 ) {
string = HnString::null;
return;
}
if ( strncmp(ptr, "%EMPTY", n) == 0 ) {
string = "";
return;
}
/*
* allocate buffer
*/
if ( buffer == NULL ) {
if ( (buffer = (char *)malloc(n + 1)) == NULL )
HnSysError("malloc");
}
else {
if ( (buffer = (char *)realloc(buffer, n + 1)) == NULL )
HnSysError("realloc");
}
bp = buffer;
while ( ptr < end ) {
switch ( *ptr ) {
case '+':
*bp++ = ' ';
ptr ++;
break;
case '%':
ptr ++;
if ( *ptr == '%' ) {
*bp++ = '%';
ptr ++;
}
else if ( *ptr == '(' ) {
*bp++ = '{';
ptr ++;
}
else if ( *ptr == ')' ) {
*bp++ = '}';
ptr ++;
}
else if ( isxdigit(ptr[0]) && isxdigit(ptr[1]) ) {
int c;
sscanf(ptr, "%2X", &c);
*bp++ = c;
ptr += 2;
}
else {
HnString string = new_HnString(start, end - start);
HnAbort("unescapeString: an unexpected "
"character follows after `%%' "
"at `%s'[%d].",
(char *)string, ptr - start);
}
break;
default:
*bp ++ = *ptr;
ptr ++;
break;
}
}
string = new_HnString(buffer, bp - buffer);
#ifdef DEBUG
gettimeofday(&e, NULL);
sumUnescapeString +=
e.tv_sec * 1000 + e.tv_usec / 1000
- s.tv_sec * 1000 - s.tv_usec / 1000;
#endif
}
void
HnStringObj::escape(const char *ptr, HnString *string_return)
{
HnString &string = *string_return;
string = new_HnString();
escapeString(ptr, &string);
}
void
HnStringObj::unescape(const char *ptr, HnString *string_return)
{
unescapeString(ptr, (ptr == NULL ? 0 : strlen(ptr)), string_return);
}
/*
* pack and unpack character strings
*
* NOTE:
* The partial match for truncated array should be permitted, because
* HnEntityFile, HnConnectionFile, HnLinkFile, HnPropertyFile, and
* HnReferenceFile depend on that property.
*
* The conversion syntax is as follows:
* invalid array -> %UNDEF
* empty array -> %EMPTY
* normal array -> {array[0]}{array[1]}...{array[n-1]}
*/
void
HnStringObj::pack(const HnStringVector &strings, HnString *string_return)
{
HnString &string = *string_return;
int i;
/*
* special treatment for `%UNDEF' and '%EMPTY'
*/
if ( strings.isInvalid() ) {
string = "%UNDEF";
return;
}
if ( strings.size() == 0 ) {
string = "%EMPTY";
return;
}
string = new_HnString();
for ( i=0; i<strings.size(); i++ ) {
string += '{';
escapeString(strings[i], &string);
string += '}';
}
}
void
HnStringObj::unpack(const char *chars, HnStringVector *strings_return)
{
HnStringVector &strings = *strings_return;
const char *head, *ptr;
HnString string;
/*
* special treatment for `%UNDEF' and `%EMPTY'
*/
if ( strcmp(chars, "%UNDEF") == 0 ) {
strings.invalidate();
return;
}
if ( strcmp(chars, "%EMPTY") == 0 ) {
strings = new_HnStringVector();
strings.removeAllElements();
return;
}
strings = new_HnStringVector();
strings.removeAllElements();
ptr = chars;
while ( *ptr != 0 ) {
if ( *ptr != '{' ) {
HnAbort("HnStringObj::unpack: "
"`{' is not found at `%s'[%d].",
chars, ptr - chars);
}
head = ptr + 1;
if ( (ptr = strchr(head, '}')) == NULL )
HnAbort("HnStringObj::unpack: "
"`}' is not found at `%s'[%d].",
chars, head - chars);
unescapeString(head, ptr - head, &string);
strings.addElement(string);
ptr++;
}
}
/*
* variants of pack() and unpack()
*/
void
HnStringObj::pack(const char *array[], int length, HnString *string_return)
{
HnStringVector strings;
int i;
if ( array == NULL )
strings.invalidate();
else {
strings = new_HnStringVector();
strings.removeAllElements();
for ( i=0; i<length; i++ ) {
strings.addElement(array[i]);
}
}
HnStringObj::pack(strings, string_return);
}
void
HnStringObj::pack(const char *ptr1, HnString *string_return)
{
const char *array[1];
array[0] = ptr1;
HnStringObj::pack(array, 1, string_return);
}
void
HnStringObj::unpack(const char *chars, HnString *string1_return)
{
HnStringVector strings;
HnStringObj::unpack(chars, &strings);
if ( string1_return != NULL )
*string1_return = strings[0];
}
void
HnStringObj::pack(const char *ptr1, const char *ptr2, HnString *string_return)
{
const char *array[2];
array[0] = ptr1;
array[1] = ptr2;
HnStringObj::pack(array, 2, string_return);
}
void
HnStringObj::unpack(const char *chars,
HnString *string1_return, HnString *string2_return)
{
HnStringVector strings;
HnStringObj::unpack(chars, &strings);
if ( string1_return != NULL )
*string1_return = strings[0];
if ( string2_return != NULL )
*string2_return = strings[1];
}
void
HnStringObj::pack(const char *ptr1, const char *ptr2, const char *ptr3,
HnString *string_return)
{
const char *array[3];
array[0] = ptr1;
array[1] = ptr2;
array[2] = ptr3;
HnStringObj::pack(array, 3, string_return);
}
void
HnStringObj::unpack(const char *chars,
HnString *string1_return, HnString *string2_return,
HnString *string3_return)
{
HnStringVector strings;
HnStringObj::unpack(chars, &strings);
if ( string1_return != NULL )
*string1_return = strings[0];
if ( string2_return != NULL )
*string2_return = strings[1];
if ( string3_return != NULL )
*string3_return = strings[2];
}
void
HnStringObj::pack(const char *ptr1, const char *ptr2,
const char *ptr3, const char *ptr4, HnString *string_return)
{
const char *array[4];
array[0] = ptr1;
array[1] = ptr2;
array[2] = ptr3;
array[3] = ptr4;
HnStringObj::pack(array, 4, string_return);
}
void
HnStringObj::unpack(const char *chars,
HnString *string1_return, HnString *string2_return,
HnString *string3_return, HnString *string4_return)
{
HnStringVector strings;
HnStringObj::unpack(chars, &strings);
if ( string1_return != NULL )
*string1_return = strings[0];
if ( string2_return != NULL )
*string2_return = strings[1];
if ( string3_return != NULL )
*string3_return = strings[2];
if ( string4_return != NULL )
*string4_return = strings[3];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -