blob: a90c3a2e6405efb86a0fa3021c96bc224de75807 [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "Buffer.h"
#include "FieldTable.h"
#include <string.h>
#include <boost/format.hpp>
namespace qpid {
namespace framing {
Buffer::Buffer(char* _data, uint32_t _size)
: size(_size), data(_data), position(0) {
}
void Buffer::record(){
r_position = position;
}
void Buffer::restore(bool reRecord){
uint32_t savedPosition = position;
position = r_position;
if (reRecord)
r_position = savedPosition;
}
void Buffer::reset(){
position = 0;
}
///////////////////////////////////////////////////
void Buffer::putOctet(uint8_t i){
data[position++] = i;
assert(position <= size);
}
void Buffer::putShort(uint16_t i){
uint16_t b = i;
data[position++] = (uint8_t) (0xFF & (b >> 8));
data[position++] = (uint8_t) (0xFF & b);
assert(position <= size);
}
void Buffer::putLong(uint32_t i){
uint32_t b = i;
data[position++] = (uint8_t) (0xFF & (b >> 24));
data[position++] = (uint8_t) (0xFF & (b >> 16));
data[position++] = (uint8_t) (0xFF & (b >> 8));
data[position++] = (uint8_t) (0xFF & b);
assert(position <= size);
}
void Buffer::putLongLong(uint64_t i){
uint32_t hi = i >> 32;
uint32_t lo = i;
putLong(hi);
putLong(lo);
}
void Buffer::putInt8(int8_t i){
data[position++] = (uint8_t) i;
assert(position <= size);
}
void Buffer::putInt16(int16_t i){
putShort((uint16_t) i);
}
void Buffer::putInt32(int32_t i){
putLong((uint32_t) i);
}
void Buffer::putInt64(int64_t i){
putLongLong((uint64_t) i);
}
void Buffer::putFloat(float f){
union {
uint32_t i;
float f;
} val;
val.f = f;
putLong (val.i);
}
void Buffer::putDouble(double f){
union {
uint64_t i;
double f;
} val;
val.f = f;
putLongLong (val.i);
}
void Buffer::putBin128(uint8_t* b){
memcpy (data + position, b, 16);
position += 16;
}
uint8_t Buffer::getOctet(){
uint8_t octet = static_cast<uint8_t>(data[position++]);
assert(position <= size);
return octet;
}
uint16_t Buffer::getShort(){
uint16_t hi = (unsigned char) data[position++];
hi = hi << 8;
hi |= (unsigned char) data[position++];
assert(position <= size);
return hi;
}
uint32_t Buffer::getLong(){
uint32_t a = (unsigned char) data[position++];
uint32_t b = (unsigned char) data[position++];
uint32_t c = (unsigned char) data[position++];
uint32_t d = (unsigned char) data[position++];
assert(position <= size);
a = a << 24;
a |= b << 16;
a |= c << 8;
a |= d;
return a;
}
uint64_t Buffer::getLongLong(){
uint64_t hi = getLong();
uint64_t lo = getLong();
hi = hi << 32;
return hi | lo;
}
int8_t Buffer::getInt8(){
int8_t i = static_cast<int8_t>(data[position++]);
assert(position <= size);
return i;
}
int16_t Buffer::getInt16(){
return (int16_t) getShort();
}
int32_t Buffer::getInt32(){
return (int32_t) getLong();
}
int64_t Buffer::getInt64(){
return (int64_t) getLongLong();
}
float Buffer::getFloat(){
union {
uint32_t i;
float f;
} val;
val.i = getLong();
return val.f;
}
double Buffer::getDouble(){
union {
uint64_t i;
double f;
} val;
val.i = getLongLong();
return val.f;
}
template <>
uint64_t Buffer::getUInt<1>() {
return getOctet();
}
template <>
uint64_t Buffer::getUInt<2>() {
return getShort();
}
template <>
uint64_t Buffer::getUInt<4>() {
return getLong();
}
template <>
uint64_t Buffer::getUInt<8>() {
return getLongLong();
}
template <>
void Buffer::putUInt<1>(uint64_t i) {
putOctet(i);
}
template <>
void Buffer::putUInt<2>(uint64_t i) {
putShort(i);
}
template <>
void Buffer::putUInt<4>(uint64_t i) {
putLong(i);
}
template <>
void Buffer::putUInt<8>(uint64_t i) {
putLongLong(i);
}
void Buffer::putShortString(const string& s){
size_t slen = s.length();
uint8_t len = slen < 0x100 ? (uint8_t) slen : 0xFF;
putOctet(len);
s.copy(data + position, len);
position += len;
}
void Buffer::putMediumString(const string& s){
size_t slen = s.length();
uint16_t len = slen < 0x10000 ? (uint16_t) slen : 0xFFFF;
putShort(len);
s.copy(data + position, len);
position += len;
}
void Buffer::putLongString(const string& s){
uint32_t len = s.length();
putLong(len);
s.copy(data + position, len);
position += len;
}
void Buffer::getShortString(string& s){
uint8_t len = getOctet();
checkAvailable(len);
s.assign(data + position, len);
position += len;
}
void Buffer::getMediumString(string& s){
uint16_t len = getShort();
checkAvailable(len);
s.assign(data + position, len);
position += len;
}
void Buffer::getLongString(string& s){
uint32_t len = getLong();
checkAvailable(len);
s.assign(data + position, len);
position += len;
}
void Buffer::getBin128(uint8_t* b){
memcpy (b, data + position, 16);
position += 16;
}
void Buffer::putRawData(const string& s){
uint32_t len = s.length();
s.copy(data + position, len);
position += len;
}
void Buffer::getRawData(string& s, uint32_t len){
checkAvailable(len);
s.assign(data + position, len);
position += len;
}
void Buffer::putRawData(const uint8_t* s, size_t len){
memcpy(data + position, s, len);
position += len;
}
void Buffer::getRawData(uint8_t* s, size_t len){
checkAvailable(len);
memcpy(s, data + position, len);
position += len;
}
void Buffer::dump(std::ostream& out) const {
for (uint32_t i = position; i < size; i++)
{
if (i != position)
out << " ";
out << boost::format("%02x") % ((unsigned) (uint8_t) data[i]);
}
}
std::ostream& operator<<(std::ostream& out, const Buffer& b){
out << "Buffer[";
b.dump(out);
return out << "]";
}
}}