Commit aa1fe13e authored by legoc's avatar legoc

Modified PortableByteArray to include decode

parent 74d2c386
......@@ -19,8 +19,8 @@
#ifndef COMMON_PORTABLEBYTEARRAY_H_
#define COMMON_PORTABLEBYTEARRAY_H_
#include "BaseTypes.h"
#include "Endian.h"
#include <vector>
namespace common {
......@@ -52,25 +52,25 @@ struct SerializeType<int64_t> {
struct BasePortableByteArray {
static inline int16 reverseInt16(int16 value) {
return (int32) ((value >> 8 & 0xff) |
static inline int16_t reverseInt16(int16_t value) {
return (int32_t) ((value >> 8 & 0xff) |
(value >> 0 & 0xff) << 8);
}
static inline int32 reverseInt32(int32 value) {
return (int32) ((value >> 24 & 0xff) |
static inline int32_t reverseInt32(int32_t value) {
return (int32_t) ((value >> 24 & 0xff) |
(value >> 16 & 0xff) << 8 |
(value >> 8 & 0xff) << 16 |
(value >> 0 & 0xff) << 24);
}
static inline int64 reverseInt64(int64 value) {
return (int64) ((value >> 56 & 0xff) |
static inline int64_t reverseInt64(int64_t value) {
return (int64_t) ((value >> 56 & 0xff) |
(value >> 48 & 0xff) << 8 |
(value >> 40 & 0xff) << 16 |
(value >> 32 & 0xff) << 24 |
((int64)(value >> 24 & 0xff) << 0 |
((int64_t)(value >> 24 & 0xff) << 0 |
(value >> 16 & 0xff) << 8 |
(value >> 8 & 0xff) << 16 |
(value & 0xff) << 24) << 32 );
......@@ -103,36 +103,7 @@ public:
void encode(const Type * data, std::size_t size, std::string & encodedString, int outputEndian = LITTLE_ENDIAN_ORDER);
void encodeError(EncodedType type, std::string & encodedString, int outputEndian = LITTLE_ENDIAN_ORDER);
// static inline size_t byte_size(void * encoded_data) {
// // the size of the portable_byte_array is the size of the original array in bytes + 8
// if (type(encoded_data) == FLOAT64_TYPE || type(encoded_data) == INT64_TYPE) {
// return array_size(encoded_data)*8+8;
// } else {
// return array_size(encoded_data)*4+8;
// }
// }
//
// static inline size_t array_size(void * encoded_data) {
// size_t size;
// size = ((int32_t *)encoded_data)[1];
//
// // check if the data is not in the same endianness
// if (((int16_t *)encoded_data)[0] != 1) {
// size = reverseInt32(size);
// }
// return size;
// }
// static inline EncodedType type(void * encoded_data) {
// EncodedType type;
//
// type = (EncodedType) ((int16_t *)encoded_data)[1];
//
// // check if the data is not in the same endianness
// if (((int16_t *)encoded_data)[0] != 1) {
// type = (EncodedType)reverseInt16((int16_t)type);
// }
// return type;
// }
std::vector<Type> decode(const std::string & encodedString);
};
template<typename Type>
......@@ -150,36 +121,33 @@ void PortableByteArray<Type>::encode(const Type * data, std::size_t size, std::s
// Check reverse.
if (needReverse(outputEndian)) {
// We have to serialize with reversing bytes.
((int16 *)array)[0] = reverseInt16(1);
((int16 *)array)[1] = reverseInt16(type);
((int32 *)array)[1] = reverseInt32(size);
((int16_t *)array)[0] = reverseInt16(1);
((int16_t *)array)[1] = reverseInt16(type);
((int32_t *)array)[1] = reverseInt32(size);
if (type == FLOAT32_TYPE || type == INT32_TYPE) {
int32 tmp;
for (int i = 0; i < size; i++) {
tmp = reverseInt32((((int32 *)data)[i]));
int32_t tmp = reverseInt32((((int32_t *)data)[i]));
// The real array start at byte 8.
memcpy(&((int32 *)array)[i + 2], &tmp, sizeof(int32));
memcpy(&((int32_t *)array)[i + 2], &tmp, sizeof(int32_t));
}
}
else if (type == FLOAT64_TYPE || type == INT64_TYPE) {
int64 tmp;
for (int i = 0; i < size; i++) {
int64 tmp;
tmp = reverseInt64((((int64 *)data)[i]));
int64_t tmp = reverseInt64((((int64_t *)data)[i]));
// The real array start at byte 8.
memcpy(&((int64 *)array)[i + 1], &tmp, sizeof(int64));
memcpy(&((int64_t *)array)[i + 1], &tmp, sizeof(int64_t));
}
}
}
else {
((int16 *)array)[0] = 1;
((int16 *)array)[1] = type;
((int32 *)array)[1] = size;
memcpy((int8 *)array + 8, data, size * byteSize);
((int16_t *)array)[0] = 1;
((int16_t *)array)[1] = type;
((int32_t *)array)[1] = size;
memcpy((int8_t *)array + 8, data, size * byteSize);
}
}
......@@ -195,16 +163,73 @@ void PortableByteArray<Type>::encodeError(EncodedType type, std::string & encode
// Check reverse.
if (needReverse(outputEndian)) {
// We have to serialize with reversing bytes.
((int16 *)array)[0] = reverseInt16(1);
((int16 *)array)[1] = reverseInt16(type);
((int32 *)array)[1] = reverseInt32(0);
((int16_t *)array)[0] = reverseInt16(1);
((int16_t *)array)[1] = reverseInt16(type);
((int32_t *)array)[1] = reverseInt32(0);
}
else {
((int16 *)array)[0] = 1;
((int16 *)array)[1] = type;
((int16_t *)array)[0] = 1;
((int16_t *)array)[1] = type;
}
}
template<typename Type>
std::vector<Type> PortableByteArray<Type>::decode(const std::string & encodedString) {
std::vector<Type> array;
// Get the allocated array.
char const * data = encodedString.data();
// The value "1" means that we have the same endianness.
if (((int16_t *)data)[0] == 1) {
EncodedType type = (EncodedType)(((int16_t *)data)[1]);
if (SerializeType<Type>::value != type) {
std::cerr << "Problem with type" << std::endl;
return array;
}
std::size_t size = ((int32_t *)data)[1];
int16_t byteSize = (type == FLOAT64_TYPE || type == INT64_TYPE) ? 8 : 4;
array.resize(size);
memcpy(array.data(), (int8_t *)data + 8, size * byteSize);
// We have to reverse bytes.
}
else {
EncodedType type = (EncodedType)reverseInt16(((int16_t *)data)[1]);
if (SerializeType<Type>::value != type) {
std::cerr << "Problem with type" << std::endl;
return array;
}
std::size_t size = reverseInt32(((int32_t *)data)[1]);
if (type == FLOAT32_TYPE || type == INT32_TYPE) {
array.resize(size);
Type * arrayData = array.data();
for (int i = 0; i < size; i++) {
int32_t tmp = reverseInt32(((int32_t *)data)[i + 2]);
memcpy(&((int32_t *)arrayData)[i], &tmp, sizeof(int32_t));
}
}
else if (type == FLOAT64_TYPE || type == INT64_TYPE) {
array.resize(size);
Type * arrayData = array.data();
for (int i = 0; i < size; i++) {
int64_t tmp = reverseInt64(((int64_t *)data)[i+1]);
memcpy(&((int64_t *)arrayData)[i], &tmp, sizeof(int64_t));
}
}
}
return array;
}
}
#endif
......@@ -326,33 +326,6 @@ void DatabaseResponder::processGetArraySize(const std::string & message, std::st
responseMessage.SerializeToString(&response);
}
//void DatabaseResponder::processGetInt32Array(const std::string & message, std::string & response) {
//
// database::GetValueRequest messageRequest;
// messageRequest.ParseFromString(message);
//
// common::Int32ArrayResponse responseMessage;
//
// try {
// vector<int32> values;
// m_propertyAccessor->getIcsInt32ArrayValue(messageRequest.databaseid(), messageRequest.propertyid(), values);
//
// vector<int32>::const_iterator end = values.end();
// for (vector<int32>::const_iterator v = values.begin(); v != end; ++v) {
// responseMessage.add_value(*v);
// }
// }
// catch (PropertyAccessorDirectImpl::NoSuchPropertyException& e) {
// responseMessage.set_error(common::Error::NO_SUCH_PROPERTY);
// }
// catch (PropertyAccessorDirectImpl::BadPropertyTypeException& e) {
// responseMessage.set_error(common::Error::BAD_PROPERTY_TYPE);
// }
//
// // Serialize the response.
// responseMessage.SerializeToString(&response);
//}
void DatabaseResponder::processGetInt32Array(const std::string & message, std::string & response) {
database::GetValueRequest messageRequest;
......@@ -361,33 +334,6 @@ void DatabaseResponder::processGetInt32Array(const std::string & message, std::s
m_propertyAccessor->getEncodedInt32ArrayValue(messageRequest.databaseid(), messageRequest.propertyid(), response);
}
//void DatabaseResponder::processGetFloat64Array(const std::string & message, std::string & response) {
//
// database::GetValueRequest messageRequest;
// messageRequest.ParseFromString(message);
//
// common::Float64ArrayResponse responseMessage;
//
// try {
// vector<float64> values;
// m_propertyAccessor->getIcsFloat64ArrayValue(messageRequest.databaseid(), messageRequest.propertyid(), values);
//
// vector<float64>::const_iterator end = values.end();
// for (vector<float64>::const_iterator v = values.begin(); v != end; ++v) {
// responseMessage.add_value(*v);
// }
// }
// catch (PropertyAccessorDirectImpl::NoSuchPropertyException& e) {
// responseMessage.set_error(common::Error::NO_SUCH_PROPERTY);
// }
// catch (PropertyAccessorDirectImpl::BadPropertyTypeException& e) {
// responseMessage.set_error(common::Error::BAD_PROPERTY_TYPE);
// }
//
// // Serialize the response.
// responseMessage.SerializeToString(&response);
//}
void DatabaseResponder::processGetFloat64Array(const std::string & message, std::string & response) {
database::GetValueRequest messageRequest;
......
......@@ -24,6 +24,7 @@
#include <common/base/Convert.h>
#include <common/base/PropertyType.h>
#include <common/base/TypeToString.h>
#include <common/base/PortableByteArray.h>
#include <iostream>
#include <string>
......@@ -62,6 +63,64 @@ BOOST_AUTO_TEST_CASE(testPrint1)
cout << TypeToString<Array<float64> >::convert() << endl;
cout << TypeToString<Array<bool> >::convert() << endl;
cout << TypeToString<Array<string> >::convert() << endl;
cout << "Portable byte array" << endl;
{
int32 intArray[] = {100, -21, 5665787, 45, 9898};
common::PortableByteArray<int32> portableByteArray;
string encodedString;
portableByteArray.encode(intArray, 5, encodedString, common::LITTLE_ENDIAN_ORDER);
vector<int32> resultArray = portableByteArray.decode(encodedString);
cout << "result size = " << resultArray.size() << endl;
for (int i = 0; i < 5; ++i) {
cout << resultArray[i] << ", ";
}
cout << endl;
portableByteArray.encode(intArray, 5, encodedString, common::BIG_ENDIAN_ORDER);
resultArray = portableByteArray.decode(encodedString);
cout << "result size = " << resultArray.size() << endl;
for (int i = 0; i < 5; ++i) {
cout << resultArray[i] << ", ";
}
cout << endl;
}
{
float64 floatArray[] = {100.1, -21.2, 5665787.3, 45.4, 9898.5};
common::PortableByteArray<float64> portableByteArray;
string encodedString;
portableByteArray.encode(floatArray, 5, encodedString, common::LITTLE_ENDIAN_ORDER);
vector<float64> resultArray = portableByteArray.decode(encodedString);
cout << "result size = " << resultArray.size() << endl;
for (int i = 0; i < 5; ++i) {
cout << resultArray[i] << ", ";
}
cout << endl;
portableByteArray.encode(floatArray, 5, encodedString, common::BIG_ENDIAN_ORDER);
resultArray = portableByteArray.decode(encodedString);
cout << "result size = " << resultArray.size() << endl;
for (int i = 0; i < 5; ++i) {
cout << resultArray[i] << ", ";
}
cout << endl;
}
}
BOOST_AUTO_TEST_SUITE_END();
\ No newline at end of file
BOOST_AUTO_TEST_SUITE_END();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment