jules wrote:Yeah, those classes could certainly use some more error checking. Ideally I'd make them throw exceptions, but that'd break everyone's code...
Exceptions? No...why would you want to do that? Exceptions are good for catastrophic circumstances. For example, running out of memory. But when parsing external data, or doing some sort of validation (like in an edit box), exceptions are clunky
Adding a readInt method like you suggested makes sense, but if I add that, I should probably also add all the other variations on that for the other types, which would get a bit cluttered.. Is there perhaps some kind of templated trick that could be done to get the same functionality?
Well yeah! Of course, I implied that a Result-returning function should be available for every existing read###(). If you don't mind making these new routines non-virtual in InputStream then I think you could do something like (and this is rough):
- Code: Select all
template <class T>
T ByteOrder::toLittleEndian (char const* const data) { /*...*/ }
template <class T>
Result InputStream::read (T& value)
{
const int bytes = sizeof (T);
char temp [bytes]];
if (read (temp, bytes) == bytes)
{
value = ByteOrder::toLittleEndian <T> (temp);
return true;
}
return false;
}
Why are they virtual in InputStream to begin with?
Me personally, I wouldn't mind just seeing two functions for every one that existed previously, like this:
- Code: Select all
virtual int64 readInt64();
virtual Result readInt64(int64& value);
Once you have routines that return Result you can re-implement the read### series as inline functions:
- Code: Select all
inline int64 readInt64()
{
int64 value;
if (readInt64 (value))
return value;
return 0;
}
Happy to add a getBytesRemaining() method to MemoryInputStream though, that'd be handy.
Well that's the easy one...and I believe you can add it to InputStream by just returning getTotalBytes() - getCurrentPosition(). The more interesting function is getCurrentPositionPointer().