天天看點

打造 C++ 最靈活動态數組結構 (三)

    鑒于一些工作原因和一些沒人關注的原因, 完成版不在這裡貼出來了, 如果真有感興趣的朋友可以Mail 我, 讨論下。 但MyData的思想是沒有問題的。下一步是進一步去掉MyData内部的 類型概念, 以及序列化和反序列化時支援更快捷短小的2進制資料模式。目前已經找到解決方案。這裡貼一段非MyData 的另一種資料容器 --- MyDataBinary ,這個子集将來會用做 MaData的 一部分。主要用途是存儲類型無關的資料,這些資料可以通過任何方式進行傳遞,然後再已一種經過檢查的安全方式取出來。

先貼使用方法

  如下:

   int iTestData = pam[0].get<int>();

  const char* pszData = pam[1].get<const char*>();

其中pam 是一個存儲MyDataBinary的 數組結構,這個結構用一個類表示, 傳入參數的 時候就好像一個可變的參數清單, 明白我的意思了麼? 你可以通過一個參數來傳遞多個類型的資料, 這樣可以統一函數接口,如果要設計回調托管系統,這一點很重要,統一的函數接口是保證函數回調的前提。 還有,如果要設計資料分發機制,這一點也是尤其重要的。 如果你不明白這一點的重要性, 那麼你可能出現過在解析某個配置檔案或者設計某底層功能時為你認為有必要的各種資料類型一一實作了一個接口,  這有2個壞處 1 眼花,2 未必夠用。 下面是代碼:

  #ifndef __MY_DATA_BINARY_H__

#define __MY_DATA_BINARY_H__

#pragma warning(disable: 4786)

#include <windows.h>

#include <stdio.h>

#include <assert.h>

class MyDataBinary {

public:

MyDataBinary() {

this->Init();

}

MyDataBinary(const MyDataBinary& dataString) {

this->Init();

this->_Set(dataString.c_str(), 0, dataString.length(), dataString.length());

}

MyDataBinary(const char* pszStr) {

this->Init();

size_t iTotalLen = NULL == pszStr ? 0 : strlen(pszStr);

this->_Set(pszStr, 0, iTotalLen, iTotalLen);

}

MyDataBinary(const MyDataBinary& dataString, size_t nBegin, size_t iStrLen) {

this->Init();

this->_Set(dataString.c_str(), nBegin, iStrLen, dataString.length());

}

MyDataBinary(void* dataBinary, size_t iSize) {

this->Init();

this->_Set((const char*)dataBinary, 0, iSize, iSize);

}

~MyDataBinary() {

this->_UnSet();

}

public:

const char* c_str() const {

return m_pszData;

}

size_t length() const {

return m_nLen;

}

void set(void* dataBinary, size_t iSize) {

this->_Set((const char*)dataBinary, 0, iSize, iSize);

}

template<typename ST>

void set(const ST& dataBinary) {

this->_Set(&dataBinary, 0, sizeof(ST), sizeof(ST));

}

template<typename GT>

const GT& get() const {

assert(sizeof(GT) == m_nLen);

return *(GT*)(m_pszData);

}

void reverse(size_t iSize, bool bLeave = true) {

if (iSize > m_nMelLen) {

char* pszNewData = (char* )malloc(iSize);

if (bLeave && m_nLen > 0) {

memcpy(pszNewData, m_pszData, m_nLen);

pszNewData[m_nLen] = '/0';

}

this->_UnSet();

m_nMelLen = iSize;

m_pszData = pszNewData;

}

}

public:

void operator=(const MyDataBinary& rhs) {

if (&rhs != this) {

this->_Set(rhs.c_str(), 0, rhs.length(), rhs.length());

}

}

void operator=(const char* cStr) {

size_t iTotalLen = NULL == cStr ? 0 : strlen(cStr);

this->_Set(cStr, 0, iTotalLen, iTotalLen);

}

char operator[](size_t iSize) const {

if (iSize < m_nLen) {

return m_pszData[iSize];

}

return 0;

}

friend bool operator==(const MyDataBinary& a, const MyDataBinary& b) {

return a.length() == b.length() && 0 == ::memcmp(a.c_str(), b.c_str(), a.length());

}

friend bool operator==(const MyDataBinary& a, const char* cStr) {

return NULL != cStr && 0 == strcmp(a.c_str(), cStr);

}

friend bool operator==(const char* cStr, const MyDataBinary& a) {

return NULL != cStr && 0 == strcmp(cStr, a.c_str());

}

friend bool operator !=(const MyDataBinary& a, const MyDataBinary& b) {

return a.length() != b.length() || 0 != ::memcmp(a.c_str(), b.c_str(), a.length());

}

friend bool operator !=(const MyDataBinary& a, const char* cStr) {

return NULL == cStr || 0 != strcmp(a.c_str(), cStr);

}

friend bool operator !=(const char* cStr, const MyDataBinary& a) {

return NULL == cStr || 0 != strcmp(cStr, a.c_str());

}

friend bool operator <(const MyDataBinary& a, const MyDataBinary& b) {

int iAns = ::memcmp(a.c_str(), b.c_str(), a.length() < b.length() ? a.length() : b.length());

return (iAns != 0 ? iAns : (a.length() < b.length() ? -1 : +1)) < 0;

}

friend bool operator >(const MyDataBinary& a, const MyDataBinary& b) {

int iAns = ::memcmp(a.c_str(), b.c_str(), a.length() < b.length() ? a.length() : b.length());

return (iAns != 0 ? iAns : (a.length() > b.length() ? +1 : -1)) > 0;

}

friend bool operator <=(const MyDataBinary& a, const MyDataBinary& b) {

int iAns = ::memcmp(a.c_str(), b.c_str(), a.length() < b.length() ? a.length() : b.length());

return (iAns != 0 ? iAns : (a.length() <= b.length() ? -1 : +1)) <= 0;

}

friend bool operator >=(const MyDataBinary& a, const MyDataBinary& b) {

int iAns = ::memcmp(a.c_str(), b.c_str(), a.length() < b.length() ? a.length() : b.length());

return (iAns != 0 ? iAns : (a.length() >= b.length() ? +1 : -1)) >= 0;

}

private:

void Init() {

m_pszData = new char[1];

m_pszData[0] = '/0';

m_nLen = 0;

m_nMelLen = 0;

}

void _Set(const char* cStr, size_t nBegin, size_t iStrLen, size_t iTotalLen) {

if (nBegin >= iTotalLen) {

return ;

}

if (NULL == cStr) {

m_pszData[0] = '/0';

m_nLen = 0;

return ;

}

if (iStrLen > iTotalLen - nBegin) {

iStrLen = iTotalLen - nBegin;

}

if (iStrLen + 1 > m_nMelLen) {

this->_UnSet();

m_pszData = (char* )malloc(iStrLen + 1);

m_nMelLen = iStrLen + 1;

}

m_nLen = iStrLen;

memcpy(m_pszData, &cStr[nBegin], iStrLen);

m_pszData[iStrLen] = '/0';

}

void _UnSet() {

if (NULL != m_pszData) {

free(m_pszData);

m_pszData = NULL;

}

}

private:

char* m_pszData;

size_t m_nLen;

size_t m_nMelLen;

};

#endif // end define __MY_DATA_BINARY_H__

繼續閱讀