Files
pvData/pvDataApp/misc/byteBuffer.h
Matej Sekoranja 7cf33be144 byteBuffer added
2010-10-21 14:28:34 +02:00

303 lines
10 KiB
C++

/* byteBuffer.h */
#ifndef BYTEBUFFER_H
#define BYTEBUFFER_H
#include <string>
#include <epicsTypes.h>
#include <epicsEndian.h>
namespace epics {
namespace pvData {
// not sure why I have to define epicsInt64
typedef long long epicsInt64;
/** @brief A buffer of bytes.
*
* A buffer of bytes, which has
* - capacity (size)
* - limit
* - position
* The capacity is the maximum capacity of the buffer, the buffer's
* limit is the index of the first element that should not be read or
* written, and its position is the index of the next element to be
* written.
*
* The buffer also ha a byte order specified which can be little or
* big endian.
*/
class ByteBuffer {
public:
/** @brief ByteBuffer constructor.
*
* Creates a buffer of a given size, and with a specified byteOrder.
*
* @param size Specify the capacity of the buffer. Default is 32.
* @param byteOrder the byte order of the buffer. Can be either
* EPICS_ENDIAN_LITTLE or EPICS_ENDIAN_BIG.
*/
ByteBuffer(int size = 32, int byteOrder = EPICS_BYTE_ORDER);
/**
* @brief ByteBuffer destructor.
*/
~ByteBuffer();
/**
* Clears the buffer. Sets the {@code position} to 0 and {@code limit}
* to {@code capacity}.
*/
ByteBuffer* clear();
/**
* Flips the buffer. The {@code limit} is set to the current {@code position}
* and the {@code position} is set to {@code 0}. This prepares the
* buffer for a series of relative @em get operations after a series
* of relative @em put operations.
*/
ByteBuffer* flip();
/**
* Rewinds the buffer. This sets {@code position} to {@code 0}
* without affecting the {@code limit}.
*/
ByteBuffer* rewind();
/**
* Relative boolean read, {@code position} is incremented by
* {@code 1}.
*
* @returns The next byte in the buffer as a boolean.
* @throws EpicsException - Buffer underflow if there are no bytes
* remaining in the buffer.
*/
bool getBoolean();
/**
* Relative Int8 read, {@code position} is incremented by
* {@code 1}.
*
* @returns The next byte in the buffer as a signed Int8.
* @throws EpicsException - Buffer underflow if there are no bytes
* remaining in the buffer.
*/
epicsInt8 getByte();
/**
* Relative Int16 read, {@code position} is incremented by
* {@code 2}.
*
* @returns The next Int16 value in the buffer.
* @throws EpicsException - Buffer underflow if there are less than
* 2 bytes remaining in the buffer.
*/
epicsInt16 getShort();
/**
* Relative Int32 read, {@code position} is incremented by
* {@code 4}.
*
* @returns The next Int32 value in the buffer.
* @throws EpicsException - Buffer underflow if there are less than
* 4 bytes remaining in the buffer.
*/
epicsInt32 getInt();
/**
* Relative Int64 read, {@code position} is incremented by
* {@code 8}.
*
* @returns The next Int64 value in the buffer.
* @throws EpicsException - Buffer underflow if there are less than
* 8 bytes remaining in the buffer.
*/
epicsInt64 getLong();
/**
* Relative float read, {@code position} is incremented by
* {@code 4}.
*
* @returns The next float value in the buffer.
* @throws EpicsException - Buffer underflow if there are less than
* 4 bytes remaining in the buffer.
*/
float getFloat();
/**
* Relative double read, {@code position} is incremented by
* {@code 8}.
*
* @returns The next double value in the buffer.
* @throws EpicsException - Buffer underflow if there are less than
* 8 bytes remaining in the buffer.
*/
double getDouble();
//virtual String getString() = 0; // TODO
/**
* Relative boolean write, {@code position} is incremented by
* {@code 1}.
*
* @param[in] value The boolean value to write.
* @throws EpicsException - Buffer overflow if there are no
* bytes remaining in the buffer.
*/
ByteBuffer* putBoolean(bool value);
/**
* Relative Int8 write, {@code position} is incremented by
* {@code 1}.
*
* @param[in] value The Int8 value to write.
* @throws EpicsException - Buffer overflow if there are no
* bytes remaining in the buffer.
*/
ByteBuffer* putByte(epicsInt8 value);
/**
* Relative Int16 write, {@code position} is incremented by
* {@code 2}.
*
* @param[in] value The Int16 value to write.
* @throws EpicsException - Buffer overflow if there are less than
* 2 bytes remaining in the buffer.
*/
ByteBuffer* putShort(epicsInt16 value);
/**
* Relative Int32 write, {@code position} is incremented by
* {@code 4}.
*
* @param[in] value The Int32 value to write.
* @throws EpicsException - Buffer overflow if there are less than
* 4 bytes remaining in the buffer.
*/
ByteBuffer* putInt(epicsInt32 value);
/**
* Relative Int64 write, {@code position} is incremented by
* {@code 8}.
*
* @param[in] value The Int64 value to write.
* @throws EpicsException - Buffer overflow if there are less than
* 8 bytes remaining in the buffer.
*/
ByteBuffer* putLong(epicsInt64 value);
/**
* Relative float write, {@code position} is incremented by
* {@code 4}.
*
* @param[in] value The float value to write.
* @throws EpicsException - Buffer overflow if there are less than
* 4 bytes remaining in the buffer.
*/
ByteBuffer* putFloat(float value);
/**
* Relative float write, {@code position} is incremented by
* {@code 8}.
*
* @param[in] value The double value to write.
* @throws EpicsException - Buffer overflow if there are less than
* 8 bytes remaining in the buffer.
*/
ByteBuffer* putDouble(double value);
//virtual ByteBuffer *putString(String value) = 0; // TODO
/**
* The capacity (size) of the buffer in bytes.
*
* @returns The capacity of the buffer in bytes.
*/
inline int getSize() const {
return _size;
}
/**
* The offset from the start of the buffer in bytes. Currently this
* method always returns {@code 0}.
*
* @returns The offset from the start of the buffer in bytes
*/
inline int getArrayOffset() const {
return 0;
}
/**
* The byte index of the next element to @em get or @em put.
*
* @returns The byte index of the next element.
*/
inline int getPosition() const {
return _position;
}
/**
* The byte index of the {@code limit}. {@code limit} is always less
* or equal to the buffer capacity. No @em put or @em get operation
* can be performed pass the {@code limit}.
*
* @returns The byte index of the {@code limit}.
*/
inline int getLimit() const {
return _limit;
}
/**
* The number of the bytes that can be successfully read or written.
*
* @returns The number of the bytes that can be successfully read or
* written.
*/
inline int getRemaining() const {
return _limit-_position;
}
/**
* The byte order of the buffer.
*
* @returns Either {@code EPICS_ENDIAN_LITTLE} or
* {@code EPICS_ENDIAN_BIG}.
*/
inline int getByteOrder() const {
return _bufferByteOrder;
}
/**
* Gives a read-only access to the buffer.
*
* @returns A const (read-only) pointer to the actual buffer.
*/
inline const char* getArray() const {
return _buffer;
}
// TODO must define arrays
private:
int _bufferByteOrder, _size, _position, _limit;
char* _buffer;
/**
* Reads the next <pre>size</pre> bytes from the buffer and stores them
* into the destination taking into account endianness of the buffer
* and the current hardware.
*/
void getWithEndianness(char* dest, size_t size);
/**
* Puts the next <pre>size</pre> bytes into the buffer reading them
* from source taking into account endianness of the buffer
* and the current hardware.
*/
void putWithEndianness(char* src, size_t size);
};
}
}
#endif /* BYTEBUFFER_H */