|
-
Jan 8th, 2003, 12:30 PM
#6
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|