Implement input_stream and output_stream classes
Opened this issue · 0 comments
avelanarius commented
Currently in serialize
and deserialize
functions I use std::istream
and std::ostream
for input/output data. To create streams backed by array/vector I use implementation from boost, however:
- It lacks some functionality, which in turn requires me to copy the data too many times.
std::ostream
backed bystd::vector
might be slower, because it has buffering (the data copied twice and need to remember toflush()
).
Implement alternatives with this specification:
class input_stream {
private:
const char *_data;
size_t _length;
size_t _current_position = 0;
public:
input_stream(const char *data, size_t *length) noexcept;
// Should read length characters
// beginning from current_position in data, copying them into destination.
// It should update the current_position (+= length).
// It should check for possible errors (out-of-bounds length).
// In case of error should throw parsing_exception.
// (parsing_exception might not be merged into zpp_kafka, so
// use some normal std::exception instead for now)
// Use std::copy instead of manual loops.
inline void read(char *destination, size_t *length);
// Get the pointer to _data starting from _current_position.
// It should throw if _current_position == _length
// (the whole stream has been read).
inline const char *get() const;
inline size_t get_position() const noexcept;
// It should also check for possible out-of-bounds.
inline void set_position(size_t new_position);
// Move current_position by delta. Check if new
// position >= 0 && < size. (else throw exception)
// Delta can be negative (go back in stream).
inline void move_position(ssize_t delta);
size_t size() const noexcept;
}
class output_stream {
private:
vector<char> _data;
size_t _current_position = 0;
bool _is_resizable;
public:
// Return a new stream with _data resized to size bytes.
// It will not be resizable.
static output_stream fixed_size_stream(size_t size);
// Return a new stream with empty _data and _is_resizable = true.
static output_stream resizable_stream();
// It should copy bytes from source into _data at
// current_position. It should add length to current_position.
//
// Example:
// _data = [0, 1, 2, 3, 4]
// _current_position = 1
// write([7, 7], 2);
// _data = [0, 7, 7, 3, 4]
// _current_position = 3
//
// If it is not resizable and we try to write
// out-of-bounds, it should throw parsing_exception.
//
// If it is resizable and we try to write out of bounds
// it should resize _data:
//
// _data = []
// _current_position = 0
// write([7, 7], 2);
// _data = [7, 7]
// _current_position = 2
inline void write(const char *source, size_t *length);
// Get the pointer to _data from _current_position.
// It should throw if _current_position == _length.
inline char *get();
inline const char *get() const;
// Get reference to _data.
inline vector<char>& get_vector() noexcept;
inline const vector<char>& get_vector() const noexcept;
inline size_t get_position() const noexcept;
// It should also check for possible out-of-bounds.
// If resizable it should resize stream (and not check).
inline void set_position(size_t new_position);
// Move current_position by delta. Check if new
// position >= 0 && < size. (else throw exception)
// If resizable it should resize stream (not checking < 0
// but checking >= 0).
inline void move_position(ssize_t delta);
size_t size() const noexcept;
}
Please also implement tests, which should test edge cases (writing/reading out-of-bounds).
The file should be header-only (no .cc
.cpp
file).