views:

51

answers:

2

I am using some cross platform stuff called nutcracker to go between Windows and Linux, to make a long story short its limited in its support for wide string chars. I have to take the code below and replace what the swprintf is doing and I have no idea how. My experience with low level byte manipulation sucks. Can someone please help me with this?

Please keep in mind I can't go crazy and re-write swprintf but get the basic functionality to format the pwszString correctly from the data in pBuffer. This is c++ using the Microsoft vc6.0 compiler but through CXX so it's limited as well.

The wszSep is just a delimeter, either "" or "-" for readabilty when printing.

HRESULT BufferHelper::Buff2StrASCII( 
   /*[in]*/ const unsigned char * pBuffer, 
   /*[in]*/ int iSize,
   /*[in]*/ LPWSTR wszSep,
   /*[out]*/ LPWSTR* pwszString )
{
 // Check args
 if (! pwszString) return E_POINTER;

 // Allocate memory
 int iSep = (int)wcslen(wszSep);
 *pwszString = new WCHAR [ (((iSize * ( 2 + iSep )) + 1 ) - iSep ) ];
 if (! pwszString) return E_OUTOFMEMORY;

 // Loop
 int i = 0;
 for (i=0; i< iSize; i++)
 {
  swprintf( (*pwszString)+(i*(2+iSep)), L"%02X%s", pBuffer[i],  (i!=(iSize-1)) ? wszSep : L"" );
 }
 return S_OK;
}

This takes whats in the pBuffer and encodes the wide buffer with ascii. I use typedef const unsigned short* LPCWSTR; because that type does not exist in the nutcracker.

I can post more if you need to see more code.

Thanks.

A: 

Why would you use the WSTR types at all in nutcracker / the linux build? Most unixes and linux use utf-8 for their filesystem representation, so, in the non windows builds, you use sprintf, and char*'s.

Chris Becke
I tried that but I can't get it to work the same way. I have to send the results of that function over to a server and it expects it to be wide, so I can't.
Dixon Steel
A: 

It is a bit hard to understand exactly what you are looking for, so I've guessed.

As the tag was "C++", not "C" I have converted it to work in a more "C++" way. I don't have a linux box to try this on, but I think it will probably compile OK.

Your description of the input data sounded like UTF-16 wide characters, so I've used a std::wstring for the input buffer. If that is wrong, change it to a std::vector of unsigned chars and adjust the formatting statement accordingly.

#include <string>
#include <vector>
#include <cerrno>
#include <iostream>
#include <iomanip>
#include <sstream>

#if !defined(S_OK)
    #define S_OK 0
    #define E_OUTOFMEMORY ENOMEM
#endif

unsigned Buff2StrASCII( 
                const std::wstring &sIn, 
                const std::wstring &sSep, 
                std::wstring &sOut)
{
    try
    {
        std::wostringstream os;

        for (size_t i=0; i< sIn.size(); i++)
        {
            if (i)
                os << sSep;
            os  << std::setw(4) << std::setfill(L'0') << std::hex
                << static_cast<unsigned>(sIn[i]);
        }
        sOut = os.str();
        return S_OK;
    }
    catch (std::bad_alloc &)
    {
        return E_OUTOFMEMORY;
    }
}


int main(int argc, char *argv[])
{
    wchar_t szIn[] = L"The quick brown fox";
    std::wstring sOut;
    Buff2StrASCII(szIn, L" - ", sOut);
    std::wcout << sOut << std::endl;
    return 0;
}
Michael J
Thank you, this was more of what I wanted to achieve, here is what I eventually used (I got help from someone who does this all the time):if(pBuffer[j] == NULL) // No data, so ascii encode the null (0x30){ //cout << "Found NUll: " << j << endl; // First wide char 0 NULL *ctemp = '0'; ctemp+=1; *ctemp = NULL; ctemp+=1; // Second wide char 0 NULL *ctemp = '0'; ctemp+=1; *ctemp = NULL; ctemp+=1; }That was the main idea. I will try yours as well.Thanks!
Dixon Steel
Sorry, that didn't format well. I want to mark yours as my answer but I am not sure how?
Dixon Steel
@Dixon There should be a hollow tick that you can click on.
Michael J