Thread: Struggling to spot what I did wrong with my encoding functions

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Struggling to spot what I did wrong with my encoding functions

    So I made this encode object of mine to hide differences between windows & linux, I went to the
    effort of setting up my custom printf handler to support UTF-16, UTF-32 & TCHAR plus a a "largest character type" (pawjc) and the encoder was responsible for passing the pointers over to the system handlers, trouble is I'm somehow getting 0 bytes written to the destination according to the output length, yet the string is definitely copied over according to the debugger so I'm at a loss as to what I did wrong that resulted in "0 characters" converted despite it actually getting in the destination.

    Triggered by:
    Code:
    pawd test__Printf( paws ARGS, paws VA, paws args, pawhhs arghhs, ... )
    {
    #define CHK_MAX 511
    	pawd did = -1;
    	pawd len = -1;
    	va_list one, two;
    	pawSTR Got = NULL;
    	pawc chk[CHK_MAX+1] = {0};
    	va_start( one, arghhs );
    	va_copy( two, one );
    
    	len = vsnprintf( chk, CHK_MAX, args, one );
    	Got = pawMakeStringv( arghhs, &two );
    	printf( "vsnprintf( %s, %s ): %s\n", ARGS, VA, chk );
    	printf( "pawPrintf( %s, %s ): ", ARGS, VA );
    	...
    }
    ...
    	switch ( *mod )
    	{
    	case 'h':
    		if ( len > 1 )
    			paw_cpy( dst, src, sizeof(pawhhc) * did );
    		else
    			did = pawhs2hhs( dst, cap, src, len );
    		break;
    	case 'l':
    		did = (len > 1)
    			? pawlls2hhs( dst, cap, src, did )
    			: pawls2hhs( dst, cap, src, did );
    		break;
    	case 't': did = pawts2hhs( dst, cap, src, did ); break;
    	case 'j': did = pawjs2hhs( dst, cap, src, did ); break;
    	default: did = paws2hhs( dst, cap, src, did ); // here
    	}
    ...
    PAW_API pawzd paws2hhs( pawhhc *dst, pawd max, paws src, pawd len )
    {
    	return paw_encode
    	(
    		PAWHHC_ENCODING, dst, max, sizeof(pawhhc),
    		PAWC_ENCODING, src, len, sizeof(pawc)
    	);
    }
    ...
    PAW_API pawzd paw_encode
    (
    	paws DST, void *dst, pawd max, pawzd perDN,
    	paws SRC, pawp  src, pawd len, pawzd perSN
    )
    {
    	if ( dst && max > 0 && perDN > 0 && src && len >= 0 && perSN > 0 )
    	{
    		pawENC enc = pawMakeEncoder( DST, SRC );
    		pawhhu *D = (pawhhu*)dst;
    		if ( !enc )
    			return -1;
    		len = pawEncodeText
    			( enc, dst, perDN * --max, src, perSN * len );
    		pawVoidEncoder( enc );
    		paw_set( D + perDN * max, 0, perDN );
    		return (len > 0) ? len / perDN : len;
    	}
    	return -1;
    }
    Code:
    #include "std.h"
    #include <stdlib.h>
    
    PAW_API pawzd pawEncodeCB_notsup( pawENC enc )
    	{ (void)enc; errno = ENOSYS; return -1; }
    PAW_API pawzd pawEncodeCB_rawcpy( pawENC enc )
    {
    	pawzd bytes = PawToLower( enc->dleft, enc->sleft );
    	paw_cpy( enc->daddr, enc->saddr, bytes );
    	enc->daddr += bytes;
    	enc->saddr += bytes;
    	enc->dleft -= bytes;
    	enc->sleft -= bytes;
    	return bytes;
    }
    #ifdef PAW_ON_WINDOWS
    PAW_API	paws pawCharEncoding() { return "UTF-8"; }
    PAW_API pawzd pawEncodeCB_MultiByteToWideChar( pawENC enc )
    {
    	pawzd did = WideCharToMultiByte
    	(
    		enc->dstcp, 0,
    		enc->saddr,
    		enc->sleft,
    		enc->daddr,
    		enc->dleft,
    		NULL,
    		NULL
    	);
    	if ( did < 0 )
    		return -1;
    	return did;
    }
    PAW_API pawzd pawEncodeCB_MultiByteToWideChar( pawENC enc )
    {
    	pawzd did = MultiByteToWideChar
    	(
    		enc->dstcp, 0,
    		enc->saddr,
    		enc->sleft,
    		enc->daddr,
    		enc->dleft
    	);
    	if ( did < 0 )
    		return -1;
    	return did;
    }
    #else
    PAW_API	paws pawCharEncoding()
    {
    	paws info = getenv("LC_TYPE"), conv;
    	if ( !info  ) info = getenv("LANG");
    	conv = strchr( info, '.' );
    	conv = conv ? conv + 1 : PAWC_LAST_RESORT_ENCODING_ASSUMPTION;
    	return conv;
    }
    PAW_API void	pawVoidEncoder( pawENC enc )
    {
    	if ( enc->dname )
    		iconv_close( enc->iconv );
    	PawGet( enc, 0 );
    }
    PAW_API pawENC	pawMakeEncoder( paws dst, paws src )
    {
    	pawENC enc = PawGetUD( sizeof(pawENC) );
    	if ( enc )
    	{
    		if ( !dst || !(dst[0]) ) dst = pawCharEncoding();
    		if ( !src || !(src[0]) ) src = pawCharEncoding();
    		if ( dst == src || paws_icmp( dst, src ) < 0 ) // footnote at bottom about this
    		{
    			enc->encodeCB = pawEncodeCB_rawcpy;
    			enc->iconv = (iconv_t)-1;
    			return enc;
    		}
    		enc->iconv = iconv_open( dst, src );
    		if ( enc->iconv == (iconv_t)-1 )
    		{
    			PawGet( enc, 0 );
    			return NULL;
    		}
    		enc->dname = dst;
    		enc->sname = src;
    		enc->encodeCB = pawEncodeCB_iconv;
    	}
    	return enc;
    }
    PAW_API pawzd pawEncodeCB_iconv( pawENC enc )
    {
    	pawzu dleft = enc->dleft;
    	pawzu sleft = enc->sleft;
    	pawc* daddr = (pawc*)(enc->daddr);
    	pawc* saddr = (pawc*)(enc->saddr);
    	pawzd bytes = iconv( enc->iconv, &saddr, &sleft, &daddr, &dleft );
    	enc->daddr = daddr;
    	enc->dleft = dleft;
    	enc->saddr = saddr;
    	enc->sleft = sleft;
    	return bytes;
    }
    #endif
    PAW_API pawzd pawEncodeText
    	( pawENC enc, void *dst, pawzd cap, pawp src, pawzd has )
    {
    	enc->daddr = dst;
    	enc->dleft = cap;
    	enc->saddr = src;
    	enc->sleft = has;
    	return enc->encodeCB( enc );
    }
    As an extra I also found I had made a mistake somewhere with my paw_icmp function, not seeing what though, only realised it because a comparison between "UTF-8" & "UTF-8" did not yield -1 as I was expecting it to, if anyone's inclined to look, here it is:
    Code:
    PAW_API pawd paw_icmp( pawp a, pawp b, pawzd perN )
    {
    	pawd i = 0;
    	pawzd n = 0, N = 0;
    	pawhhu const *A = (pawhhu const*)a;
    	pawhhu const *B = (pawhhu const*)b;
    
    	if ( !a || !b || a == b )
    		return -(a == b);
    
    	for ( N = paw_is0( A, perN ); N < 0; N = paw_is0( A + n, perN ) )
    	{
    		N = paw_cmp( A + n, B + n, perN );
    		if ( N > 0 || toupper(A[n]) != toupper(B[n]) )
    			return i;
    		n += perN;
    		++i;
    	}
    
    	N = paw_is0( B + n, perN );
    	return (N < 0) ? -1 : n + N;
    }

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Before anyone points it out, I just noticed I was passing the wrong size to PawGetUD(), does not change the problem, I was just lucky that didn't crash the app, should've but didn't

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Well I just spotted what I did wrong with paw_icmp, I had mistakenly put N < 0 as the loop condition when it should've been N >= 0 since paw_is0 only returns < 0 when no non-0 bytes were found

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Struggling to see what I did wrong
    By awsdert in forum C Programming
    Replies: 7
    Last Post: 07-06-2019, 02:49 AM
  2. Can anybody spot where I'm going wrong with this?
    By awsdert in forum C Programming
    Replies: 3
    Last Post: 01-08-2018, 05:05 AM
  3. Help~~something went wrong with my encoding code
    By yssmile in forum C Programming
    Replies: 1
    Last Post: 10-15-2015, 09:04 AM
  4. Struggling to understand C, and where I am going wrong.
    By DARK_STALKER in forum C Programming
    Replies: 1
    Last Post: 11-29-2012, 10:44 AM
  5. Who can spot what I did wrong?
    By jturner38 in forum C Programming
    Replies: 13
    Last Post: 03-25-2009, 01:09 AM

Tags for this Thread