26 #ifndef EPICS_ALWAYS_INLINE 27 # define EPICS_ALWAYS_INLINE inline 33 #if defined(__clang__) 35 #if __has_builtin(__builtin_bswap16) 36 #define _PVA_swap16(X) __builtin_bswap16(X) 38 #if __has_builtin(__builtin_bswap32) 39 #define _PVA_swap32(X) __builtin_bswap32(X) 41 #if __has_builtin(__builtin_bswap64) 42 #define _PVA_swap64(X) __builtin_bswap64(X) 45 #elif defined(__GNUC__) && ((__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=3)) 47 #if (__GNUC__>4) || (__GNUC__==4 && __GNUC_MINOR__>=8) 48 #define _PVA_swap16(X) __builtin_bswap16(X) 51 #define _PVA_swap32(X) __builtin_bswap32(X) 52 #define _PVA_swap64(X) __builtin_bswap64(X) 54 #elif defined(_MSC_VER) 56 #define _PVA_swap16(X) _byteswap_ushort(X) 57 #define _PVA_swap32(X) _byteswap_ulong(X) 58 #define _PVA_swap64(X) _byteswap_uint64(X) 62 namespace epics {
namespace pvData {
109 return _PVA_swap16(v);
111 return (((v) >> 8) | ((v) << 8));
119 return _PVA_swap32(v);
121 return ((((v) & 0xff000000) >> 24) |
122 (((v) & 0x00ff0000) >> 8) |
123 (((v) & 0x0000ff00) << 8) |
124 (((v) & 0x000000ff) << 24));
132 return _PVA_swap64(v);
136 return (((v) >> 56) | \
137 (((v) >> 40) & 0x0000ff00) | \
138 (((v) >> 24) & 0x00ff0000) | \
139 (((v) >> 8) & 0xff000000) | \
140 (((v) << 8) & ((uint64_t)0xff << 32)) | \
141 (((v) << 24) & ((uint64_t)0xff << 40)) | \
142 (((v) << 40) & ((uint64_t)0xff << 48)) | \
165 char bytes[
sizeof(T)];
173 for(
unsigned i=0, N=
sizeof(T);
i<N;
i++) {
182 for(
unsigned i=0, N=
sizeof(T);
i<N;
i++) {
193 *
reinterpret_cast<T*
>(buf) = val;
199 return *
reinterpret_cast<const T*
>(buf);
216 #define is_aligned(POINTER, BYTE_COUNT) \ 217 (((std::size_t)(POINTER)) % (BYTE_COUNT) == 0) 219 #if defined (__GNUC__) && (__GNUC__ < 3) 220 #define GET(T) get((T*)0) 222 #define GET(T) get<T>() 244 _buffer((char*)
std::malloc(size)), _size(size),
250 throw std::bad_alloc();
263 _buffer(buffer), _size(size),
269 throw std::invalid_argument(
"ByteBuffer can't be constructed with NULL");
277 if (_buffer && !_wrapped) std::free(_buffer);
305 _limit = _buffer + _size;
348 return _position - _buffer;
360 _position = _buffer + pos;
361 assert(_position<=_limit);
370 return _limit - _buffer;
383 _limit = _buffer + limit;
384 assert(_position<=_limit);
393 return _limit - _position;
418 inline void put(std::size_t index, T value)
const;
425 #if defined (__GNUC__) && (__GNUC__ < 3) 427 inline T
get(
const T*);
441 inline T
get(std::size_t index)
const;
451 inline void put(
const char* src, std::size_t src_offset, std::size_t count) {
452 assert(count<=getRemaining());
453 memcpy(_position, src + src_offset, count);
465 inline void get(
char* dest, std::size_t dest_offset, std::size_t count) {
466 assert(count<=getRemaining());
467 memcpy(dest + dest_offset, _position, count);
478 inline void putArray(
const T* values, std::size_t count);
487 inline void getArray(T* values, std::size_t count);
495 return sizeof(T)>1 && _reverseEndianess;
504 inline void align(std::size_t size,
char fill=
'\0')
506 const std::size_t k = size - 1, bufidx = (std::size_t)_position;
508 std::size_t npad = size-(bufidx&k);
509 assert(npad<=getRemaining());
510 std::fill(_position, _position+npad, fill);
709 const std::size_t _size;
710 bool _reverseEndianess;
711 bool _reverseFloatEndianess;
736 return _reverseFloatEndianess;
742 return _reverseFloatEndianess;
750 assert(
sizeof(T)<=getRemaining());
753 value = swap<T>(value);
756 _position +=
sizeof(T);
762 assert(_buffer+index<=_limit);
765 value = swap<T>(value);
770 #if defined (__GNUC__) && (__GNUC__ < 3) 778 assert(
sizeof(T)<=getRemaining());
780 T
value = detail::load_unaligned<T>(_position);
781 _position +=
sizeof(T);
784 value = swap<T>(value);
791 assert(_buffer+index<=_limit);
793 T
value = detail::load_unaligned<T>(_buffer + index);
796 value = swap<T>(value);
803 size_t n =
sizeof(T)*count;
804 assert(n<=getRemaining());
807 for(std::size_t
i=0;
i<count;
i++) {
811 memcpy(_position, values, n);
819 size_t n =
sizeof(T)*count;
820 assert(n<=getRemaining());
823 for(std::size_t
i=0;
i<count;
i++) {
824 values[
i] = swap<T>(detail::load_unaligned<T>(_position+
i*
sizeof(T)));
827 memcpy(values, _position, n);
EPICS_ALWAYS_INLINE bool getBoolean(std::size_t index)
#define EPICS_FLOAT_WORD_ORDER
#define assert(exp)
Declare that a condition should be true.
EPICS_ALWAYS_INLINE void store_unaligned(char *buf, T val)
std::tr1::shared_ptr< detail::SharedPut > put
EPICS_ALWAYS_INLINE int32 getInt(std::size_t index)
static EPICS_ALWAYS_INLINE double from(uint64 v)
EPICS_ALWAYS_INLINE int8 getByte()
EPICS_ALWAYS_INLINE T swap(T val)
EPICS_ALWAYS_INLINE float getFloat(std::size_t index)
An EPICS-specific replacement for ANSI C's assert.
ByteBuffer(char *buffer, std::size_t size, int byteOrder=EPICS_BYTE_ORDER)
EPICS_ALWAYS_INLINE void putInt(int32 value)
const char * getBuffer() const
std::size_t getLimit() const
EPICS_ALWAYS_INLINE void putDouble(std::size_t index, double value)
EPICS_ALWAYS_INLINE int8 getByte(std::size_t index)
TODO only here because of the Lockable.
EPICS_ALWAYS_INLINE void putBoolean(std::size_t index, bool value)
Mark external symbols and entry points for shared libraries.
EPICS_ALWAYS_INLINE std::size_t getSize() const
EPICS_ALWAYS_INLINE double getDouble(std::size_t index)
void align(std::size_t size, char fill='\0')
std::size_t getPosition() const
static EPICS_ALWAYS_INLINE float from(uint32 v)
static EPICS_ALWAYS_INLINE uint32 to(float v)
void putArray(const T *values, std::size_t count)
EPICS_ALWAYS_INLINE int32 getInt()
ByteBuffer(std::size_t size, int byteOrder=EPICS_BYTE_ORDER)
void setPosition(std::size_t pos)
EPICS_ALWAYS_INLINE T load_unaligned(const char *buf)
EPICS_ALWAYS_INLINE void putFloat(float value)
EPICS_ALWAYS_INLINE double getDouble()
EPICS_ALWAYS_INLINE int16 getShort(std::size_t index)
EPICS_ALWAYS_INLINE int64 getLong(std::size_t index)
EPICS_ALWAYS_INLINE void putByte(int8 value)
This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
EPICS_ALWAYS_INLINE int16 getShort()
static EPICS_ALWAYS_INLINE uint16 op(uint16 v)
EPICS_ALWAYS_INLINE void putInt(std::size_t index, int32 value)
std::size_t getRemaining() const
EPICS_ALWAYS_INLINE const char * getArray() const EPICS_DEPRECATED
static uint64 op(uint64 v)
::epics::pvAccess::Destroyable Destroyable EPICS_DEPRECATED
EPICS_ALWAYS_INLINE void putByte(std::size_t index, int8 value)
static EPICS_ALWAYS_INLINE uint64 to(double v)
EPICS_ALWAYS_INLINE void putFloat(std::size_t index, float value)
EPICS_ALWAYS_INLINE bool getBoolean()
void setEndianess(int byteOrder)
EPICS_ALWAYS_INLINE int64 getLong()
EPICS_ALWAYS_INLINE void putDouble(double value)
static EPICS_ALWAYS_INLINE T to(T v)
void put(const char *src, std::size_t src_offset, std::size_t count)
ChannelPut::shared_pointer op
EPICS_ALWAYS_INLINE void putBoolean(bool value)
Compiler specific declarations.
EPICS_ALWAYS_INLINE bool reverse() const
void setLimit(std::size_t limit)
EPICS_ALWAYS_INLINE void putLong(int64 value)
#define EPICS_ALWAYS_INLINE
EPICS_ALWAYS_INLINE void putShort(int16 value)
EPICS_ALWAYS_INLINE float getFloat()
static EPICS_ALWAYS_INLINE T from(T v)
static EPICS_ALWAYS_INLINE uint32 op(uint32 v)
static EPICS_ALWAYS_INLINE uint8 op(uint8 v)
EPICS_ALWAYS_INLINE void putShort(std::size_t index, int16 value)
EPICS_ALWAYS_INLINE void putLong(std::size_t index, int64 value)