@@ -11,7 +11,6 @@ WsjcppObjTreeNode::WsjcppObjTreeNode(WsjcppObjTree *pTree, uint16_t nType) {
1111 m_pTree = pTree;
1212 m_pParent = nullptr ;
1313 m_nType = nType;
14- // TODO regestry in global factory
1514}
1615
1716// ---------------------------------------------------------------------
@@ -92,8 +91,71 @@ WsjcppObjTree::~WsjcppObjTree() {
9291
9392bool WsjcppObjTree::readTreeFromFile (const std::string &sFilename , std::string &sError ) {
9493 if (!WsjcppCore::fileExists (sFilename )) {
94+ sError = " File not exists" ;
9595 return false ;
9696 }
97+
98+ clearNodes ();
99+ std::ifstream f;
100+ f.open (sFilename .c_str (), std::ios::in | std::ios::binary);
101+
102+ uint32_t nTreeSize = 0 ;
103+ if (!this ->readUInt32 (f, nTreeSize, sError )) {
104+ return false ;
105+ }
106+
107+ if (!this ->readUInt32 (f, m_nLastId, sError )) {
108+ return false ;
109+ }
110+
111+ std::map<uint32_t , WsjcppObjTreeNode *> mapTempIdToNode;
112+ for (int i = 0 ; i < nTreeSize; i++) {
113+ uint16_t nNodeType = 0 ;
114+ if (!this ->readUInt16 (f, nNodeType, sError )) {
115+ return false ;
116+ }
117+
118+ if (m_mapFabricTreeNode.find (nNodeType) == m_mapFabricTreeNode.end ()) {
119+ sError = " On read file could not found node type: " + std::to_string (nNodeType);
120+ return false ;
121+ }
122+
123+ // read parent id
124+ uint32_t nParentId = 0 ;
125+ if (!this ->readUInt32 (f, nParentId, sError )) {
126+ return false ;
127+ }
128+ WsjcppObjTreeNode *pParentNode = nullptr ; // TODO find by Id
129+
130+ if (mapTempIdToNode.find (nParentId) != mapTempIdToNode.end ()) {
131+ pParentNode = mapTempIdToNode[nParentId];
132+ }
133+
134+ // read node id
135+ uint32_t nNodeId = 0 ;
136+ if (!this ->readUInt32 (f, nNodeId, sError )) {
137+ return false ;
138+ }
139+
140+
141+ if (nNodeId > m_nLastId) {
142+ sError = " Node id '" + std::to_string (nNodeId) + " ' could not more then last id " + std::to_string (m_nLastId);
143+ return false ;
144+ }
145+
146+ WsjcppObjTreeNode *pNode = m_mapFabricTreeNode[nNodeType]->create ();
147+ pNode->setId (nNodeId);
148+ pNode->setParent (pParentNode);
149+ if (pParentNode != nullptr ) {
150+ pParentNode->addChild (pNode);
151+ }
152+ if (!pNode->readDataPartFromFile (f, sError )) {
153+ return false ;
154+ }
155+ mapTempIdToNode[nNodeId] = pNode;
156+ m_vNodes.push_back (pNode);
157+ }
158+ f.close ();
97159 return true ;
98160}
99161
@@ -222,24 +284,43 @@ std::string WsjcppObjTree::toString() { // for printing
222284// ---------------------------------------------------------------------
223285
224286void WsjcppObjTree::writeUInt32 (std::ofstream &f, uint32_t nVal) {
287+ const char *pBuffer = reinterpret_cast <const char *>(&nVal);
288+ f.write (pBuffer, 4 );
289+ }
290+
291+ // ---------------------------------------------------------------------
292+
293+ bool WsjcppObjTree::readUInt32 (std::ifstream &f, uint32_t &nVal, std::string &sError ) {
225294 // not for multithreading
226- // TODO redesign to reinterpret_cast<const char *>(&m_nValue);
227- static unsigned char arrInteger[4 ];
228- arrInteger[0 ] = (nVal >> 24 ) & 0xFF ;
229- arrInteger[1 ] = (nVal >> 16 ) & 0xFF ;
230- arrInteger[2 ] = (nVal >> 8 ) & 0xFF ;
231- arrInteger[3 ] = nVal & 0xFF ;
232- f.write ((const char *)arrInteger, 4 );
295+ static char arrInteger[4 ];
296+ f.read (arrInteger, 4 );
297+ if (!f) {
298+ sError = " Could not read. File broken. Can read " + std::to_string (f.gcount ());
299+ return false ;
300+ }
301+ nVal = *reinterpret_cast <uint32_t *>(arrInteger);
302+ return true ;
233303}
234304
235305// ---------------------------------------------------------------------
236306
237307void WsjcppObjTree::writeUInt16 (std::ofstream &f, uint16_t nVal) {
308+ const char *pBuffer = reinterpret_cast <const char *>(&nVal);
309+ f.write (pBuffer, 2 );
310+ }
311+
312+ // ---------------------------------------------------------------------
313+
314+ bool WsjcppObjTree::readUInt16 (std::ifstream &f, uint16_t &nVal, std::string &sError ) {
238315 // not for multithreading
239- static unsigned char arrShort[2 ];
240- arrShort[0 ] = (nVal >> 8 ) & 0xFF ;
241- arrShort[1 ] = nVal & 0xFF ;
242- f.write ((const char *)arrShort, 2 );
316+ static char arrShort[2 ];
317+ f.read (arrShort, 2 );
318+ if (!f) {
319+ sError = " Could not read. File broken. Can read " + std::to_string (f.gcount ());
320+ return false ;
321+ }
322+ nVal = *reinterpret_cast <uint16_t *>(arrShort);
323+ return true ;
243324}
244325
245326// ---------------------------------------------------------------------
@@ -337,6 +418,28 @@ const char *WsjcppObjTreeNodeString::getData() {
337418
338419// ---------------------------------------------------------------------
339420
421+ bool WsjcppObjTreeNodeString::readDataPartFromFile (std::ifstream &f, std::string &sError ) {
422+ uint32_t nStringLen = 0 ;
423+ char arrInteger[4 ];
424+ f.read (arrInteger, 4 );
425+ if (!f) {
426+ sError = " WsjcppObjTreeNodeString. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
427+ return false ;
428+ }
429+ nStringLen = *reinterpret_cast <uint32_t *>(arrInteger);
430+ char *pStr = new char [nStringLen];
431+ f.read (pStr, nStringLen);
432+ if (!f) {
433+ delete pStr;
434+ sError = " WsjcppObjTreeNodeString. Could not read string data. File broken. Can read " + std::to_string (f.gcount ());
435+ return false ;
436+ }
437+ m_sValue = std::string (pStr, nStringLen);
438+ return true ;
439+ }
440+
441+ // ---------------------------------------------------------------------
442+
340443std::string WsjcppObjTreeNodeString::toString (const std::string &sIntent ) {
341444 return " string: " + m_sValue;
342445}
@@ -376,6 +479,28 @@ const char *WsjcppObjTreeNodeInteger::getData() {
376479
377480// ---------------------------------------------------------------------
378481
482+ bool WsjcppObjTreeNodeInteger::readDataPartFromFile (std::ifstream &f, std::string &sError ) {
483+ // size
484+ // TODO remove - because this not need
485+ char arrBytes[4 ];
486+ f.read (arrBytes, 4 );
487+ if (!f) {
488+ sError = " WsjcppObjTreeNodeInteger. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
489+ return false ;
490+ }
491+ // value
492+ f.read (arrBytes, 4 );
493+ if (!f) {
494+ sError = " WsjcppObjTreeNodeInteger. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
495+ return false ;
496+ }
497+ static_assert (sizeof (uint32_t ) == 4 , " Expected sizeof(uint32_t) == 4" );
498+ m_nValue = *reinterpret_cast <uint32_t *>(arrBytes);
499+ return true ;
500+ }
501+
502+ // ---------------------------------------------------------------------
503+
379504std::string WsjcppObjTreeNodeInteger::toString (const std::string &sIntent ) {
380505 return " int: " + std::to_string (m_nValue);
381506}
@@ -415,6 +540,28 @@ const char *WsjcppObjTreeNodeFloat::getData() {
415540
416541// ---------------------------------------------------------------------
417542
543+ bool WsjcppObjTreeNodeFloat::readDataPartFromFile (std::ifstream &f, std::string &sError ) {
544+ static_assert (sizeof (float ) == 4 , " Expected sizeof(float) == 4" );
545+ // size
546+ // TODO remove - because this not need
547+ char arrBytes[4 ];
548+ f.read (arrBytes, 4 );
549+ if (!f) {
550+ sError = " WsjcppObjTreeNodeInteger. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
551+ return false ;
552+ }
553+ // value
554+ f.read (arrBytes, 4 );
555+ if (!f) {
556+ sError = " WsjcppObjTreeNodeFloat. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
557+ return false ;
558+ }
559+ m_nValue = *reinterpret_cast <float *>(arrBytes);
560+ return true ;
561+ }
562+
563+ // ---------------------------------------------------------------------
564+
418565std::string WsjcppObjTreeNodeFloat::toString (const std::string &sIntent ) {
419566 return " float: " + std::to_string (m_nValue);
420567}
@@ -454,6 +601,29 @@ const char *WsjcppObjTreeNodeDouble::getData() {
454601
455602// ---------------------------------------------------------------------
456603
604+ bool WsjcppObjTreeNodeDouble::readDataPartFromFile (std::ifstream &f, std::string &sError ) {
605+ static_assert (sizeof (double ) == 8 , " Expected sizeof(double) == 8" );
606+ // size
607+ // TODO remove - because this not need
608+ char arrBytes4[4 ];
609+ f.read (arrBytes4, 4 );
610+ if (!f) {
611+ sError = " WsjcppObjTreeNodeInteger. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
612+ return false ;
613+ }
614+ // value
615+ char arrBytes[8 ];
616+ f.read (arrBytes, 8 );
617+ if (!f) {
618+ sError = " WsjcppObjTreeNodeDouble. Could not read string len. File broken. Can read " + std::to_string (f.gcount ());
619+ return false ;
620+ }
621+ m_nValue = *reinterpret_cast <double *>(arrBytes);
622+ return true ;
623+ }
624+
625+ // ---------------------------------------------------------------------
626+
457627std::string WsjcppObjTreeNodeDouble::toString (const std::string &sIntent ) {
458628 return " double: " + std::to_string (m_nValue);
459629}
0 commit comments