pm100
pm100

Reputation: 50210

C++ any standard library for reading binary values from a stream

I mean say I have a file that contains 4 bytes 0x2a x00 0x00 0x00

I would like to go (assuming f is an open ifstream)

uint32_t x;
f >> x;

and have x contain 42

I know this doesn't work but it seems like such an obvious thing to do it is surprising that it isn't in the standard. For example an open flag that says ios::binaryio.

The suggested thing is usually

f.read(reinterpret_cast<char*>(&x), sizeof(x));

which is plain ugly and unsafe

Upvotes: 0

Views: 99

Answers (2)

Pierre-Olivier
Pierre-Olivier

Reputation: 51

Not yet standard I guess... But you can easily find one or write it yourself. Here's an example found on GitHub

Here's another:

class StreamUtility
{
public:
    StreamUtility();
    StreamUtility(const StreamUtility&) = delete;
    StreamUtility& operator=(const StreamUtility&) = delete;
    ~StreamUtility() = default;
    
    enum endianness{ eBigEndian=0, eLittleEndian };
    
    static endianness getLocalMachineByteOrder();
    endianness getStreamFormat() const {return mStreamFormat;}
    bool readBytes(std::istream& iStream, size_t iNumberOfBytesToRead, char *oV);
    bool readBytes(std::istream& iStream, size_t iNumberOfBytesToRead, std::string *oV);
    bool readChar(std::istream& iStream, size_t iNumberOfCharToRead, std::string *oV);
    bool readDouble(std::istream& iStream, double *oV);
    bool readFloat32(std::istream& iStream, float *oV);
    bool readInt8(std::istream& iStream, int8_t *oV);
    bool readInt16(std::istream& iStream, int16_t *oV);
    bool readInt32(std::istream& iStream, int32_t *oV);
    bool readInt64(std::istream& iStream, int64_t *oV);
    bool readUint8(std::istream& iStream, uint8_t *oV);
    bool readUint16(std::istream& iStream, uint16_t *oV);
    bool readUint32(std::istream& iStream, uint32_t *oV);
    bool readUint64(std::istream& iStream, uint64_t *oV);

    void setStreamFormat(endianness);

    void write(std::ostream& iStream, ByteArray);
    void write(std::ostream& iStream, int8_t);
    void write(std::ostream& iStream, int16_t);
    void write(std::ostream& iStream, int32_t);
    void write(std::ostream& iStream, int64_t);
    void write(std::ostream& iStream, uint8_t);
    void write(std::ostream& iStream, uint16_t);
    void write(std::ostream& iStream, uint32_t);
    void write(std::ostream& iStream, uint64_t);
    void write(std::ostream& iStream, float);
    void write(std::ostream& iStream, double);
    void write(std::ostream& iStream, size_t iNumberOfBytesToWrite, const char *ipData);
    void writeBytes(std::ostream& iStream, const std::string& iData);
    void writeChar(std::ostream& iStream, const std::string& iData);
    
protected:
    bool needsSwapping() const;
    void swapBytes2(void* iV);
    void swapBytes4(void* iV);
    void swapBytes8(void* iV);
    
    endianness mStreamFormat;
};

Upvotes: 0

Acorn
Acorn

Reputation: 26186

is there still no library standard for reading binary values from a stream

There are two: the C API and the C++ one.

which is plain ugly

It is always possible to wrap those calls into a more elegant interface tailored to what you need.

and unsafe

The wrapper can also take care of that.

Upvotes: 2

Related Questions