Example #1
0
/*:::::*/
FBCALL FB_WCHAR *fb_WstrConcatWA ( const FB_WCHAR *str1, const void *str2, int str2_size )
{
	FB_WCHAR *dst;
	int str1_len, str2_len;
	char *str2_ptr;

	if( str1 != NULL )
		str1_len = fb_wstr_Len( str1 );
	else
		str1_len = 0;

	FB_STRSETUP_FIX( str2, str2_size, str2_ptr, str2_len );

	/* NULL? */
	if( str1_len + str2_len == 0 )
	{
		dst = NULL;
	}
	else
	{
		/* alloc temp string */
    	dst = fb_wstr_AllocTemp( str1_len + str2_len );

		/* do the concatenation */
    	fb_wstr_Move( dst, str1, str1_len );
    	fb_wstr_ConvFromA( &dst[str1_len], str2_len, str2_ptr );
    }

	/* delete temp? */
	if( str2_size == -1 )
		fb_hStrDelTemp( (FBSTRING *)str2 );

	return dst;
}
Example #2
0
FBCALL FB_WCHAR *fb_WstrAssignFromA
	(
		FB_WCHAR *dst,
		ssize_t dst_chars,
		void *src,
		ssize_t src_size
	)
{
	char *src_ptr;
	ssize_t src_chars;

	if( dst != NULL )
	{
		FB_STRSETUP_FIX( src, src_size, src_ptr, src_chars );

		/* size unknown? assume it's big enough */
		if( dst_chars == 0 )
		{
			dst_chars = src_chars;
		}
		else
		{
			/* less the null-term */
			--dst_chars;
		}

		fb_wstr_ConvFromA( dst, dst_chars, src_ptr );
	}

	/* delete temp? */
	if( src_size == -1 )
		fb_hStrDelTemp( (FBSTRING *)src );

	return dst;
}
Example #3
0
/*:::::*/
FBCALL void fb_StrSwap( void *str1, int size1, int fillrem1,
                        void *str2, int size2, int fillrem2 )
{
	char *p1, *p2;
	int len1, len2;

	if( (str1 == NULL) || (str2 == NULL) )
		return;

	/* both var-len? */
	if( (size1 == -1) && (size2 == -1) )
	{
		FBSTRING td;

		/* just swap the descriptors */
		td.data = ((FBSTRING *)str1)->data;
		td.len  = ((FBSTRING *)str1)->len;
		td.size  = ((FBSTRING *)str1)->size;

		((FBSTRING *)str1)->data = ((FBSTRING *)str2)->data;
		((FBSTRING *)str1)->len = ((FBSTRING *)str2)->len;
		((FBSTRING *)str1)->size = ((FBSTRING *)str2)->size;

		((FBSTRING *)str2)->data = td.data;
		((FBSTRING *)str2)->len = td.len;
		((FBSTRING *)str2)->size = td.size;

		return;
	}

	FB_STRSETUP_FIX( str1, size1, p1, len1 );
	FB_STRSETUP_FIX( str2, size2, p2, len2 );

	/* Same length? Only need to do an fb_MemSwap() */
	if( len1 == len2 ) {
		if( len1 > 0 ) {
			fb_MemSwap( (unsigned char *)p1,
			            (unsigned char *)p2,
			            len1 );
			/* null terminators don't need to change */
		}
		return;
	}

	/* Note: user-allocated zstrings are assumed to be large enough */

	/* Is one of them a var-len string? Might need to be (re)allocated */
	if( (size1 == -1) || (size2 == -1) )
	{
		FBSTRING td = { 0 };
		fb_StrAssign( &td, -1, str1, size1, FALSE );
		fb_StrAssign( str1, size1, str2, size2, fillrem1 );
		fb_StrAssign( str2, size2, &td, -1, fillrem2 );
		fb_StrDelete( &td );
		return;
	}

	/* Both are fixed-size/user-allocated [z]strings */

	/* Make str1/str2 be the smaller/larger string respectively */
	if( len1 > len2 ) {
		{
			char* p = p1;
			p1 = p2;
			p2 = p;
		}

		{
			int len = len1;
			len1 = len2;
			len2 = len;
		}

		{
			int size = size1;
			size1 = size2;
			size2 = size;
		}

		{
			int fillrem = fillrem1;
			fillrem1 = fillrem2;
			fillrem2 = fillrem;
		}
	}

	/* MemSwap as much as possible (i.e. the smaller length) */
	if( len1 > 0 ) {
		fb_MemSwap( (unsigned char *)p1,
			    (unsigned char *)p2,
			    len1 );
	}

	/* and copy over the remainder from larger to smaller, unless it's
	   a fixed-size [z]string that doesn't have enough room left (not even
	   for the null terminator) */
	if( (size1 > 0) && (len2 >= size1) ) {
		len2 = len1;
	} else if( len2 > len1 ) {
		FB_MEMCPYX( (unsigned char *)(p1 + len1),
		            (unsigned char *)(p2 + len1),
		            len2 - len1 );
	}

	/* set null terminators */
	p1[len2] = '\0';
	p2[len1] = '\0';

	/* Clear remainder of the larger (now smaller) string with nulls if
	   requested (see also fb_StrAssign()). We can assume that the strings
	   were originally cleared properly, because uninitialized strings
	   mustn't be used in rvalues, FB_STRSETUP_FIX() doesn't handle that.
	   The smaller (now larger) string doesn't need to be touched, as it's
	   remainder didn't increase */
	if( fillrem2 ) {
		int used2 = len1 + 1;
		if( size2 > used2 ) {
			memset( p2 + used2, 0, size2 - used2 );
		}
	}
}