⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hnstringobj.cpp

📁 SR-tree is an index structure for high-dimensional nearest neighbor queries
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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 + -