Search code examples
c++boostbufferifstream

Passing ifstream created from embedded resource file to boost XML parser


I am trying to parse an embedded resource XML file:

HRSRC hresinfo = FindResource(hInstance, MAKEINTRESOURCE(IDR_XML1), _T("XML"));
if (hresinfo)
{
    HGLOBAL hRes = LoadResource(hInstance, hresinfo);
    DWORD datasize = SizeofResource(hInstance, hresinfo); // this size is correct
    LPVOID data = LockResource(hRes);

    if (hRes && datasize != 0 && data) {
        ifstream in;
        in.rdbuf()->pubsetbuf((char*)data, datasize);

        streamsize size = in.rdbuf()->in_avail();
        printf("size=%d", size); // this size is 0
        
        pt::read_xml(in, tree); // parses nothing
    }
    else {
        printf("error: %d\n", GetLastError());
    }
}

memcpy'ing the data into a regular buffer and printing each char works which leads me to believe the problem is with the ifstream.


Solution

  • I think that pubsetbuf doesn't do what you need (however, I don't fully understand what it does exactly). To set std::ifstream content as it was loaded from the real file you can do the following:

        std::ifstream in;
        std::stringstream ss{std::string((char*)data, datasize)};
        in.basic_ios<char>::rdbuf(ss.rdbuf());
        std::string str;
        in >> str;  // to check if ifstream has expected content
        std::cout << "str = " << str << std::endl;
    

    Your ifstream will share the same content as stringstream created from the raw memory block pointed by data.

    EDIT

    Sorry, forget std::ifstream. I see that pt::read_xml accepts std::basic_istream, so just pass std::stringstream directly.