Created
October 15, 2019 06:52
-
-
Save lvpidadiao/46755ac211809cc99fec6f293045db22 to your computer and use it in GitHub Desktop.
simple bytes buf。with extend and noextend buffer, also the buffer could managed by yourself。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by TrevorProfessor on 2019-09-18. | |
// | |
#include <cstring> | |
#include "bytes_buf.hpp" | |
static int align128(int v) { | |
#define CACHE_LINE_SIZE 128 | |
int r = ( v & ~(CACHE_LINE_SIZE - 1)) + CACHE_LINE_SIZE; | |
return (r & ~(CACHE_LINE_SIZE - 1)); | |
} | |
template<> | |
int Extend<InnerBuf>::write(uint8_t *data, int size) { | |
if (m_capacity - m_cursor < size) { | |
int newsize = align128(m_capacity + size); | |
uint8_t *temp = new uint8_t[newsize]; | |
memcpy(temp, m_buf, m_cursor); | |
delete []m_buf; | |
m_buf = temp; | |
m_capacity = newsize; | |
} | |
std::memcpy(m_buf + m_cursor, data, size); | |
m_cursor += size; | |
return size; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by TrevorProfessor on 2019-09-18. | |
// | |
#ifndef _BYTES_BUF_HPP | |
#define _BYTES_BUF_HPP | |
#include <cstdint> | |
#include <cstring> | |
#include <type_traits> | |
class InnerBuf{ | |
public: | |
InnerBuf() = delete; | |
explicit InnerBuf(uint8_t *, int capacity): m_cursor(0), m_capacity(capacity) { | |
m_buf = new uint8_t[capacity]; | |
} | |
~InnerBuf() { | |
delete []m_buf; | |
m_buf = nullptr; | |
} | |
protected: | |
uint8_t *m_buf; | |
int m_cursor; | |
int m_capacity; | |
}; | |
class OuterBuf{ | |
public: | |
OuterBuf() = delete; | |
explicit OuterBuf(uint8_t *buf, int capacity) { | |
m_buf = buf; | |
m_cursor = 0; | |
m_capacity = capacity; | |
} | |
~OuterBuf() { | |
m_buf = nullptr; | |
} | |
protected: | |
uint8_t *m_buf; | |
int m_cursor; | |
int m_capacity; | |
}; | |
template <typename T=OuterBuf> | |
class NoExtend: public T{ | |
public: | |
NoExtend() = delete; | |
explicit NoExtend(uint8_t *buf_ptr, int capacity): T(buf_ptr, capacity) { | |
} | |
~NoExtend() = default; | |
int write(uint8_t *data, int size) { | |
int to_copy_size = T::m_capacity - T::m_cursor; | |
if (to_copy_size >= size) { | |
std::memcpy(T::m_buf + T::m_cursor, data, size); | |
T::m_cursor += size; | |
return size; | |
}else { | |
if (to_copy_size == 0) { | |
return 0; | |
}else { | |
std::memcpy(T::m_buf + T::m_cursor, data, to_copy_size); | |
T::m_cursor += to_copy_size; | |
return to_copy_size; | |
} | |
} | |
} | |
}; | |
// OutBuffer can't be used by XyBytesBuf<OutBuffer, Extend>, this will lead to compile error. | |
template <typename T> | |
class Extend : public InnerBuf{ | |
public: | |
Extend() = delete; | |
explicit Extend(uint8_t *buf_ptr, int capacity):T(buf_ptr, capacity) { | |
} | |
int write(uint8_t *data, int size); | |
}; | |
// Default is outer buffer and Noextend memory. | |
template <class BufferType = OuterBuf, | |
template<class > class Extendable = NoExtend | |
> | |
class XyBytesBuf : public Extendable<BufferType> { | |
private: | |
typedef Extendable<BufferType> ThisType; | |
typedef XyBytesBuf<OuterBuf, NoExtend> NoExtendBuf; | |
public: | |
explicit XyBytesBuf(int capacity,uint8_t *buf=nullptr): Extendable<BufferType>(buf, capacity) { | |
} | |
~XyBytesBuf() = default; | |
int len() { | |
return Extendable<BufferType>::m_cursor; | |
} | |
int capability() { | |
return Extendable<BufferType>::m_capacity; | |
} | |
int remaining() { | |
return capability() - len(); | |
} | |
template <typename T> | |
void put(T v) { | |
ThisType::write(reinterpret_cast<uint8_t *>(&v), sizeof(v)); | |
} | |
template <typename D> | |
D get(int offset = 0) { | |
static_assert(std::is_integral<D>::value, "only integer type"); | |
if (ThisType::m_cursor + offset + sizeof(D) > capability()) { | |
return 0; | |
} | |
uint8_t *p = ThisType::m_buf + ThisType::m_cursor + offset; | |
return *(reinterpret_cast<D *>(p)); | |
} | |
// caveat: | |
// Make Sure peek_buf data will not outlive original buffer | |
// this function will return a XyBytesBuf refer to original XyBytesBuf's data | |
// may lead to a dangling ref.p | |
NoExtendBuf peek_buf(int size, int offset = 0) { | |
if ( size + offset > ThisType::m_capacity) { | |
return NoExtendBuf(0); | |
} | |
return NoExtendBuf(size, ThisType::m_buf + offset); | |
} | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment