第二版代码如下:
1 MyData.h
/*--------------------------------*/
C++ 散列化数组结构
[email protected]
cjxx 2008-06-27
/*--------------------------------*/
#ifndef __CJ_MY_DATA_H__
#define __CJ_MY_DATA_H__
#include <iostream>
#include <string>
#include <map>
using namespace std;
// 数字索引字符前缀
#define INT_INDEX_PRO_STR "INT_INDEX_"
// 相关头信息
class MyData;
// 序列化时的风格类型
enum PRINT_R_STYLE {
PHP,JS
};
// 序列化一个字串到MyData
MyData& Serialize(const char* serStr, MyData* dVal = NULL);
// 反序列化一个MyData到 字符串
bool UnSerialize(MyData* dVal, string& unserStr);
// 格式化输出一个MyData 结构 -- 调试用
void print_r(MyData& data);
// 构造MyData 格式化字串
string& print_s(MyData& data, string& str, bool bFormat = false, enum PRINT_R_STYLE style = PHP, int level = 0) ;
// 递归遍历 MyData 并执行用户自定义函数
void ForEachData(MyData& data, void* pCallBackFunc);
class MyData {
public:
enum ENUM_DATA_TYPE {
DATA_TYPE_DEF = 0, // 初始类型
DATA_TYPE_DAT = 1, // 数组类型
DATA_TYPE_INT = 2, // 整数类型
DATA_TYPE_STR = 3, // 字符类型
};
typedef map<string, MyData> MAP_MY_DATA;
public:
// 构造
MyData() {
this->Init();
}
// 序列化构造
MyData(const char* dVal) {
this->Init();
Serialize(dVal, this);
}
// 析构
~MyData() {
this->Clear();
}
// 判断类型
bool IsType(enum ENUM_DATA_TYPE eType) {
return m_cType == eType;
}
// 获取类型
enum ENUM_DATA_TYPE Type() {
return m_cType;
}
// 获取MAP
MAP_MY_DATA& Map() {
return m_mapMyData;
}
// 获取整形数据
int i() {
return (m_cType == DATA_TYPE_INT) ? m_intData : 0;
}
// 获取字符数据
const char* c() {
return (m_cType == DATA_TYPE_STR) ? m_strData.c_str() : "";
}
// 获取反序列化字串
const char* u() {
m_strUnSer = "";
return UnSerialize(this, m_strUnSer) ? m_strUnSer.c_str() : "";
}
// 赋值为整数
void operator=(int iVal) {
this->Clear();
m_intData = iVal;
m_cType = DATA_TYPE_INT;
this->SetFatherDat();
}
// 赋值为字符
void operator=(const char* cVal) {
this->Clear();
m_strData = cVal;
m_cType = DATA_TYPE_STR;
this->SetFatherDat();
}
// 赋值为数据
void operator=(const MyData& dVal) {
this->Clear();
m_strData = dVal.m_strData;
m_strUnSer = dVal.m_strUnSer;
m_intData = dVal.m_intData;
m_iNowIndex = dVal.m_iNowIndex;
m_mapMyData = dVal.m_mapMyData;
m_cType = dVal.m_cType;
this->SetFatherDat();
}
// 自动增加一个数字索引
MyData& operator()() {
m_iTmpIndex = m_iNowIndex;
return this->Get(StrIndex(m_iNowIndex++));
}
// 整形索引
MyData& operator[](int keyName) {
m_iTmpIndex = keyName;
return this->Get(StrIndex(keyName));
}
// 字符型索引
MyData& operator[](const char* keyName) {
m_iTmpIndex = 0;
return this->Get(keyName);
}
// 自动转换成 int
operator int() {
return m_intData;
}
// 自动转换成 const char*
operator const char*() {
return m_strData.c_str();
}
private:
void Clear() {
if (m_cType == DATA_TYPE_DAT) {
m_mapMyData.clear();
}
}
void Init() {
m_iNowIndex = 0;
m_iTmpIndex = 0;
m_intData = 0;
m_pFather = NULL;
m_cType = DATA_TYPE_DEF;
m_mapMyData.clear();
}
const char* StrIndex(unsigned int index) {
char buf[64] = {0};
sprintf_s(buf, INT_INDEX_PRO_STR"%d", index);
m_strUnSer = buf;
return m_strUnSer.c_str();
}
MyData& Get(const char* keyName) {
MAP_MY_DATA::iterator iter;
if (NULL == keyName) {
iter = m_mapMyData.find("");
} else {
iter = m_mapMyData.find(keyName);
}
if (iter != m_mapMyData.end()) {
return (*iter).second;
} else {
pair<MAP_MY_DATA::iterator, bool> Insert_Pair;
MyData data;
if (NULL == keyName) {
Insert_Pair = m_mapMyData.insert(MAP_MY_DATA::value_type("", data));
} else {
Insert_Pair = m_mapMyData.insert(MAP_MY_DATA::value_type(keyName, data));
}
(*Insert_Pair.first).second.SetFather(this);
return (*Insert_Pair.first).second;
}
}
void SetFatherDat() {
if (NULL != this->GetFather()) {
if (! this->GetFather()->IsType(DATA_TYPE_DAT)) {
this->GetFather()->m_cType = DATA_TYPE_DAT;
}
if (this->GetFather()->m_iNowIndex < this->GetFather()->m_iTmpIndex) {
this->GetFather()->m_iNowIndex = this->GetFather()->m_iTmpIndex + 1;
}
this->GetFather()->SetFatherDat();
}
}
void SetFather(MyData* pData) {
m_pFather = pData;
}
MyData* GetFather() {
return m_pFather;
}
private:
enum ENUM_DATA_TYPE m_cType;
string m_strData;
string m_strUnSer;
int m_intData;
int m_iNowIndex;
int m_iTmpIndex;
MyData* m_pFather;
MAP_MY_DATA m_mapMyData;
};
#endif // end define __CJ_MY_DATA_H__
2 MyData.cpp
#include "MyData.h"
// 序列化成数据
MyData& Serialize(const char* serStr, MyData* dVal /*= NULL*/) {
MyData* pDVal;
if (dVal == NULL) {
pDVal = new MyData;
} else {
pDVal = dVal;
}
// 序列化并添加数据
return (*pDVal);
}
// 反序列化为字串
bool UnSerialize(MyData* dVal, string& unserStr) {
if (NULL == dVal) {
return false;
}
string str = "";
if (dVal->IsType(MyData::DATA_TYPE_DAT)) {
str += "{";
}
print_s(*dVal, str, false, JS, 0);
if (dVal->IsType(MyData::DATA_TYPE_DAT)) {
str += "}";
}
unserStr = str;
return true;
}
string& print_s(MyData& data, string& str, bool bFormat /*= false*/, enum PRINT_R_STYLE style /*= PHP*/, int level /*= 0*/) {
char p_style[5][15] = {" =>array (", ")", "=>", "/"", ","};
char j_style[5][15] = {": {" , "}", ":" , "/"", ","};
char (* u_style)[15] = style == PHP ? p_style : j_style;
string space = "";
if (bFormat) {
for (int i = 0; i < level; i++) {
space += " ";
}
++level;
}
if (data.IsType(MyData::DATA_TYPE_DAT)) {
MyData::MAP_MY_DATA::iterator iter = data.Map().begin();
for (;iter != data.Map().end();) {
string keyString = "";
if ((*iter).first.substr(0,strlen(INT_INDEX_PRO_STR)) == INT_INDEX_PRO_STR) {
keyString = (*iter).first.substr(strlen(INT_INDEX_PRO_STR), (*iter).first.length());
} else {
keyString+= u_style[3];
keyString+= (*iter).first.c_str();
keyString+= u_style[3];
}
if ((*iter).second.IsType(MyData::DATA_TYPE_DAT)) {
if (bFormat) {
str += space;
}
str += keyString;
str += u_style[0];
if (bFormat) {
str += "/n";
}
str = print_s((*iter).second, str, bFormat, style, level);
if (bFormat) {
str += space;
}
str += u_style[1];
} else if ((*iter).second.IsType(MyData::DATA_TYPE_INT)) {
char buf[12] = {0};
sprintf_s(buf, "%d", (*iter).second.i());
if (bFormat) {
str += space;
}
str += keyString;
str += u_style[2];
str += buf;
} else if ((*iter).second.IsType(MyData::DATA_TYPE_STR)) {
if (bFormat) {
str += space;
}
str += keyString;
str += u_style[2];
str += (*iter).second.c();
}
if (++iter != data.Map().end()) {
str += u_style[4];
}
if (bFormat) {
str += "/n";
}
}
} else if (data.IsType(MyData::DATA_TYPE_INT)) {
char buf[12] = {0};
sprintf_s(buf, "%d", data.i());
if (bFormat) {
str += space;
}
str += buf;
if (bFormat) {
str += "/n";
}
} else if (data.IsType(MyData::DATA_TYPE_STR)) {
if (bFormat) {
str += space;
}
str += data.c();
if (bFormat) {
str += "/n";
}
}
return str;
}
void print_r(MyData& data) {
string str = "/n{/n";
print_s(data, str, true, JS, 1);
str += "}";
printf("%s", str.c_str());
}
void ForEachData(MyData& data, void* pCallBackFunc) {
}
3 testMain.cpp
#include "MyData.h"
int main(void)
{
int i = 0;
MyData testData;
MyData testData2("[1:22, '2':0, 'dff': [1:3]]");
testData[0] = 100;
testData[1] = "abc";
testData[3] = 3;
testData[1] = 1;
testData[6] = 2;
testData()[1] = 41;
testData[5]()[6] = 506;
testData[5]["a"][1] = 501;
testData[5][3][1] = 511;
testData[5]()[2] = 541;
testData["a"]() = Serialize("[1:22, '2':0, 'dff': [1:3]]");
testData["a"] = "fuck";
testData["a"][2] = "a";
testData["a"]() = "b";
testData["a"]() = "c";
testData2[1] = "abc";
testData2[2] = 3;
testData2[3]() = 4;
testData["c"]() = 1;
testData["c"]() = testData2;
testData[2][i][i] = 2;
int b = testData[0];
const char* p = testData[1];
printf("%d/n", b);
printf("%s/n", p);
print_r(testData);
printf("%s", testData.u());
getchar();
return 1;
}
功能:
1 增加了类型自动识别转换的操作,这个功能需要依赖C++的编译器而不是用户逻辑,使用时小心。
2 增加反序列化功能,此功能可以将自身导出成字串用来存储发送,目前两种可选方案 -- JSON -- PHP方式