2013-02-25 3 views
1

다음 코드는 서명되지 않은 int 및 std :: wstring을 std :: stringstream에 읽고 쓰려고합니다.std :: stringstream에 이진 읽기/쓰기

#include <memory> 
#include <iostream> 
#include <vector> 
#include <sstream> 

class SerializationException : public std::runtime_error 
{ 
public: 
    SerializationException(const char* msg) : std::runtime_error(msg) { } 
}; 

class Serialization 
{ 
public: 
    static void Write(std::ostream& stream, const std::wstring& item) 
    { 
     Write(stream, eStdWString); 
     Write(stream, item.length()); 
     stream.write(reinterpret_cast< const char* >(item.c_str()), item.length()); 
    } 

    static std::wstring ReadWString(std::istream& stream) 
    { 
     const unsigned int type = ReadUInt32(stream); 
     if (type != eStdWString) 
     { 
      throw SerializationException("Expected eStdWString"); 
     } 
     const unsigned int length = ReadUInt32(stream); 
     std::vector<wchar_t> tmpBuf(length); 
     stream.read(reinterpret_cast< char* > (tmpBuf.data()), length); 
     return std::wstring(tmpBuf.begin(), tmpBuf.end()); 
    } 

    static void Write(std::ostream& stream, const unsigned int& item) 
    { 
     const unsigned int type = eUInt32; 
     stream.write(reinterpret_cast< const char* >(&type), sizeof(type)); 
     stream.write(reinterpret_cast< const char* >(&item), sizeof(item)); 
    } 

    static unsigned int ReadUInt32(std::istream& stream) 
    { 
     const unsigned int type = 0; 
     stream.read(reinterpret_cast< char* > (type), sizeof(type)); 
     if (type != eUInt32) 
     { 
      throw SerializationException("Expected eUInt32"); 
     } 
     const unsigned int tmp = 0; 
     stream.read(reinterpret_cast< char* > (tmp), sizeof(tmp)); 
     return tmp; 
    } 

private: 
    enum eTlvBlockTypes 
    { 
     eStdWString, 
     eUInt32 
    }; 
}; 

int main(int, char**) 
{ 
    std::wstring myStr = L"HelloWorld!"; 
    int myInt = 0xdeadbeef; 

    try 
    { 
     std::stringstream ss(std::ios_base::out | std::ios_base::in | std::ios_base::binary); 
     Serialization::Write(ss, myStr); 
     Serialization::Write(ss, myInt); 

     myInt = Serialization::ReadUInt32(ss); 
     myStr = Serialization::ReadWString(ss); 
    } 
    catch (const std::runtime_error& ex) 
    { 
     std::cout << ex.what() << std::endl; 
    } 
    return 0; 
} 

는 그러나 스트림을 읽고 나는 주장은 스트림이 NULL이기 때문에, 사람이이 이유를 설명 할 수 있고, 어떻게 그것을 해결하기 위해 실패 얻을?

편집 : 실패한 어설 션은 ReadUInt32()의 두 번째 줄입니다.

stream.read(reinterpret_cast< char* > (type), sizeof(type)); 
+0

위험을 다시 보여줍니다? – jrok

+0

업데이트 됨/편집 됨. – paulm

+2

주목할 점은 문자열과 int를 쓰면 int와 문자열을 다시 읽는 것입니다. 나는 당신이 그들 중 하나가 거꾸로 있다고 생각합니다. –

답변

4

당신은이 문제를 해결해야합니다 이것에

stream.read(reinterpret_cast< char* > (type), sizeof(type)); 

는 :

stream.read(reinterpret_cast< char* > (&type), sizeof(type)); 

그것은 그 reinterpret_cast 어디 어설 션이 실패하는

+0

당신은 무엇을 제안하겠습니까? 이 경우 사용을 피하기 위해? – paulm

+0

불행히도 때때로 불가피합니다.이 경우 std :: basic_istream :: read에서 char * 대신 void *를 사용해야한다고 생각합니다. 적어도 이런 경우를 막는 데 도움이 될 것입니다. – Slava

관련 문제