mirror of https://github.com/JAJames/Jupiter.git
JustinAJ
10 years ago
22 changed files with 1066 additions and 17 deletions
@ -0,0 +1,121 @@ |
|||
/**
|
|||
* Copyright (C) Justin James - All Rights Reserved. |
|||
* Unauthorized use or copying of this file via any medium is strictly prohibited. |
|||
* This document is proprietary and confidential. |
|||
* This document should be immediately destroyed unless given explicit permission by Justin James. |
|||
* Written by Justin James <justin.aj@hotmail.com> |
|||
*/ |
|||
|
|||
#include <cstdlib> |
|||
#include "DataBuffer.h" |
|||
#include "Reference_String.h" |
|||
|
|||
Jupiter::DataBuffer::DataBuffer() |
|||
{ |
|||
Jupiter::DataBuffer::base = nullptr; |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head; |
|||
Jupiter::DataBuffer::bufferSize = 0U; |
|||
} |
|||
|
|||
Jupiter::DataBuffer::DataBuffer(size_t size_) |
|||
{ |
|||
Jupiter::DataBuffer::base = reinterpret_cast<uint8_t *>(malloc(size_)); |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head; |
|||
Jupiter::DataBuffer::bufferSize = size_; |
|||
} |
|||
|
|||
Jupiter::DataBuffer::~DataBuffer() |
|||
{ |
|||
free(Jupiter::DataBuffer::base); |
|||
} |
|||
|
|||
void Jupiter::DataBuffer::push(const uint8_t *data, size_t size_) |
|||
{ |
|||
Jupiter::DataBuffer::secure(size_); |
|||
fputs("Pushing: \"", stdout); |
|||
while (size_-- != 0) |
|||
{ |
|||
fputc(*data, stdout); |
|||
*Jupiter::DataBuffer::end++ = *data++; |
|||
} |
|||
puts("\""); |
|||
} |
|||
|
|||
size_t Jupiter::DataBuffer::shrink() |
|||
{ |
|||
Jupiter::DataBuffer::bufferSize = Jupiter::DataBuffer::size(); |
|||
|
|||
if (Jupiter::DataBuffer::base != Jupiter::DataBuffer::head) |
|||
memmove(Jupiter::DataBuffer::base, Jupiter::DataBuffer::head, Jupiter::DataBuffer::bufferSize); |
|||
|
|||
Jupiter::DataBuffer::base = reinterpret_cast<uint8_t *>(realloc(Jupiter::DataBuffer::base, Jupiter::DataBuffer::bufferSize)); |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head + Jupiter::DataBuffer::bufferSize; |
|||
return Jupiter::DataBuffer::bufferSize; |
|||
} |
|||
|
|||
size_t Jupiter::DataBuffer::expandBuffer(size_t size_) |
|||
{ |
|||
Jupiter::DataBuffer::bufferSize += size_; |
|||
size_ = Jupiter::DataBuffer::end - Jupiter::DataBuffer::head; |
|||
|
|||
if (Jupiter::DataBuffer::base != Jupiter::DataBuffer::head) |
|||
memmove(Jupiter::DataBuffer::base, Jupiter::DataBuffer::head, size_); |
|||
|
|||
Jupiter::DataBuffer::base = reinterpret_cast<uint8_t *>(realloc(Jupiter::DataBuffer::base, Jupiter::DataBuffer::bufferSize)); |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head + size_; |
|||
return Jupiter::DataBuffer::bufferSize; |
|||
} |
|||
|
|||
void Jupiter::DataBuffer::secure(size_t size_) |
|||
{ |
|||
size_t data_size = Jupiter::DataBuffer::end - Jupiter::DataBuffer::head; |
|||
size_ += data_size; |
|||
if (Jupiter::DataBuffer::bufferSize < size_) |
|||
{ |
|||
if (Jupiter::DataBuffer::base != Jupiter::DataBuffer::head) |
|||
memmove(Jupiter::DataBuffer::base, Jupiter::DataBuffer::head, data_size); |
|||
|
|||
Jupiter::DataBuffer::base = reinterpret_cast<uint8_t *>(realloc(Jupiter::DataBuffer::base, size_)); |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head + data_size; |
|||
Jupiter::DataBuffer::bufferSize = size_; |
|||
} |
|||
} |
|||
|
|||
void Jupiter::DataBuffer::setBufferSize(size_t size_) |
|||
{ |
|||
Jupiter::DataBuffer::bufferSize = size_; |
|||
size_ = Jupiter::DataBuffer::end - Jupiter::DataBuffer::head; |
|||
|
|||
if (Jupiter::DataBuffer::base != Jupiter::DataBuffer::head) |
|||
memmove(Jupiter::DataBuffer::base, Jupiter::DataBuffer::head, size_); |
|||
|
|||
Jupiter::DataBuffer::base = reinterpret_cast<uint8_t *>(realloc(Jupiter::DataBuffer::base, Jupiter::DataBuffer::bufferSize)); |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head + size_; |
|||
} |
|||
|
|||
size_t Jupiter::DataBuffer::size() const |
|||
{ |
|||
return Jupiter::DataBuffer::end - Jupiter::DataBuffer::head; |
|||
} |
|||
|
|||
size_t Jupiter::DataBuffer::getBufferSize() const |
|||
{ |
|||
return Jupiter::DataBuffer::bufferSize; |
|||
} |
|||
|
|||
uint8_t *Jupiter::DataBuffer::getHead() const |
|||
{ |
|||
return Jupiter::DataBuffer::head; |
|||
} |
|||
|
|||
void Jupiter::DataBuffer::empty() |
|||
{ |
|||
Jupiter::DataBuffer::head = Jupiter::DataBuffer::base; |
|||
Jupiter::DataBuffer::end = Jupiter::DataBuffer::head; |
|||
} |
@ -0,0 +1,216 @@ |
|||
/**
|
|||
* Copyright (C) 2015 Justin James. |
|||
* |
|||
* This license must be preserved. |
|||
* Any applications, libraries, or code which make any use of any |
|||
* component of this program must not be commercial, unless explicit |
|||
* permission is granted from the original author. The use of this |
|||
* program for non-profit purposes is permitted. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|||
* |
|||
* In the event that this license restricts you from making desired use of this program, contact the original author. |
|||
* Written by Justin James <justin.aj@hotmail.com> |
|||
*/ |
|||
|
|||
#if !defined _DATABUFFER_H_HEADER |
|||
#define _DATABUFFER_H_HEADER |
|||
|
|||
/**
|
|||
* @file DataBuffer.h |
|||
* @brief Defines a simple data buffer structure. |
|||
*/ |
|||
|
|||
#include <cstdint> |
|||
#include "Jupiter.h" |
|||
|
|||
namespace Jupiter |
|||
{ |
|||
/**
|
|||
* @brief Provides a data buffer implementation intended for files and sockets. |
|||
* DataBuffer behaves as a FIFO single-directional queue. |
|||
*/ |
|||
class JUPITER_API DataBuffer |
|||
{ |
|||
public: |
|||
|
|||
/**
|
|||
* @brief Generates an object based on an input head position; the head |
|||
* will be moved if the input type can be interpreted. |
|||
* |
|||
* @return Generated object. |
|||
*/ |
|||
template<typename T> static T interpret_data(uint8_t *&head); |
|||
template<template<typename> class T, typename Y> static T<Y> interpret_data(uint8_t *&head); |
|||
template<template<typename, typename> class T, typename X, typename Y> static T<X, Y> interpret_data(uint8_t *&head); |
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> static T<X, Y, Z> interpret_data(uint8_t *&head); |
|||
|
|||
/**
|
|||
* @brief Copies data from the front of the buffer, without removing it. |
|||
* |
|||
* @param T Data type |
|||
* |
|||
* @return Sum of all the elements in the string |
|||
*/ |
|||
template<typename T> T peek() const; |
|||
template<template<typename> class T, typename Y> T<Y> peek() const; |
|||
template<template<typename, typename> class T, typename X, typename Y> T<X, Y> peek() const; |
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> T<X, Y, Z> peek() const; |
|||
|
|||
template<typename T> void peek(T &out) const; |
|||
template<template<typename> class T, typename Y> void peek(T<Y> &out) const; |
|||
template<template<typename, typename> class T, typename X, typename Y> void peek(T<X, Y> &out) const; |
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void peek(T<X, Y, Z> &out) const; |
|||
|
|||
/**
|
|||
* @brief Copies data from the front of the buffer, without removing it. |
|||
* Note: Elements will be in the opposite order than concurrent calls |
|||
* to peek() would produce. |
|||
* |
|||
* @param T Data type |
|||
* @param size Number of elements to pop |
|||
* |
|||
* @return Sum of all the elements in the string |
|||
*/ |
|||
template<typename T> T *peek(size_t size) const; |
|||
|
|||
/**
|
|||
* @brief Copies data from the front of the buffer and removes it. |
|||
* |
|||
* @param T Data type |
|||
* |
|||
* @return Sum of all the elements in the string |
|||
*/ |
|||
template<typename T> T pop(); |
|||
template<template<typename> class T, typename Y> T<Y> pop(); |
|||
template<template<typename, typename> class T, typename X, typename Y> T<X, Y> pop(); |
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> T<X, Y, Z> pop(); |
|||
|
|||
template<typename T> void pop(T &out); |
|||
template<template<typename> class T, typename Y> void pop(T<Y> &out); |
|||
template<template<typename, typename> class T, typename X, typename Y> void pop(T<X, Y> &out); |
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void pop(T<X, Y, Z> &out); |
|||
|
|||
/**
|
|||
* @brief Copies data from the front of the buffer and removes it. |
|||
* Note: Elements will be in the opposite order than concurrent calls |
|||
* to pop() would produce. |
|||
* |
|||
* @param T Data type |
|||
* @param size Number of elements to pop |
|||
* |
|||
* @return Sum of all the elements in the string |
|||
*/ |
|||
template<typename T> T *pop(size_t size); |
|||
|
|||
/**
|
|||
* @brief Adds data to the front of the buffer. |
|||
* |
|||
* @param T Data type |
|||
* @param data Data to add to the buffer |
|||
*/ |
|||
template<typename T> void push(const T *data); |
|||
template<typename T> void push(const T &data); |
|||
|
|||
// Specialization: Jupiter::ReadableString + Sub classes
|
|||
template<template<typename> class T, typename Y> void push(const T<Y> *data); |
|||
template<template<typename> class T, typename Y> void push(const T<Y> &data); |
|||
|
|||
// SPECIALIZATION TODO: std::deque - std::list - std::forward_list
|
|||
|
|||
// SPECIALIZATION: std::array
|
|||
template<template<typename, size_t> class T, typename X, size_t Y> void push(const T<X, Y> *data); |
|||
template<template<typename, size_t> class T, typename X, size_t Y> void push(const T<X, Y> &data); |
|||
|
|||
// SPECIALIZATION: std::vector
|
|||
template<template<typename, typename> class T, typename X, typename Y> void push(const T<X, Y> *data); |
|||
template<template<typename, typename> class T, typename X, typename Y> void push(const T<X, Y> &data); |
|||
|
|||
// SPECIALIZATION: std::basic_string (std::string / std::wstring / etc)
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void push(const T<X, Y, Z> *data); |
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void push(const T<X, Y, Z> &data); |
|||
|
|||
/**
|
|||
* @brief Adds data to the end of the buffer. |
|||
* |
|||
* @param data Data to add to the buffer |
|||
* @param size Number of octets in data to add |
|||
*/ |
|||
void push(const uint8_t *data, size_t size); |
|||
|
|||
/**
|
|||
* @brief Shrinks the buffer to the smallest possible size. |
|||
* |
|||
* @return New size of the buffer in octets. |
|||
*/ |
|||
size_t shrink(); |
|||
|
|||
/**
|
|||
* @brief Expands the size of the internal buffer by a set number of octets. |
|||
* |
|||
* @param size Number of octets to |
|||
* @return New size of the buffer in octets. |
|||
*/ |
|||
size_t expandBuffer(size_t size); |
|||
|
|||
/**
|
|||
* @brief Guarantees availability for a specified number of octets. |
|||
* |
|||
* @param size Number of octets to guarantee. |
|||
* @return New size of the buffer in octets. |
|||
*/ |
|||
void secure(size_t size); |
|||
|
|||
/**
|
|||
* @brief Sets the size of the internal buffer. |
|||
* Note: If input 'size' is less than size(), data is removed. |
|||
* |
|||
* @param size Size to set the buffer to. |
|||
* @return New size of the buffer in octets. |
|||
*/ |
|||
void setBufferSize(size_t size); |
|||
|
|||
/**
|
|||
* @brief Fetches the size of the data in octets. |
|||
* |
|||
* @return Size of the data in octets. |
|||
*/ |
|||
size_t size() const; |
|||
|
|||
/**
|
|||
* @brief Fetches the size of the buffer in octets. |
|||
* |
|||
* @return Size of the buffer in octets. |
|||
*/ |
|||
size_t getBufferSize() const; |
|||
|
|||
/**
|
|||
* @brief Fetches the head of the buffer |
|||
* |
|||
* @return Buffer head |
|||
*/ |
|||
uint8_t *getHead() const; |
|||
|
|||
/**
|
|||
* @brief Empties the buffer of all elements. |
|||
* Note: The internal memory buffer is not freed or reallocated. |
|||
*/ |
|||
void empty(); |
|||
|
|||
DataBuffer(); |
|||
DataBuffer(size_t size); |
|||
~DataBuffer(); |
|||
|
|||
private: |
|||
uint8_t *base; |
|||
uint8_t *head; |
|||
uint8_t *end; |
|||
size_t bufferSize; |
|||
}; |
|||
} |
|||
|
|||
#include "DataBuffer_Imp.h" |
|||
|
|||
#endif // _DATABUFFER_H_HEADER
|
@ -0,0 +1,350 @@ |
|||
/**
|
|||
* Copyright (C) 2015 Justin James. |
|||
* |
|||
* This license must be preserved. |
|||
* Any applications, libraries, or code which make any use of any |
|||
* component of this program must not be commercial, unless explicit |
|||
* permission is granted from the original author. The use of this |
|||
* program for non-profit purposes is permitted. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|||
* |
|||
* In the event that this license restricts you from making desired use of this program, contact the original author. |
|||
* Written by Justin James <justin.aj@hotmail.com> |
|||
*/ |
|||
|
|||
#if !defined _DATABUFFER_IMP_H_HEADER |
|||
#define _DATABUFFER_IMP_H_HEADER |
|||
|
|||
/**
|
|||
* @file DataBuffer_Imp.h |
|||
* @brief Provides the implementations for DataBuffer template functions. |
|||
* Note: Modification of this file is not supported in any way. |
|||
*/ |
|||
|
|||
#include <vector> |
|||
#include <array> |
|||
|
|||
/**
|
|||
* IMPLEMENTATION: |
|||
* DataBuffer |
|||
*/ |
|||
|
|||
template<typename T> T Jupiter::DataBuffer::interpret_data(uint8_t *&head) |
|||
{ |
|||
T r = T(*(reinterpret_cast<T *>(head))); |
|||
head += sizeof(T); |
|||
return r; |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> static T<Y> interpret_data(uint8_t *&head) |
|||
{ |
|||
return _Jupiter_DataBuffer_partial_specialization_impl_std<T>::interpret<Y>(head); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> static T<X, Y> interpret_data(uint8_t *&head) |
|||
{ |
|||
return _Jupiter_DataBuffer_partial_specialization_impl_std_vector<T>::interpret<X, Y>(head); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> static T<X, Y, Z> interpret_data(uint8_t *&head) |
|||
{ |
|||
return _Jupiter_DataBuffer_partial_specialization_impl_std_string<T>::interpret<X, Y, Z>(head); |
|||
} |
|||
|
|||
// Basic peek
|
|||
|
|||
template<typename T> T Jupiter::DataBuffer::peek() const |
|||
{ |
|||
uint8_t *ptr = Jupiter::DataBuffer::head; |
|||
return Jupiter::DataBuffer::interpret_data<T>(ptr); |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> T<Y> Jupiter::DataBuffer::peek() const |
|||
{ |
|||
uint8_t *ptr = Jupiter::DataBuffer::head; |
|||
return Jupiter::DataBuffer::interpret_data<T, Y>(ptr); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> T<X, Y> Jupiter::DataBuffer::peek() const |
|||
{ |
|||
uint8_t *ptr = Jupiter::DataBuffer::head; |
|||
return Jupiter::DataBuffer::interpret_data<T, X, Y>(ptr); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> T<X, Y, Z> Jupiter::DataBuffer::peek() const |
|||
{ |
|||
uint8_t *ptr = Jupiter::DataBuffer::head; |
|||
return Jupiter::DataBuffer::interpret_data<T, X, Y, Z>(ptr); |
|||
} |
|||
|
|||
template<typename T> void Jupiter::DataBuffer::peek(T &out) const |
|||
{ |
|||
out = Jupiter::DataBuffer::peek<T>(); |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> void Jupiter::DataBuffer::peek(T<Y> &out) const |
|||
{ |
|||
out = Jupiter::DataBuffer::peek<T, Y>(); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> void Jupiter::DataBuffer::peek(T<X, Y> &out) const |
|||
{ |
|||
out = Jupiter::DataBuffer::peek<T, X, Y>(); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void Jupiter::DataBuffer::peek(T<X, Y, Z> &out) const |
|||
{ |
|||
out = Jupiter::DataBuffer::peek<T, X, Y, Z>(); |
|||
} |
|||
|
|||
template<typename T> T *Jupiter::DataBuffer::peek(size_t size_) const |
|||
{ |
|||
uint8_t *ptr = Jupiter::DataBuffer::head; |
|||
T *r = new T[size_]; |
|||
T *itr = r; |
|||
while (size_-- != 0) |
|||
*itr++ = Jupiter::DataBuffer::interpret_data<T>(ptr); |
|||
return r; |
|||
} |
|||
|
|||
// Basic pop
|
|||
|
|||
template<typename T> T Jupiter::DataBuffer::pop() |
|||
{ |
|||
return Jupiter::DataBuffer::interpret_data<T>(Jupiter::DataBuffer::head); |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> T<Y> Jupiter::DataBuffer::pop() |
|||
{ |
|||
return Jupiter::DataBuffer::interpret_data<T, Y>(Jupiter::DataBuffer::head); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> T<X, Y> Jupiter::DataBuffer::pop() |
|||
{ |
|||
return Jupiter::DataBuffer::interpret_data<T, X, Y>(Jupiter::DataBuffer::head); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> T<X, Y, Z> Jupiter::DataBuffer::pop() |
|||
{ |
|||
return Jupiter::DataBuffer::interpret_data<T, X, Y, Z>(Jupiter::DataBuffer::head); |
|||
} |
|||
|
|||
template<typename T> void Jupiter::DataBuffer::pop(T &out) |
|||
{ |
|||
out = Jupiter::DataBuffer::pop<T>(); |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> void Jupiter::DataBuffer::pop(T<Y> &out) |
|||
{ |
|||
out = Jupiter::DataBuffer::pop<T, Y>(); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> void Jupiter::DataBuffer::pop(T<X, Y> &out) |
|||
{ |
|||
out = Jupiter::DataBuffer::pop<T, X, Y>(); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void Jupiter::DataBuffer::pop(T<X, Y, Z> &out) |
|||
{ |
|||
out = Jupiter::DataBuffer::pop<T, X, Y, Z>(); |
|||
} |
|||
|
|||
template<typename T> T *Jupiter::DataBuffer::pop(size_t size_) |
|||
{ |
|||
T *r = new T[size_]; |
|||
T *itr = r; |
|||
while (size_-- != 0) |
|||
*itr++ = Jupiter::DataBuffer::interpret_data<T>(Jupiter::DataBuffer::head); |
|||
return r; |
|||
} |
|||
|
|||
// Basic push
|
|||
|
|||
template<typename T> void Jupiter::DataBuffer::push(const T *data) |
|||
{ |
|||
Jupiter::DataBuffer::secure(sizeof(T)); |
|||
*reinterpret_cast<T *>(Jupiter::DataBuffer::end) = *data; |
|||
Jupiter::DataBuffer::end += sizeof(T); |
|||
} |
|||
|
|||
template<typename T> void Jupiter::DataBuffer::push(const T &data) |
|||
{ |
|||
Jupiter::DataBuffer::push<T>(&data); |
|||
} |
|||
|
|||
// SPECIALIZATION: Jupiter::DataBuffer
|
|||
|
|||
template<> void inline Jupiter::DataBuffer::push(const Jupiter::DataBuffer *data) |
|||
{ |
|||
size_t size_ = data->size(); |
|||
Jupiter::DataBuffer::secure(sizeof(size_t) + size_); |
|||
Jupiter::DataBuffer::push<size_t>(size_); |
|||
Jupiter::DataBuffer::push(data->getHead(), size_); |
|||
} |
|||
|
|||
template<> Jupiter::DataBuffer inline Jupiter::DataBuffer::interpret_data(uint8_t *&head_) |
|||
{ |
|||
size_t size_ = *reinterpret_cast<size_t *>(head_); |
|||
head_ += sizeof(size_t); |
|||
Jupiter::DataBuffer r = Jupiter::DataBuffer(size_); |
|||
while (size_-- != 0) |
|||
*r.end++ = *head_++; |
|||
return r; |
|||
} |
|||
|
|||
// template / string push
|
|||
|
|||
template<template<typename> class T> struct _Jupiter_DataBuffer_partial_specialization_impl |
|||
{ |
|||
}; |
|||
|
|||
template<template<typename> class T, typename Y> void Jupiter::DataBuffer::push(const T<Y> *data) |
|||
{ |
|||
_Jupiter_DataBuffer_partial_specialization_impl<T>::push<Y>(this, data); |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> void Jupiter::DataBuffer::push(const T<Y> &data) |
|||
{ |
|||
Jupiter::DataBuffer::push<T, Y>(&data); |
|||
} |
|||
|
|||
template<template<typename> class T, typename Y> T<Y> Jupiter::DataBuffer::interpret_data(uint8_t *&head) |
|||
{ |
|||
return _Jupiter_DataBuffer_partial_specialization_impl<T>::interpret<Y>(head); |
|||
} |
|||
|
|||
// PUSH SPECIALIZATION: std::array
|
|||
|
|||
template<template<typename, size_t> class T> struct _Jupiter_DataBuffer_partial_specialization_impl_std_array |
|||
{ |
|||
}; |
|||
|
|||
template<> struct _Jupiter_DataBuffer_partial_specialization_impl_std_array<std::array> |
|||
{ |
|||
template<typename X, size_t Y> static void push(Jupiter::DataBuffer *buffer, const std::array<X, Y> *data) |
|||
{ |
|||
buffer->push<size_t>(Y); |
|||
if (std::is_fundamental<std::array<X, Y>::value_type>::value) |
|||
buffer->push(reinterpret_cast<const uint8_t *>(data->data()), data->size() * sizeof(std::array<X, Y>::value_type)); |
|||
else |
|||
{ |
|||
std::array<X, Y>::const_iterator itr = data->begin(); |
|||
std::array<X, Y>::const_iterator end = data->end(); |
|||
while (itr != end) |
|||
buffer->push<std::array<X, Y>::value_type>(*itr++); |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
template<template<typename, size_t> class T, typename X, size_t Y> void Jupiter::DataBuffer::push(const T<X, Y> *data) |
|||
{ |
|||
_Jupiter_DataBuffer_partial_specialization_impl_std_array<T>::push<X, Y>(this, data); |
|||
} |
|||
|
|||
template<template<typename, size_t> class T, typename X, size_t Y> void Jupiter::DataBuffer::push(const T<X, Y> &data) |
|||
{ |
|||
Jupiter::DataBuffer::push<T, X, Y>(&data); |
|||
} |
|||
|
|||
// SPECIALIZATION: std::vector
|
|||
|
|||
template<template<typename, typename> class T> struct _Jupiter_DataBuffer_partial_specialization_impl_std_vector |
|||
{ |
|||
}; |
|||
|
|||
template<> struct _Jupiter_DataBuffer_partial_specialization_impl_std_vector<std::vector> |
|||
{ |
|||
template<typename X, typename Y> static void push(Jupiter::DataBuffer *buffer, const std::vector<X, Y> *data) |
|||
{ |
|||
buffer->push<std::vector<X, Y>::size_type>(data->size()); |
|||
if (std::is_fundamental<std::vector<X, Y>::value_type>::value) |
|||
buffer->push(reinterpret_cast<const uint8_t *>(data->data()), data->size() * sizeof(std::vector<X, Y>::value_type)); |
|||
else |
|||
{ |
|||
std::vector<X, Y>::const_iterator itr = data->begin(); |
|||
std::vector<X, Y>::const_iterator end = data->end(); |
|||
while (itr != end) |
|||
buffer->push<std::vector<X, Y>::value_type>(*itr++); |
|||
} |
|||
}; |
|||
|
|||
template<typename X, typename Y> static std::vector<X, Y> interpret(uint8_t *&head) |
|||
{ |
|||
size_t size_ = *reinterpret_cast<size_t *>(head); |
|||
head += sizeof(size_t); |
|||
std::vector<X, Y> r; |
|||
r.reserve(size_); |
|||
while (size_-- != 0) |
|||
r.push_back(Jupiter::DataBuffer::interpret_data<std::vector<X, Y>::value_type>(head)); |
|||
return r; |
|||
} |
|||
}; |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> void Jupiter::DataBuffer::push(const T<X, Y> *data) |
|||
{ |
|||
_Jupiter_DataBuffer_partial_specialization_impl_std_vector<T>::push<X, Y>(this, data); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> void Jupiter::DataBuffer::push(const T<X, Y> &data) |
|||
{ |
|||
Jupiter::DataBuffer::push<T, X, Y>(&data); |
|||
} |
|||
|
|||
template<template<typename, typename> class T, typename X, typename Y> T<X, Y> Jupiter::DataBuffer::interpret_data(uint8_t *&head) |
|||
{ |
|||
return _Jupiter_DataBuffer_partial_specialization_impl_std_vector<T>::interpret<X, Y>(head); |
|||
} |
|||
|
|||
// SPECIALIZATION: std::string
|
|||
|
|||
template<template<typename, typename, typename> class T> struct _Jupiter_DataBuffer_partial_specialization_impl_std_string |
|||
{ |
|||
}; |
|||
|
|||
template<> struct _Jupiter_DataBuffer_partial_specialization_impl_std_string<std::basic_string> |
|||
{ |
|||
template<typename X, typename Y, typename Z> static void push(Jupiter::DataBuffer *buffer, const std::basic_string<X, Y, Z> *data) |
|||
{ |
|||
buffer->push(data->size()); |
|||
if (std::is_fundamental<std::basic_string<X, Y, Z>::value_type>::value) |
|||
buffer->push(reinterpret_cast<const uint8_t *>(data->data()), data->size() * sizeof(X)); |
|||
else |
|||
{ |
|||
std::basic_string<X, Y, Z>::const_iterator itr = data->begin(); |
|||
std::basic_string<X, Y, Z>::const_iterator end = data->end(); |
|||
while (itr != end) |
|||
buffer->push<std::basic_string<X, Y, Z>::value_type>(*itr++); |
|||
} |
|||
}; |
|||
|
|||
template<typename X, typename Y, typename Z> static std::basic_string<X, Y, Z> interpret(uint8_t *&head) |
|||
{ |
|||
size_t size_ = *reinterpret_cast<size_t *>(head); |
|||
head += sizeof(size_t); |
|||
std::basic_string<X, Y, Z> r; |
|||
r.reserve(size_); |
|||
while (size_-- != 0) |
|||
r.push_back(Jupiter::DataBuffer::interpret_data<std::basic_string<X, Y, Z>::value_type>(head)); |
|||
return r; |
|||
} |
|||
}; |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void Jupiter::DataBuffer::push(const T<X, Y, Z> *data) |
|||
{ |
|||
_Jupiter_DataBuffer_partial_specialization_impl_std_string<T>::push<X, Y, Z>(this, data); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> void Jupiter::DataBuffer::push(const T<X, Y, Z> &data) |
|||
{ |
|||
Jupiter::DataBuffer::push<T, X, Y, Z>(&data); |
|||
} |
|||
|
|||
template<template<typename, typename, typename> class T, typename X, typename Y, typename Z> T<X, Y, Z> Jupiter::DataBuffer::interpret_data(uint8_t *&head) |
|||
{ |
|||
return _Jupiter_DataBuffer_partial_specialization_impl_std_string<T>::interpret<X, Y, Z>(head); |
|||
} |
|||
|
|||
#endif // _DATABUFFER_IMP_H_HEADER
|
Binary file not shown.
Loading…
Reference in new issue