Results 1 to 25 of 25

Thread: How to make an MFC Class to be used in VB6 ??

Threaded View

  1. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    And before you ask me about arrays...
    Code:
    // This function decodes a string to a byte array, wrapped up in a variant.
    STDMETHODIMP CBase64Coder::DecodeStringToByteArray(BSTR strIn, VARIANT* arByteOut)
    {
    	// Many functions have a HRESULT as return value.
    	HRESULT hr;
    	// A pointer to move over the input buffer
    	const wchar_t *p;
    	// Random loop index
    	UINT i=0;
    
    	// Check for error conditions.
    	// The output pointer could point to nothing.
    	if(arByteOut == NULL)
    	{
    		return E_POINTER;
    	}
    	// If strIn is NULL this may have two causes: an error may have occured or
    	// (more likely) the passed string is empty. For some reason VB passes NULL in that
    	// case. So let's just return an empty variant.
    	if(strIn == NULL)
    	{
    		// This most probably means that "" was passed.
    		VariantInit(arByteOut);
    		return S_OK;
    	}
    
    	// Find the length of the encoded data.
    	UINT uiSourceLength = SysStringLen(strIn);
    
    	// It's easier to work with CAtlString than with BSTR
    	CAtlStringW strUse;
    
    	// first go through string and kick out everything invalid
    	for(p=(const wchar_t *)strIn, i=0; i<uiSourceLength &&
    		(i==0 || (*(p-1) != L'=' || (*(p-1) == L'=' && *p == L'='))); ++p, ++i)
    	{
    		if(isbase64(*p))
    			strUse += *p;
    		else if(!isbase64allowed(*p))
    		{
    			// this character should not be there
    			// possible reactions:
    			// 1) warn
    			// 2) ignore <- I have chosen this.
    			// 3) fail
    		}
    	}
    
    	// There should be padding characters so that the character count is an exact
    	// multiple of 4. If not then something is wrong.
    	UINT pad = (UINT)strUse.GetLength() % 4;
    	if(pad != 0)
    	{
    		// again two options:
    		// 1) add padding so that it works and maybe warn
    		// 2) fail <-
    		return E_INVALIDARG;
    	}
    
    	// Initialize the output value and set its type to byte array.
    	VariantInit(arByteOut);
    	arByteOut->vt = VT_ARRAY | VT_UI1;
    
    	// Create a 1-dimensional array (1 to whatever is needed).
    	SAFEARRAYBOUND bound;
    	bound.cElements = strUse.GetLength()/4*3;
    	bound.lLbound = 1;
    	V_ARRAY(arByteOut) = SafeArrayCreateEx(VT_UI1, 1, &bound, NULL);
    	// The only real reason this call could fail is because there is no memory
    	// to allocate the array.
    	if(V_ARRAY(arByteOut) == NULL)
    		return E_OUTOFMEMORY;
    
    	// Now access the data
    	PBYTE pOut;
    	hr = SafeArrayAccessData(V_ARRAY(arByteOut), (void **)&pOut);
    	if(FAILED(hr))
    		return hr;
    
    	// Decode the string
    	for(p=strUse; *p; p+=4, pOut+=3)
    	{
    		GrabByteTriple(pOut, p);
    	}
    
    	// Clean up
    	hr = SafeArrayUnaccessData(V_ARRAY(arByteOut));
    	if(FAILED(hr))
    		return hr;
    
    	return S_OK;
    }
    isbase64, isbase64allowed and GrabByteTriple are functions defined by me, all others are API or ATL.
    Last edited by CornedBee; Jan 8th, 2003 at 12:33 PM.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width