Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 45afdb5

Browse files
committedSep 10, 2020
Prepare version 0.0.1
1 parent 11db891 commit 45afdb5

18 files changed

+986
-6
lines changed
 

‎.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
.wsjcpp/*
22
tmp/*
3+
wsjcpp-obj-tree
4+
.logs/*
5+
.vscode/*
36

47
# Prerequisites
58
*.d

‎.travis.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
language: cpp
2+
3+
branches:
4+
only:
5+
- master
6+
7+
dist: bionic
8+
9+
addons:
10+
apt:
11+
packages:
12+
- cmake
13+
- make
14+
- g++
15+
- pkg-config
16+
17+
# Build steps
18+
script:
19+
- ./build_simple.sh
20+
- cd unit-tests.wsjcpp
21+
- ./build_simple.sh
22+
- ./unit-tests
23+

‎CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ set(EXECUTABLE_OUTPUT_PATH ${wsjcpp-obj-tree_SOURCE_DIR})
1010
# include header dirs
1111
list (APPEND WSJCPP_INCLUDE_DIRS "src")
1212

13+
list (APPEND WSJCPP_SOURCES "./src/wsjcpp_obj_tree.h")
14+
list (APPEND WSJCPP_SOURCES "./src/wsjcpp_obj_tree.cpp")
1315
list (APPEND WSJCPP_SOURCES "src/main.cpp")
1416

1517
#### BEGIN_WSJCPP_APPEND
@@ -28,3 +30,4 @@ install(
2830
/usr/bin
2931
)
3032

33+

‎README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# wsjcpp-obj-tree
2+
[![Build Status](https://api.travis-ci.com/wsjcpp/wsjcpp-obj-tree.svg?branch=master)](https://travis-ci.com/wsjcpp/wsjcpp-obj-tree)
3+
24
Multi Object Tree
5+

‎src.wsjcpp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
cmake_minimum_required(VERSION 3.0)
33

44
add_definitions(-DWSJCPP_APP_VERSION="v0.0.1")
5-
add_definitions(-DWSJCPP_APP_NAME="wsjcpp-obj-tree.git")
5+
add_definitions(-DWSJCPP_APP_NAME="wsjcpp-obj-tree")
66

77
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
88
set(MACOSX TRUE)

‎src/main.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
#include <string.h>
1+
#include <string>
22
#include <iostream>
33
#include <algorithm>
44
#include <wsjcpp_core.h>
5+
#include <wsjcpp_obj_tree.h>
56

67
int main(int argc, const char* argv[]) {
78
std::string TAG = "MAIN";
@@ -12,7 +13,36 @@ int main(int argc, const char* argv[]) {
1213
}
1314
WsjcppLog::setPrefixLogFile("wsjcpp");
1415
WsjcppLog::setLogDirectory(".logs");
15-
// TODO your code here
16+
17+
WsjcppObjTree tree;
18+
tree.addSupportType<WsjcppObjTreeNodeString>();
19+
tree.addSupportType<WsjcppObjTreeNodeInteger>();
20+
tree.addSupportType<WsjcppObjTreeNodeFloat>();
21+
tree.addSupportType<WsjcppObjTreeNodeDouble>();
22+
23+
WsjcppObjTreeChainDeclare chain(&tree);
24+
25+
chain
26+
.add("Motherboard")
27+
.add("CPU_SOCKET")
28+
.add("count")
29+
.add(1).up()
30+
.up()
31+
.add("frequency")
32+
.add(3.2).up()
33+
.up()
34+
.add("GPU_SOCKET")
35+
.add(1).up()
36+
.add("USB-A")
37+
.add(4).up()
38+
.add("PCI")
39+
.add(3).up()
40+
.add("PCI_EXPRESS")
41+
.add(1).up()
42+
.up()
43+
.up()
44+
;
45+
1646
return 0;
1747
}
1848

‎src/wsjcpp_obj_tree.cpp

Lines changed: 385 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,385 @@
1+
2+
#include "wsjcpp_obj_tree.h"
3+
#include <wsjcpp_core.h>
4+
#include <algorithm>
5+
#include <fstream>
6+
7+
// ---------------------------------------------------------------------
8+
// WsjcppObjTreeNode
9+
10+
WsjcppObjTreeNode::WsjcppObjTreeNode(WsjcppObjTree *pTree, uint16_t nType) {
11+
m_pTree = pTree;
12+
m_pParent = nullptr;
13+
m_nType = nType;
14+
// TODO regestry in global factory
15+
}
16+
17+
// ---------------------------------------------------------------------
18+
19+
uint16_t WsjcppObjTreeNode::getType() {
20+
return m_nType;
21+
}
22+
23+
// ---------------------------------------------------------------------
24+
25+
WsjcppObjTreeNode::~WsjcppObjTreeNode() {
26+
// std::cout << "TreeNode destroyed" << std::endl;
27+
}
28+
29+
// ---------------------------------------------------------------------
30+
31+
WsjcppObjTreeNode *WsjcppObjTreeNode::getParent() {
32+
return m_pParent;
33+
}
34+
35+
// ---------------------------------------------------------------------
36+
37+
uint32_t WsjcppObjTreeNode::getId() {
38+
return m_nId;
39+
}
40+
41+
// ---------------------------------------------------------------------
42+
43+
const std::vector<WsjcppObjTreeNode *> &WsjcppObjTreeNode::getChilds() {
44+
return m_vChilds;
45+
}
46+
47+
// ---------------------------------------------------------------------
48+
49+
void WsjcppObjTreeNode::setParent(WsjcppObjTreeNode *pParent) {
50+
m_pParent = pParent;
51+
}
52+
53+
// ---------------------------------------------------------------------
54+
55+
void WsjcppObjTreeNode::addChild(WsjcppObjTreeNode *pChild) {
56+
m_vChilds.push_back(pChild);
57+
}
58+
59+
// ---------------------------------------------------------------------
60+
61+
void WsjcppObjTreeNode::setId(uint32_t nId) {
62+
m_nId = nId;
63+
}
64+
65+
// ---------------------------------------------------------------------
66+
// WsjcppObjTree
67+
68+
WsjcppObjTree::WsjcppObjTree() {
69+
m_nLastId = 0;
70+
TAG = "WsjcppObjTree";
71+
}
72+
73+
// ---------------------------------------------------------------------
74+
75+
WsjcppObjTree::~WsjcppObjTree() {
76+
clearNodes();
77+
std::map<uint16_t, IFabricWsjcppObjTreeNode*>::iterator it;
78+
for (it = m_mapFabricTreeNode.begin(); it != m_mapFabricTreeNode.end(); ++it) {
79+
delete it->second;
80+
}
81+
m_mapFabricTreeNode.clear();
82+
83+
}
84+
85+
// ---------------------------------------------------------------------
86+
87+
bool WsjcppObjTree::readTreeFromFile(const std::string &sFilename, std::string &sError) {
88+
if (!WsjcppCore::fileExists(sFilename)) {
89+
return false;
90+
}
91+
return true;
92+
}
93+
94+
// ---------------------------------------------------------------------
95+
96+
bool WsjcppObjTree::writeTreeToFile(const std::string &sFilename, std::string &sError) {
97+
std::ofstream f(sFilename.c_str(), std::ios::out | std::ios::binary);
98+
if (!f) {
99+
std::cout << "FAILED could not create file to write " << sFilename << std::endl;
100+
return false;
101+
}
102+
103+
// m_nLastId
104+
int nTreeSize = m_vNodes.size();
105+
this->writeUInt32(f, nTreeSize);
106+
this->writeUInt32(f, m_nLastId);
107+
108+
unsigned char arrShort[4];
109+
110+
for (int i = 0; i < nTreeSize; i++) {
111+
WsjcppObjTreeNode *pNode = m_vNodes[i];
112+
113+
// write type
114+
this->writeUInt16(f, pNode->getType());
115+
116+
// write parent id
117+
if (pNode->getParent() != nullptr) {
118+
this->writeUInt32(f, pNode->getParent()->getId());
119+
} else {
120+
this->writeUInt32(f, 0);
121+
}
122+
123+
// write id
124+
this->writeUInt32(f, pNode->getId());
125+
126+
// write data size
127+
int nDataSize = pNode->getDataSize();
128+
this->writeUInt32(f, nDataSize);
129+
130+
// write data
131+
f.write(pNode->getData(), nDataSize);
132+
}
133+
f.close();
134+
return true;
135+
}
136+
137+
// ---------------------------------------------------------------------
138+
139+
void WsjcppObjTree::clearNodes() {
140+
int nSize = m_vNodes.size();
141+
for (int i = nSize - 1; i >=0; i--) {
142+
delete m_vNodes[i];
143+
}
144+
m_vNodes.clear();
145+
}
146+
147+
// ---------------------------------------------------------------------
148+
149+
void WsjcppObjTree::addNode(WsjcppObjTreeNode *pParent, WsjcppObjTreeNode *pChild) {
150+
if (pChild == nullptr) {
151+
WsjcppLog::throw_err(TAG, "::addNode - Child could not be null");
152+
}
153+
// check type of node
154+
if (!this->isSupportType(pChild->getType())) {
155+
WsjcppLog::throw_err(TAG, "::addNode - Not supported type");
156+
}
157+
158+
std::vector<WsjcppObjTreeNode *>::iterator it;
159+
160+
// check that parent node already exists in a list
161+
if (pParent != nullptr && !this->hasNode(pParent)) {
162+
WsjcppLog::throw_err(TAG, "::addNode - Not found parent node in the tree");
163+
}
164+
165+
// check child node - exclude circles
166+
if (this->hasNode(pChild)) {
167+
WsjcppLog::throw_err(TAG, "::addNode - Child already added in the tree");
168+
}
169+
170+
pChild->setParent(pParent);
171+
if (pParent != nullptr) {
172+
pParent->addChild(pChild);
173+
}
174+
m_nLastId++;
175+
pChild->setId(m_nLastId);
176+
m_vNodes.push_back(pChild);
177+
}
178+
179+
// ---------------------------------------------------------------------
180+
181+
bool WsjcppObjTree::isSupportType(uint16_t nType) {
182+
std::map<uint16_t, IFabricWsjcppObjTreeNode*>::iterator it;
183+
it = m_mapFabricTreeNode.find(nType);
184+
return it != m_mapFabricTreeNode.end();
185+
}
186+
187+
// ---------------------------------------------------------------------
188+
189+
bool WsjcppObjTree::hasNode(WsjcppObjTreeNode *pNode) {
190+
std::vector<WsjcppObjTreeNode *>::iterator it;
191+
it = std::find(m_vNodes.begin(), m_vNodes.end(), pNode);
192+
return it != m_vNodes.end();
193+
}
194+
195+
// ---------------------------------------------------------------------
196+
197+
void WsjcppObjTree::writeUInt32(std::ofstream &f, uint32_t nVal) {
198+
// not for multithreading
199+
// TODO redesign to reinterpret_cast<const char *>(&m_nValue);
200+
static unsigned char arrInteger[4];
201+
arrInteger[0] = (nVal >> 24) & 0xFF;
202+
arrInteger[1] = (nVal >> 16) & 0xFF;
203+
arrInteger[2] = (nVal >> 8) & 0xFF;
204+
arrInteger[3] = nVal & 0xFF;
205+
f.write((const char *)arrInteger, 4);
206+
}
207+
208+
// ---------------------------------------------------------------------
209+
210+
void WsjcppObjTree::writeUInt16(std::ofstream &f, uint16_t nVal) {
211+
// not for multithreading
212+
static unsigned char arrShort[2];
213+
arrShort[0] = (nVal >> 8) & 0xFF;
214+
arrShort[1] = nVal & 0xFF;
215+
f.write((const char *)arrShort, 2);
216+
}
217+
218+
// ---------------------------------------------------------------------
219+
//WsjcppObjTreeChainDeclare
220+
221+
WsjcppObjTreeChainDeclare::WsjcppObjTreeChainDeclare(WsjcppObjTree *pTree) {
222+
TAG = "WsjcppObjTreeChainDeclare";
223+
m_pTree = pTree;
224+
m_pCurrentNode = nullptr;
225+
}
226+
227+
// ---------------------------------------------------------------------
228+
229+
WsjcppObjTreeChainDeclare &WsjcppObjTreeChainDeclare::addNode(WsjcppObjTreeNode *pNode) {
230+
m_pTree->addNode(m_pCurrentNode, pNode);
231+
m_pCurrentNode = pNode;
232+
return *this;
233+
}
234+
235+
// ---------------------------------------------------------------------
236+
237+
WsjcppObjTreeChainDeclare &WsjcppObjTreeChainDeclare::up() {
238+
if (m_pCurrentNode != nullptr) {
239+
m_pCurrentNode = m_pCurrentNode->getParent();
240+
}
241+
return *this;
242+
}
243+
244+
// ---------------------------------------------------------------------
245+
246+
WsjcppObjTreeChainDeclare &WsjcppObjTreeChainDeclare::switchTo(WsjcppObjTreeNode *pNode) {
247+
if (!m_pTree->hasNode(pNode)) {
248+
WsjcppLog::throw_err(TAG, "::switchTo Not existed node in tree");
249+
}
250+
m_pCurrentNode = pNode;
251+
return *this;
252+
}
253+
254+
// ---------------------------------------------------------------------
255+
// WsjcppObjTreeNodeString
256+
257+
WsjcppObjTreeNodeString::WsjcppObjTreeNodeString(WsjcppObjTree *pTree, const std::string &sValue)
258+
: WsjcppObjTreeNode(pTree, WsjcppObjTreeNodeString::staticType()) {
259+
m_sValue = sValue;
260+
}
261+
262+
// ---------------------------------------------------------------------
263+
264+
std::string WsjcppObjTreeNodeString::getValue() {
265+
return m_sValue;
266+
}
267+
268+
// ---------------------------------------------------------------------
269+
270+
void WsjcppObjTreeNodeString::setValue(const std::string &sValue) {
271+
m_sValue = sValue;
272+
}
273+
274+
// ---------------------------------------------------------------------
275+
276+
int WsjcppObjTreeNodeString::getDataSize() {
277+
return m_sValue.size();
278+
}
279+
280+
// ---------------------------------------------------------------------
281+
282+
const char *WsjcppObjTreeNodeString::getData() {
283+
return m_sValue.c_str();
284+
}
285+
286+
// ---------------------------------------------------------------------
287+
// WsjcppObjTreeNodeInteger
288+
289+
WsjcppObjTreeNodeInteger::WsjcppObjTreeNodeInteger(WsjcppObjTree *pTree, const int32_t &nValue)
290+
: WsjcppObjTreeNode(pTree, WsjcppObjTreeNodeInteger::staticType()) {
291+
m_nValue = nValue;
292+
}
293+
294+
// ---------------------------------------------------------------------
295+
296+
int32_t WsjcppObjTreeNodeInteger::getValue() {
297+
return m_nValue;
298+
}
299+
300+
// ---------------------------------------------------------------------
301+
302+
void WsjcppObjTreeNodeInteger::setValue(int32_t nValue) {
303+
m_nValue = nValue;
304+
}
305+
306+
// ---------------------------------------------------------------------
307+
308+
int WsjcppObjTreeNodeInteger::getDataSize() {
309+
return sizeof(uint32_t);
310+
}
311+
312+
// ---------------------------------------------------------------------
313+
314+
const char *WsjcppObjTreeNodeInteger::getData() {
315+
const char *p = reinterpret_cast<const char *>(&m_nValue);
316+
return p;
317+
}
318+
319+
// ---------------------------------------------------------------------
320+
// WsjcppObjTreeNodeFloat
321+
322+
WsjcppObjTreeNodeFloat::WsjcppObjTreeNodeFloat(WsjcppObjTree *pTree, const float &nValue)
323+
: WsjcppObjTreeNode(pTree, WsjcppObjTreeNodeFloat::staticType()) {
324+
m_nValue = nValue;
325+
}
326+
327+
// ---------------------------------------------------------------------
328+
329+
float WsjcppObjTreeNodeFloat::getValue() {
330+
return m_nValue;
331+
}
332+
333+
// ---------------------------------------------------------------------
334+
335+
void WsjcppObjTreeNodeFloat::setValue(float nValue) {
336+
m_nValue = nValue;
337+
}
338+
339+
// ---------------------------------------------------------------------
340+
341+
int WsjcppObjTreeNodeFloat::getDataSize() {
342+
static_assert(sizeof(float) == 4, "Expected sizeof(float) == 4");
343+
return sizeof(float);
344+
}
345+
346+
// ---------------------------------------------------------------------
347+
348+
const char *WsjcppObjTreeNodeFloat::getData() {
349+
return reinterpret_cast<const char *>(&m_nValue);
350+
}
351+
352+
353+
// ---------------------------------------------------------------------
354+
// WsjcppObjTreeNodeDouble
355+
356+
WsjcppObjTreeNodeDouble::WsjcppObjTreeNodeDouble(WsjcppObjTree *pTree, const double &nValue)
357+
: WsjcppObjTreeNode(pTree, WsjcppObjTreeNodeDouble::staticType()) {
358+
m_nValue = nValue;
359+
}
360+
361+
// ---------------------------------------------------------------------
362+
363+
float WsjcppObjTreeNodeDouble::getValue() {
364+
return m_nValue;
365+
}
366+
367+
// ---------------------------------------------------------------------
368+
369+
void WsjcppObjTreeNodeDouble::setValue(float nValue) {
370+
m_nValue = nValue;
371+
}
372+
373+
// ---------------------------------------------------------------------
374+
375+
int WsjcppObjTreeNodeDouble::getDataSize() {
376+
static_assert(sizeof(double) == 8, "Expected sizeof(double) == 8");
377+
return sizeof(double);
378+
}
379+
380+
// ---------------------------------------------------------------------
381+
382+
const char *WsjcppObjTreeNodeDouble::getData() {
383+
return reinterpret_cast<const char *>(&m_nValue);
384+
}
385+

‎src/wsjcpp_obj_tree.h

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
#ifndef WSJCPP_OBJ_TREE_H
2+
#define WSJCPP_OBJ_TREE_H
3+
4+
#include <wsjcpp_core.h>
5+
#include <string>
6+
#include <map>
7+
8+
// not enum - because need more extendable from different modules
9+
10+
static uint16_t WSJCPP_OBJ_TREE_NODE_NONE = 0;
11+
static uint16_t WSJCPP_OBJ_TREE_NODE_STRING = 1;
12+
static uint16_t WSJCPP_OBJ_TREE_NODE_INTEGER = 2;
13+
static uint16_t WSJCPP_OBJ_TREE_NODE_FLOAT = 3;
14+
static uint16_t WSJCPP_OBJ_TREE_NODE_DOUBLE = 4;
15+
16+
class WsjcppObjTree;
17+
18+
class WsjcppObjTreeNode {
19+
friend class WsjcppObjTree;
20+
21+
public:
22+
WsjcppObjTreeNode(WsjcppObjTree *pTree, uint16_t nType);
23+
virtual ~WsjcppObjTreeNode();
24+
uint16_t getType();
25+
26+
// virtual zero methods will be deny create basic class
27+
virtual int getDataSize() = 0;
28+
virtual const char *getData() = 0;
29+
30+
WsjcppObjTreeNode *getParent();
31+
uint32_t getId();
32+
const std::vector<WsjcppObjTreeNode *> &getChilds();
33+
34+
protected:
35+
void setParent(WsjcppObjTreeNode *pParent);
36+
void addChild(WsjcppObjTreeNode *pChild);
37+
void setId(uint32_t id);
38+
39+
private:
40+
WsjcppObjTree *m_pTree;
41+
WsjcppObjTreeNode *m_pParent;
42+
uint32_t m_nId;
43+
std::vector<WsjcppObjTreeNode *> m_vChilds;
44+
uint16_t m_nType;
45+
};
46+
47+
class IFabricWsjcppObjTreeNode {
48+
public:
49+
virtual ~IFabricWsjcppObjTreeNode() {};
50+
virtual WsjcppObjTreeNode *create() = 0;
51+
};
52+
53+
54+
template<class T>
55+
class FabricWsjcppObjTreeNode : public IFabricWsjcppObjTreeNode {
56+
public:
57+
FabricWsjcppObjTreeNode(WsjcppObjTree *pTree) : m_pTree(pTree) { };
58+
~FabricWsjcppObjTreeNode() {};
59+
virtual WsjcppObjTreeNode *create() override {
60+
return new T(m_pTree);
61+
};
62+
private:
63+
WsjcppObjTree *m_pTree;
64+
};
65+
66+
67+
class WsjcppObjTree {
68+
friend class WsjcppObjTreeNode;
69+
70+
public:
71+
WsjcppObjTree();
72+
~WsjcppObjTree();
73+
74+
bool readTreeFromFile(const std::string &sFilename, std::string &sError);
75+
bool writeTreeToFile(const std::string &sFilename, std::string &sError);
76+
void clearNodes();
77+
void addNode(WsjcppObjTreeNode *pParent, WsjcppObjTreeNode *pChild);
78+
79+
template<class T>
80+
bool addSupportType() {
81+
std::map<uint16_t, IFabricWsjcppObjTreeNode*>::iterator it;
82+
uint16_t nType = T::staticType();
83+
it = m_mapFabricTreeNode.find(nType);
84+
if (it != m_mapFabricTreeNode.end()) {
85+
WsjcppLog::err(TAG, "WsjcppObjTreeNode '" + std::to_string(nType) + "' type already registered.");
86+
return false;
87+
}
88+
m_mapFabricTreeNode[nType] = new FabricWsjcppObjTreeNode<T>(this);
89+
return true;
90+
}
91+
bool isSupportType(uint16_t );
92+
bool hasNode(WsjcppObjTreeNode *);
93+
94+
template<class T, class A>
95+
int findNodes(const A &val, std::vector<T *> &vFoundNodes) {
96+
int nRet = 0;
97+
uint16_t nType = T::staticType();
98+
std::vector<WsjcppObjTreeNode *>::iterator it = m_vNodes.begin();
99+
for (it = m_vNodes.begin(); it != m_vNodes.end(); ++it) {
100+
if ((*it)->getType() == nType) {
101+
T *pNode = static_cast<T *>(*it);
102+
if (pNode->getValue() == val) {
103+
vFoundNodes.push_back(pNode);
104+
nRet++;
105+
}
106+
}
107+
}
108+
return nRet;
109+
};
110+
111+
private:
112+
std::string TAG;
113+
std::vector<WsjcppObjTreeNode *> m_vNodes;
114+
int m_nLastId;
115+
std::map<uint16_t, IFabricWsjcppObjTreeNode*> m_mapFabricTreeNode;
116+
117+
void writeUInt32(std::ofstream &f, uint32_t nVal);
118+
void writeUInt16(std::ofstream &f, uint16_t nVal);
119+
};
120+
121+
class WsjcppObjTreeChainDeclare {
122+
public:
123+
WsjcppObjTreeChainDeclare(WsjcppObjTree *pTree);
124+
125+
WsjcppObjTreeChainDeclare &addNode(WsjcppObjTreeNode *);
126+
127+
template<class T, class A>
128+
WsjcppObjTreeChainDeclare &addT(const A &val) {
129+
WsjcppObjTreeNode *pNode = new T(m_pTree, val);
130+
return addNode(pNode);
131+
}
132+
template<typename T> WsjcppObjTreeChainDeclare &add(const T &val);
133+
template<typename T> WsjcppObjTreeChainDeclare &add(const T *val);
134+
WsjcppObjTreeChainDeclare &up();
135+
WsjcppObjTreeChainDeclare &switchTo(WsjcppObjTreeNode *);
136+
137+
private:
138+
std::string TAG;
139+
WsjcppObjTree *m_pTree;
140+
WsjcppObjTreeNode *m_pCurrentNode;
141+
};
142+
143+
// define for inline templates
144+
#define WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE( type0, classname ) \
145+
template<> inline \
146+
WsjcppObjTreeChainDeclare &WsjcppObjTreeChainDeclare::add< type0 >(type0 const &val) { \
147+
return this->addT< classname >(val); \
148+
}
149+
150+
#define WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE_P( type0, classname ) \
151+
template<> inline \
152+
WsjcppObjTreeChainDeclare &WsjcppObjTreeChainDeclare::add< type0 >(type0 const *val) { \
153+
return this->addT< classname >(val); \
154+
}
155+
156+
class WsjcppObjTreeNodeString : public WsjcppObjTreeNode {
157+
public:
158+
WsjcppObjTreeNodeString(WsjcppObjTree *pTree, const std::string &sValue = "");
159+
static uint16_t staticType() { return WSJCPP_OBJ_TREE_NODE_STRING; }; // string
160+
161+
std::string getValue();
162+
void setValue(const std::string &sValue);
163+
164+
// TreeNode
165+
virtual int getDataSize() override;
166+
virtual const char *getData() override;
167+
168+
private:
169+
std::string m_sValue;
170+
};
171+
172+
WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE(std::string, WsjcppObjTreeNodeString)
173+
WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE_P(char, WsjcppObjTreeNodeString)
174+
175+
class WsjcppObjTreeNodeInteger : public WsjcppObjTreeNode {
176+
public:
177+
WsjcppObjTreeNodeInteger(WsjcppObjTree *pTree, const int32_t &nValue = 0);
178+
static uint16_t staticType() { return WSJCPP_OBJ_TREE_NODE_INTEGER; }; // integer 32
179+
180+
int32_t getValue();
181+
void setValue(int32_t nValue);
182+
183+
// WsjcppObjTreeNode
184+
virtual int getDataSize() override;
185+
virtual const char *getData() override;
186+
187+
private:
188+
int32_t m_nValue;
189+
};
190+
191+
WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE(int, WsjcppObjTreeNodeInteger)
192+
193+
class WsjcppObjTreeNodeFloat : public WsjcppObjTreeNode {
194+
public:
195+
WsjcppObjTreeNodeFloat(WsjcppObjTree *pTree, const float &nValue = 0);
196+
static uint16_t staticType() { return WSJCPP_OBJ_TREE_NODE_FLOAT; }; // float
197+
198+
float getValue();
199+
void setValue(float nValue);
200+
201+
// TreeNode
202+
virtual int getDataSize() override;
203+
virtual const char *getData() override;
204+
205+
private:
206+
float m_nValue;
207+
};
208+
209+
WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE(float, WsjcppObjTreeNodeFloat)
210+
211+
212+
class WsjcppObjTreeNodeDouble : public WsjcppObjTreeNode {
213+
public:
214+
WsjcppObjTreeNodeDouble(WsjcppObjTree *pTree, const double &nValue = 0);
215+
static uint16_t staticType() { return WSJCPP_OBJ_TREE_NODE_DOUBLE; };
216+
217+
float getValue();
218+
void setValue(float nValue);
219+
220+
// TreeNode
221+
virtual int getDataSize() override;
222+
virtual const char *getData() override;
223+
224+
private:
225+
double m_nValue;
226+
};
227+
228+
WSJCPP_OBJ_TREE_CHAIN_DECLARE_INLINE(double, WsjcppObjTreeNodeDouble)
229+
230+
#endif // WSJCPP_OBJ_TREE_H

‎unit-tests.wsjcpp/CMakeLists.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.0)
33

44
project(unit-tests C CXX)
55
add_definitions(-DWSJCPP_APP_VERSION="ut-v0.0.1")
6-
add_definitions(-DWSJCPP_APP_NAME="unit-tests-wsjcpp-obj-tree.git")
6+
add_definitions(-DWSJCPP_APP_NAME="unit-tests-wsjcpp-obj-tree")
77

88
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
99
set(MACOSX TRUE)
@@ -29,11 +29,19 @@ list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/wsjcpp_unit_tests_main.cp
2929
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/wsjcpp_resources_manager.h")
3030
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/wsjcpp_resources_manager.cpp")
3131

32-
# wsjcpp-obj-tree.git:v0.0.1
32+
# wsjcpp-obj-tree:v0.0.1
3333
list (APPEND WSJCPP_INCLUDE_DIRS "../src")
34+
list (APPEND WSJCPP_SOURCES "../src/wsjcpp_obj_tree.h")
35+
list (APPEND WSJCPP_SOURCES "../src/wsjcpp_obj_tree.cpp")
3436

3537
# unit-tests
3638
list (APPEND WSJCPP_INCLUDE_DIRS "src")
39+
list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_add_node.h")
40+
list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_add_node.cpp")
41+
list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_write_tree.h")
42+
list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_write_tree.cpp")
43+
list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_find_nodes.h")
44+
list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_find_nodes.cpp")
3745

3846
include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt)
3947

‎unit-tests.wsjcpp/data/.gitkeeper

Whitespace-only changes.
296 Bytes
Binary file not shown.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "unit_test_add_node.h"
2+
#include <vector>
3+
#include <wsjcpp_core.h>
4+
#include <wsjcpp_obj_tree.h>
5+
6+
REGISTRY_WSJCPP_UNIT_TEST(UnitTestAddNode)
7+
8+
UnitTestAddNode::UnitTestAddNode()
9+
: WsjcppUnitTestBase("UnitTestAddNode") {
10+
}
11+
12+
// ---------------------------------------------------------------------
13+
14+
void UnitTestAddNode::init() {
15+
// nothing
16+
}
17+
18+
// ---------------------------------------------------------------------
19+
20+
bool UnitTestAddNode::run() {
21+
bool bTestSuccess = true;
22+
23+
WsjcppObjTree tree;
24+
tree.addSupportType<WsjcppObjTreeNodeString>();
25+
tree.addSupportType<WsjcppObjTreeNodeInteger>();
26+
tree.addSupportType<WsjcppObjTreeNodeFloat>();
27+
28+
auto *pNodeRoot = new WsjcppObjTreeNodeInteger(&tree, 8);
29+
auto *pNodeBar = new WsjcppObjTreeNodeString(&tree, "bar");
30+
auto *pNodeBaz = new WsjcppObjTreeNodeString(&tree, "baz");
31+
auto *pNode1dot2 = new WsjcppObjTreeNodeFloat(&tree, 1.2);
32+
33+
compareN(bTestSuccess, "pNodeRoot->getType()", pNodeRoot->getType(), WSJCPP_OBJ_TREE_NODE_INTEGER);
34+
compareN(bTestSuccess, "pNodeBar->getType()", pNodeBar->getType(), WSJCPP_OBJ_TREE_NODE_STRING);
35+
compareN(bTestSuccess, "pNodeBaz->getType()", pNodeBaz->getType(), WSJCPP_OBJ_TREE_NODE_STRING);
36+
compareN(bTestSuccess, "pNode1dot2->getType()", pNode1dot2->getType(), WSJCPP_OBJ_TREE_NODE_FLOAT);
37+
38+
compareB(bTestSuccess, "pNodeRoot getParent", pNodeRoot->getParent() == nullptr, true);
39+
compareB(bTestSuccess, "pNodeBar getParent", pNodeBar->getParent() == nullptr, true);
40+
compareB(bTestSuccess, "pNodeBaz getParent", pNodeBaz->getParent() == nullptr, true);
41+
compareB(bTestSuccess, "pNode1dot2 getParent", pNode1dot2->getParent() == nullptr, true);
42+
43+
tree.addNode(nullptr, pNodeRoot);
44+
tree.addNode(pNodeRoot, pNodeBar);
45+
tree.addNode(pNodeRoot, pNodeBaz);
46+
47+
compareB(bTestSuccess, "tree.hasNode pNodeRoot", tree.hasNode(pNodeRoot), true);
48+
compareB(bTestSuccess, "tree.hasNode pNodeBar", tree.hasNode(pNodeBar), true);
49+
compareB(bTestSuccess, "tree.hasNode pNodeBaz", tree.hasNode(pNodeBaz), true);
50+
compareB(bTestSuccess, "tree.hasNode pNode1dot2", tree.hasNode(pNode1dot2), false);
51+
52+
tree.addNode(pNodeBaz, pNode1dot2);
53+
compareB(bTestSuccess, "tree.hasNode pNode1dot2", tree.hasNode(pNode1dot2), true);
54+
55+
const std::vector<WsjcppObjTreeNode *> &vRootChilds = pNodeRoot->getChilds();
56+
compareN(bTestSuccess, "vRootChilds.size()", vRootChilds.size(), 2);
57+
if (vRootChilds.size() == 2) {
58+
compareB(bTestSuccess, "vRootChilds[0] == pNodeBar", vRootChilds[0] == (WsjcppObjTreeNode *)pNodeBar, true);
59+
compareB(bTestSuccess, "vRootChilds[1] == pNodeBaz", vRootChilds[1] == (WsjcppObjTreeNode *)pNodeBaz, true);
60+
}
61+
62+
const std::vector<WsjcppObjTreeNode *> &vBazChilds = pNodeBaz->getChilds();
63+
compareN(bTestSuccess, "vBazChilds.size()", vBazChilds.size(), 1);
64+
if (vBazChilds.size() == 1) {
65+
compareB(bTestSuccess, "vBazChilds[0] == pNode1dot2", vBazChilds[0] == (WsjcppObjTreeNode *)pNode1dot2, true);
66+
}
67+
68+
return bTestSuccess;
69+
}
70+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef UNIT_TEST_ADD_NODE_H
2+
#define UNIT_TEST_ADD_NODE_H
3+
4+
#include <wsjcpp_unit_tests.h>
5+
6+
// Description: TODO
7+
class UnitTestAddNode : public WsjcppUnitTestBase {
8+
public:
9+
UnitTestAddNode();
10+
virtual void init();
11+
virtual bool run();
12+
};
13+
14+
#endif // UNIT_TEST_ADD_NODE_H
15+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include "unit_test_find_nodes.h"
2+
#include <vector>
3+
#include <wsjcpp_core.h>
4+
#include <wsjcpp_obj_tree.h>
5+
6+
REGISTRY_WSJCPP_UNIT_TEST(UnitTestFindNodes)
7+
8+
UnitTestFindNodes::UnitTestFindNodes()
9+
: WsjcppUnitTestBase("UnitTestFindNodes") {
10+
}
11+
12+
// ---------------------------------------------------------------------
13+
14+
void UnitTestFindNodes::init() {
15+
// nothing
16+
}
17+
18+
// ---------------------------------------------------------------------
19+
20+
21+
class CompStruct : public WsjcppObjTree {
22+
public:
23+
CompStruct() {
24+
addSupportType<WsjcppObjTreeNodeString>();
25+
addSupportType<WsjcppObjTreeNodeInteger>();
26+
addSupportType<WsjcppObjTreeNodeFloat>();
27+
addSupportType<WsjcppObjTreeNodeDouble>();
28+
}
29+
};
30+
31+
bool UnitTestFindNodes::run() {
32+
bool bTestSuccess = true;
33+
34+
CompStruct comp;
35+
36+
WsjcppObjTreeChainDeclare chain(&comp);
37+
38+
chain
39+
.add("Motherboard")
40+
.add("CPU_SOCKET")
41+
.add("count")
42+
.add(1).up()
43+
.up()
44+
.add("frequency")
45+
.add(3.2).up()
46+
.up()
47+
.add("GPU_SOCKET")
48+
.add("count")
49+
.add(1).up()
50+
.up()
51+
.add("USB-A")
52+
.add(4).up()
53+
.add("PCI")
54+
.add(3).up()
55+
.add("PCI_EXPRESS")
56+
.add(1).up()
57+
.up()
58+
.up()
59+
;
60+
61+
std::vector<WsjcppObjTreeNodeString *> vFoundNodes;
62+
comp.findNodes("frequency", vFoundNodes);
63+
compareN(bTestSuccess, "Find 'frequency' ", vFoundNodes.size(), 1);
64+
65+
if (vFoundNodes.size() == 1) {
66+
WsjcppObjTreeNode *pNode = vFoundNodes[0];
67+
compareN(bTestSuccess, "'frequency' childs size", pNode->getChilds().size(), 1);
68+
if (pNode->getChilds().size() == 1) {
69+
WsjcppObjTreeNode *pNode2 = pNode->getChilds()[0];
70+
compareB(bTestSuccess, "'frequency' parent of the child", pNode2->getParent() == pNode, true);
71+
compareN(bTestSuccess, "'frequency' child type", pNode2->getType(), WSJCPP_OBJ_TREE_NODE_DOUBLE);
72+
WsjcppObjTreeNodeDouble *pDouble = (WsjcppObjTreeNodeDouble *)pNode2;
73+
compareN(bTestSuccess, "'frequency' child data size", pDouble->getDataSize(), 8);
74+
compareS(bTestSuccess, "'frequency' child value", std::to_string(pDouble->getValue()), std::to_string(3.2));
75+
}
76+
}
77+
78+
vFoundNodes[0]->getChilds()[0];
79+
80+
81+
comp.findNodes("count", vFoundNodes);
82+
compareN(bTestSuccess, "Find 'count' and 'frequency' ", vFoundNodes.size(), 3);
83+
84+
vFoundNodes.clear();
85+
comp.findNodes("count", vFoundNodes);
86+
compareN(bTestSuccess, "Find 'count' ", vFoundNodes.size(), 2);
87+
88+
return bTestSuccess;
89+
}
90+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef UNIT_TEST_FIND_NODES_H
2+
#define UNIT_TEST_FIND_NODES_H
3+
4+
#include <wsjcpp_unit_tests.h>
5+
6+
// Description: TODO
7+
class UnitTestFindNodes : public WsjcppUnitTestBase {
8+
public:
9+
UnitTestFindNodes();
10+
virtual void init();
11+
virtual bool run();
12+
};
13+
14+
#endif // UNIT_TEST_FIND_NODES_H
15+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include "unit_test_write_tree.h"
2+
#include <vector>
3+
#include <wsjcpp_core.h>
4+
#include <wsjcpp_obj_tree.h>
5+
6+
REGISTRY_WSJCPP_UNIT_TEST(UnitTestWriteTree)
7+
8+
UnitTestWriteTree::UnitTestWriteTree()
9+
: WsjcppUnitTestBase("UnitTestWriteTree") {
10+
}
11+
12+
// ---------------------------------------------------------------------
13+
14+
void UnitTestWriteTree::init() {
15+
// nothing
16+
}
17+
18+
class CompStruct : public WsjcppObjTree {
19+
public:
20+
CompStruct() {
21+
addSupportType<WsjcppObjTreeNodeString>();
22+
addSupportType<WsjcppObjTreeNodeInteger>();
23+
addSupportType<WsjcppObjTreeNodeFloat>();
24+
addSupportType<WsjcppObjTreeNodeDouble>();
25+
}
26+
};
27+
28+
// ---------------------------------------------------------------------
29+
30+
bool UnitTestWriteTree::run() {
31+
bool bTestSuccess = true;
32+
33+
CompStruct comp;
34+
35+
WsjcppObjTreeChainDeclare chain(&comp);
36+
37+
chain
38+
.add("Motherboard")
39+
.add("CPU_SOCKET")
40+
.add("count")
41+
.add(1).up()
42+
.up()
43+
.add("frequency")
44+
.add(3.2).up()
45+
.up()
46+
.add("GPU_SOCKET")
47+
.add(1).up()
48+
.add("USB-A")
49+
.add(4).up()
50+
.add("PCI")
51+
.add(3).up()
52+
.add("PCI_EXPRESS")
53+
.add(1).up()
54+
.up()
55+
.up()
56+
;
57+
58+
if (!WsjcppCore::dirExists("./data/tmp")) {
59+
WsjcppCore::makeDir("./data/tmp");
60+
}
61+
62+
std::string sFilename = "./data/tmp/example.obj-tree";
63+
std::string sError;
64+
bool bWrote = comp.writeTreeToFile(sFilename, sError);
65+
compareB(bTestSuccess, "write to file", bWrote, true);
66+
67+
char *pBuffer = nullptr;
68+
int nBufferSize = 0;
69+
WsjcppCore::readFileToBuffer(sFilename, &pBuffer, nBufferSize);
70+
71+
compareN(bTestSuccess, "write to file", nBufferSize, 296);
72+
73+
return bTestSuccess;
74+
}
75+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef UNIT_TEST_WRITE_TREE_H
2+
#define UNIT_TEST_WRITE_TREE_H
3+
4+
#include <wsjcpp_unit_tests.h>
5+
6+
// Description: TODO
7+
class UnitTestWriteTree : public WsjcppUnitTestBase {
8+
public:
9+
UnitTestWriteTree();
10+
virtual void init();
11+
virtual bool run();
12+
};
13+
14+
#endif // UNIT_TEST_WRITE_TREE_H
15+

‎wsjcpp.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authors:
77
- name: "Evgenii Sopov"
88
email: "mrseakg@gmail.com"
99
origins:
10-
- address: "https://sea-kg.com/wsjcpp-package-registry/"
10+
- address: "https://wsjcpp.org/wsjcpp-package-registry/"
1111
type: "package-registry"
1212
keywords:
1313
- "c++"
@@ -17,3 +17,18 @@ dependencies:
1717
url: "https://github.com/wsjcpp/wsjcpp-core:master"
1818
origin: "https://github.com/"
1919
installation-dir: "./src.wsjcpp/wsjcpp_core"
20+
distribution:
21+
- source-file: "src/wsjcpp_obj_tree.h"
22+
target-file: "wsjcpp_obj_tree.h"
23+
type: "source-code"
24+
- source-file: "src/wsjcpp_obj_tree.cpp"
25+
target-file: "wsjcpp_obj_tree.cpp"
26+
type: "source-code"
27+
unit-tests:
28+
cases:
29+
- name: "AddNode"
30+
description: ""
31+
- name: "WriteTree"
32+
description: ""
33+
- name: "FindNodes"
34+
description: ""

0 commit comments

Comments
 (0)
Please sign in to comment.