c++stdtchar

Use TCHAR in ostringstream


Okay, I'm not really a C++ person, and this will probably be downvoted to damnation as I am just reading the code and making guesses based of the other languages I know (bad I know, but I just want to compile one solution with a small change)

...

BOOL uploadFile(HWND hwnd, LPCTSTR fileName)
{
    const TCHAR* UPLOAD_SERVER  = _T("myhostname.com"); //not my real hostname, just for this question
    const TCHAR* UPLOAD_PATH    = _T("/upload.php"); 
    const TCHAR* CONFIG_FILE    = _T("config.ini");
    const TCHAR* API_KEY = _T("key");

    TCHAR szUploadServer[MAX_PATH];
    TCHAR szUploadPath[MAX_PATH];
    TCHAR szAPI[MAX_PATH];
    TCHAR szWD[MAX_PATH];

    const char*  sBoundary = "----BOUNDARYBOUNDARY----";        // boundary
    const char   sCrLf[]   = { 0xd, 0xa, 0x0 };                 // ‰üs(CR+LF)
    const TCHAR* szHeader  = 
        _T("Content-type: multipart/form-data; boundary=----BOUNDARYBOUNDARY----");

    _tgetcwd(szWD, sizeof(szWD) / sizeof(TCHAR));
    _tcsncat(szWD, _T("\\"), 1);
    _tcsncat(szWD, CONFIG_FILE, _tcslen(CONFIG_FILE));

    GetPrivateProfileString(_T("Configuration"), _T("SERVER"), UPLOAD_SERVER, szUploadServer, sizeof(szUploadServer) / sizeof(TCHAR), szWD);
    GetPrivateProfileString(_T("Configuration"), _T("PATH"), UPLOAD_PATH, szUploadPath, sizeof(szUploadPath) / sizeof(TCHAR), szWD);
    GetPrivateProfileString(_T("Configuration"), _T("API"), API_KEY, szAPI, sizeof(szAPI) / sizeof(TCHAR), szWD);
    std::ostringstream  buf;

    // -- "api" part
    buf << "--";
    buf << sBoundary;
    buf << sCrLf;
    buf << "content-disposition: form-data; name=\"api\"";
    buf << sCrLf;
    buf << sCrLf;
    buf << szAPI;
    buf << sCrLf;
    // -- "imagedata" part
    buf << "--";
    buf << sBoundary;
    buf << sCrLf;
    buf << "content-disposition: form-data; name=\"imagedata\"";
    buf << sCrLf;
    //buf << "Content-type: image/png"; // ˆê‰ž
    //buf << sCrLf;
    buf << sCrLf;

    // –{•¶: PNG ƒtƒ@ƒCƒ‹‚ð“Ç‚Ýž‚Þ
    std::ifstream png;
    png.open(fileName, std::ios::binary);
    if (png.fail()) {
        MessageBox(hwnd, _T("PNG open failed"), szTitle, MB_ICONERROR | MB_OK);
        png.close();
        return FALSE;
    }
    buf << png.rdbuf();     // read all & append to buffer
    png.close();

    // ÅŒã
    buf << sCrLf;
    buf << "--";
    buf << sBoundary;
    buf << "--";
    buf << sCrLf;

    // ƒƒbƒZ[ƒWŠ®¬
    std::string oMsg(buf.str());

... many lines later ...

HttpSendRequest(hRequest,
                szHeader,
                lstrlen(szHeader),
                (LPVOID)oMsg.c_str(),
                (DWORD) oMsg.length())

So, as you can see, the program is reading an ini file, writing the API key to szAPI, and then I need to use it in the ostringstream (buf). When I look at the POST variables in PHP, it gives me an 8 digit hex "0019EEE0" when I'd like it to be giving a 32 character long alphanumeric string in the ini file. I looked in how to convert tchar to string, but nothing really worked for me. When i put

#ifndef UNICODE  
  typedef std::string szAPI; 
#else
  typedef std::wstring szAPI; 
#endif

in the header file, nothing happens, and when i put it right when the variable should convert to string, it errors (symbol cannot be overloaded with a typedef)

I would use TCHAR to make the headers, but I wouldn't know how to make work with the code to put the image in the headers right below the api header.

So I'm sort of at a loss with making this work. I need the API key to be in the ini file so I can build a zip in php with a generated ini file and an exe, then send it out so I can track who is uploading what to my server.

If you've got any ideas, thanks.


Solution

  • As you have noted, Windows use UTF16, but internet functions expect UTF8.

    char api[MAX_PATH];
    wcstombs(api, szAPI, wcslen(szAPI) + 1);
    

    This conversion will not always work.

    In general, you have to use WideCharToMultiByte to convert UTF16 to UTF8.

    Since you are using Visual Studio, you can use ATL classes for convenience.

    #include <AtlStr.h>
    
    ...
    CStringA sA = CW2A(szAPI, CP_UTF8);
    

    sA now contains UTF8 data. Use as follows:

    my_ostringstream << sA.GetString();
    

    or

    HttpSendRequest(hRequest, szHeader, lstrlen(szHeader),
        (LPVOID)sA.GetString(), (DWORD)sA.GetLength());