Currently trying to create an XML system using Ogre and the STL. As a proof of concept, we are trying to get it to output the contents of the XML file to our log file. Sadly our current code won't compile, and we don't know why. Relevant code follows:
Here is a stream class that we have inherited from to simplify management of a custom streambuf. The main reason it exists it to delete the custom streambuf in it's destructor.
class ResourceInputStream : public std::istream
{
private:
internal::OgreDataStreamBuf* OgreBuffer;
ResourceManager* Manager;
/// @internal
/// @brief Called by the constructors to actually construct this class
/// @param InputBuffer A pointer to an internal::OgreDataStreamBuf. A buffer to read from the disk access subsystem (which happens to be part of Ogre). This Stream will assume ownership of this buffer and will handle deleting it.
/// @param ResourceManager_ Currently unused, future functionality may tuse this.
void Construct(std::streambuf *InputBuffer, ResourceManager* ResourceManager_);
protected:
public:
/// @brief Descriptive Constructor
/// @param InputBuffer A pointer to an internal::OgreDataStreamBuf. A buffer to read from the disk access subsystem (which happens to be part of Ogre). This Stream will assume ownership of this buffer and will handle deleting it.
/// @param ResourceManager_ Currently unused, future functionality may tuse this.
/// @warning Do not delete the InputBuffer you pass in, this class will assume owner ship and delete it on it's own
ResourceInputStream(std::streambuf *InputBuffer, ResourceManager* ResourceManager_) :
std::istream(InputBuffer)
{ this->Construct(InputBuffer, ResourceManager_); }
/// @brief Tears down the Stream, and Delete the Buffer Passed in.
virtual ~ResourceInputStream();
};
Here is the definition for the custom streambuf class. It uses an ogreDatastreambuf to read from zipped files in that are managed by the Ogre resource library:
class OgreDataStreamBuf : public std::streambuf
{
protected:
/// @brief a shard_ptr to the internal Ogre Datastream
Ogre::DataStreamPtr OgreStream;
public:
/// @brief constructor
/// @param Datum A pointer to the Ogre Datastream that this stream will use
OgreDataStreamBuf(const Ogre::DataStreamPtr& Datum) : OgreStream(Datum)
{
#ifdef PHYSDEBUG
World::GetWorldPointer()->Log("Entering/Exiting OgreDataStreamBuf Constructor");
#endif
}
/// @brief Should get the amount of characters left in the sequence
/// @returns -1 if no estimate could be made, other wise this returns an estimate of the amount of bytes in the buffer
std::streamsize showmanyc();
/// @brief Gets a sequence of characters
/// @param s a Pointer to where the characters should go
/// @param n How many characters
/// @return This returns the amount of characters retrieved
std::streamsize xsgetn(char* s, std::streamsize n);
/// @brief puts a sequence of characters in
/// @param s a Pointer to the characters
/// @param n How many characters
/// @return This returns the amount of characters inserted
/// @detail currently unimplimented
std::streamsize xsputn(const char_type*, std::streamsize n);
};
}
Here is The piece of code attempting to use this stream class. TheWorld->LogStream is a std::stringstream.
ResourceInputStream* XMLptr = TheWorld->GetResourceManager()->GetResourceStream("test.xml");
std::stringstream XMLStringStream;
(*XMLptr) >> XMLStringStream;
String ShouldHaveXML(XMLStringStream.str());
TheWorld->LogStream << "ShouldHaveXML: " << ShouldHaveXML << endl << "End XML Logging" <<endl;
TheWorld->Log("Delete XML Stream");
delete XMLptr;
Attempting to compile produces this error:
error: ambiguous overload for 'operator>>' in '* XMLptr >> XMLStringStream'
I've researched this error, and the only thing I can find about this... it's due to something being declared const that shouldn't. That isn't the case with our code as far as we can tell. So I'm at a loss as to why this is happening, or how to go about fixing it. Any insights would be greatly appreciated.
It would appear that there is a lot of extra unneeded information here, The crux of the issue is that there is no streaming operator to got from an istream >> to an ostream.
All the Ogre and custom class stuff was simply not required, in the mean time we managed to get our data out of the class using s simple workaround:
ResourceInputStream* XMLptr = TheWorld->GetResourceManager()->GetResourceStream("test.xml");
char chararray[401];
chararray[400]='\0';
XMLptr->read(chararray, 400);
String ShouldHaveXML( chararray );
This is just test code, I would always suggest using istream::gcount before assuming you read the amount of data you requested.