ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
NodeImpl.cpp
Go to the documentation of this file.
1 /*
2  * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net)
3  * Modified work Copyright 2018 - 2020 Andy Maloney <asmaloney@gmail.com>
4  *
5  * Permission is hereby granted, free of charge, to any person or organization
6  * obtaining a copy of the software and accompanying documentation covered by
7  * this license (the "Software") to use, reproduce, display, distribute,
8  * execute, and transmit the Software, and to prepare derivative works of the
9  * Software, and to permit third-parties to whom the Software is furnished to
10  * do so, all subject to the following:
11  *
12  * The copyright notices in the Software and this entire statement, including
13  * the above license grant, this restriction and the following disclaimer,
14  * must be included in all copies of the Software, in whole or in part, and
15  * all derivative works of the Software, unless such copies or derivative
16  * works are solely in the form of machine-executable object code generated by
17  * a source language processor.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include "NodeImpl.h"
29 #include "ImageFileImpl.h"
30 #include "SourceDestBufferImpl.h"
31 #include "VectorNodeImpl.h"
32 
33 using namespace e57;
34 
35 NodeImpl::NodeImpl( ImageFileImplWeakPtr destImageFile ) : destImageFile_( destImageFile ), isAttached_( false )
36 {
37  checkImageFileOpen( __FILE__, __LINE__,
38  static_cast<const char *>( __FUNCTION__ ) ); // does checking for all node type ctors
39 }
40 
41 void NodeImpl::checkImageFileOpen( const char *srcFileName, int srcLineNumber, const char *srcFunctionName ) const
42 {
45  if ( !destImageFile->isOpen() )
46  {
47  throw E57Exception( E57_ERROR_IMAGEFILE_NOT_OPEN, "fileName=" + destImageFile->fileName(), srcFileName,
48  srcLineNumber, srcFunctionName );
49  }
50 }
51 
52 bool NodeImpl::isRoot() const
53 {
54  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
55 
56  return parent_.expired();
57 };
58 
60 {
61  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
62 
63  if ( isRoot() )
64  {
66  return shared_from_this();
67  }
68 
69  NodeImplSharedPtr myParent( parent_ );
70 
71  return myParent;
72 }
73 
75 {
76  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
77 
78  if ( isRoot() )
79  {
80  return ( "/" );
81  }
82 
84 
85  if ( p->isRoot() )
86  {
87  return ( "/" + elementName_ );
88  }
89 
90  return ( p->pathName() + "/" + elementName_ );
91 }
92 
93 ustring NodeImpl::relativePathName( const NodeImplSharedPtr &origin, ustring childPathName ) const
94 {
95  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
96  if ( origin == shared_from_this() )
97  {
98  return ( childPathName );
99  }
100 
101  if ( isRoot() )
102  {
105  "this->elementName=" + this->elementName() + " childPathName=" + childPathName );
106  }
107 
110 
111  if ( childPathName.empty() )
112  {
113  return p->relativePathName( origin, elementName_ );
114  }
115 
116  return p->relativePathName( origin, elementName_ + "/" + childPathName );
117 }
118 
120 {
121  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
122 
123  return elementName_;
124 }
125 
127 {
130 }
131 
133 {
134  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
135 
136  return isAttached_;
137 }
138 
140 {
144  isAttached_ = true;
145 }
146 
148 {
151 
152  return imf->fileName();
153 }
154 
155 void NodeImpl::setParent( NodeImplSharedPtr parent, const ustring &elementName )
156 {
158 
166  if ( !parent_.expired() || isAttached_ )
167  {
171  "this->pathName=" + this->pathName() + " newParent->pathName=" + parent->pathName() );
172  }
173 
174  parent_ = parent;
176 
178  if ( parent->isAttached() )
180 }
181 
183 {
185  NodeImplSharedPtr p( shared_from_this() );
186  while ( !p->isRoot() )
187  {
188  p = NodeImplSharedPtr( p->parent_ ); //??? check if bad ptr?
189  }
190 
191  return p;
192 }
193 
194 //??? use visitor?
196 {
200  NodeImplSharedPtr p( shared_from_this() );
201 
202  while ( !p->isRoot() )
203  {
205  p = NodeImplSharedPtr( p->parent_ ); //??? check if bad ptr?
206 
207  switch ( p->type() )
208  {
209  case E57_VECTOR:
210  {
212  std::shared_ptr<VectorNodeImpl> ai( std::static_pointer_cast<VectorNodeImpl>( p ) );
213 
216  if ( !ai->allowHeteroChildren() && ai->childCount() > 1 )
217  return ( true );
218  }
219  break;
223  return ( true );
224  default:
225  break;
226  }
227  }
230  return ( false );
231 }
232 
234 {
239 
240  _verifyPathNameAbsolute( pathName );
241 
242  NodeImplSharedPtr root = _verifyAndGetRoot();
243 
245  return root->get( pathName );
246 }
247 
248 void NodeImpl::set( const ustring &pathName, NodeImplSharedPtr ni, bool autoPathCreate )
249 {
254 
255  _verifyPathNameAbsolute( pathName );
256 
257  NodeImplSharedPtr root = _verifyAndGetRoot();
258 
260  root->set( pathName, ni, autoPathCreate );
261 }
262 
263 void NodeImpl::set( const StringList & /*fields*/, unsigned /*level*/, NodeImplSharedPtr /*ni*/,
264  bool /*autoPathCreate*/ )
265 {
269 }
270 
271 void NodeImpl::checkBuffers( const std::vector<SourceDestBuffer> &sdbufs,
272  bool allowMissing ) //??? convert sdbufs to vector of shared_ptr
273 {
275 
277 
278  StringSet pathNames;
279 
280  for ( unsigned i = 0; i < sdbufs.size(); i++ )
281  {
282  ustring pathName = sdbufs.at( i ).impl()->pathName();
283 
285  if ( sdbufs.at( i ).impl()->capacity() != sdbufs.at( 0 ).impl()->capacity() )
286  {
288  "this->pathName=" + this->pathName() + " sdbuf.pathName=" + pathName +
289  " firstCapacity=" + toString( sdbufs.at( 0 ).impl()->capacity() ) +
290  " secondCapacity=" + toString( sdbufs.at( i ).impl()->capacity() ) );
291  }
292 
295  if ( !pathNames.insert( pathName ).second )
297  "this->pathName=" + this->pathName() + " sdbuf.pathName=" + pathName );
298 
300  if ( !isDefined( pathName ) )
302  "this->pathName=" + this->pathName() + " sdbuf.pathName=" + pathName );
303  }
304 
305  if ( !allowMissing )
306  {
309  checkLeavesInSet( pathNames, shared_from_this() );
310  }
311 }
312 
313 bool NodeImpl::findTerminalPosition( const NodeImplSharedPtr &target, uint64_t &countFromLeft )
314 {
316 
317  if ( this == &*target ) //??? ok?
318  {
319  return true;
320  }
321 
322  switch ( type() )
323  {
324  case E57_STRUCTURE:
325  {
326  auto sni = static_cast<StructureNodeImpl *>( this );
327 
329  int64_t childCount = sni->childCount();
330  for ( int64_t i = 0; i < childCount; ++i )
331  {
332  if ( sni->get( i )->findTerminalPosition( target, countFromLeft ) )
333  {
334  return true;
335  }
336  }
337  }
338  break;
339 
340  case E57_VECTOR:
341  {
342  auto vni = static_cast<VectorNodeImpl *>( this );
343 
345  int64_t childCount = vni->childCount();
346  for ( int64_t i = 0; i < childCount; ++i )
347  {
348  if ( vni->get( i )->findTerminalPosition( target, countFromLeft ) )
349  {
350  return true;
351  }
352  }
353  }
354  break;
355 
357  break; //??? for now, don't search into contents of compressed vector
358 
359  case E57_INTEGER:
360  case E57_SCALED_INTEGER:
361  case E57_FLOAT:
362  case E57_STRING:
363  case E57_BLOB:
364  countFromLeft++;
365  break;
366  }
367 
368  return ( false );
369 }
370 
371 #ifdef E57_DEBUG
372 void NodeImpl::dump( int indent, std::ostream &os ) const
373 {
375  os << space( indent ) << "elementName: " << elementName_ << std::endl;
376  os << space( indent ) << "isAttached: " << isAttached_ << std::endl;
377  os << space( indent ) << "path: " << pathName() << std::endl;
378 }
379 
380 bool NodeImpl::_verifyPathNameAbsolute( const ustring &inPathName )
381 {
382  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
383 
385  bool isRelative = false;
386  std::vector<ustring> fields;
388 
389  imf->pathNameParse( inPathName, isRelative,
390  fields ); // throws if bad pathName
391 
393  if ( isRelative )
394  {
395  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "this->pathName=" + this->pathName() + " pathName=" + inPathName );
396  }
397 
398  return isRelative;
399 }
400 
401 NodeImplSharedPtr NodeImpl::_verifyAndGetRoot()
402 {
404  NodeImplSharedPtr root( shared_from_this()->getRoot() );
405 
408  switch ( root->type() )
409  {
410  case E57_STRUCTURE:
411  case E57_VECTOR: //??? COMPRESSED_VECTOR?
412  break;
413  default:
414  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "root invalid for this->pathName=" + this->pathName() );
415  }
416 
417  return root;
418 }
419 #endif
std::vector< PCLPointField > fields
#define E57_EXCEPTION2(ecode, context)
Definition: Common.h:68
#define E57_EXCEPTION1(ecode)
!! inline these rather than macros?
Definition: Common.h:66
Object thrown by E57 API functions to communicate the conditions of an error.
Definition: E57Exception.h:100
ustring imageFileName() const
Definition: NodeImpl.cpp:147
ImageFileImplWeakPtr destImageFile_
Definition: NodeImpl.h:94
ustring elementName_
Definition: NodeImpl.h:96
ImageFileImplSharedPtr destImageFile()
Definition: NodeImpl.cpp:126
virtual NodeType type() const =0
NodeImpl(ImageFileImplWeakPtr destImageFile)
Definition: NodeImpl.cpp:35
ustring relativePathName(const NodeImplSharedPtr &origin, ustring childPathName=ustring()) const
Definition: NodeImpl.cpp:93
bool findTerminalPosition(const NodeImplSharedPtr &target, uint64_t &countFromLeft)
Definition: NodeImpl.cpp:313
void checkBuffers(const std::vector< SourceDestBuffer > &sdbufs, bool allowMissing)
Definition: NodeImpl.cpp:271
virtual void setAttachedRecursive()
Definition: NodeImpl.cpp:139
bool isAttached_
Definition: NodeImpl.h:97
bool isAttached() const
Definition: NodeImpl.cpp:132
virtual void set(const ustring &pathName, NodeImplSharedPtr ni, bool autoPathCreate=false)
Definition: NodeImpl.cpp:248
void checkImageFileOpen(const char *srcFileName, int srcLineNumber, const char *srcFunctionName) const
Definition: NodeImpl.cpp:41
NodeImplSharedPtr getRoot()
Definition: NodeImpl.cpp:182
virtual bool isDefined(const ustring &pathName)=0
ustring elementName() const
Definition: NodeImpl.cpp:119
virtual void checkLeavesInSet(const StringSet &pathNames, NodeImplSharedPtr origin)=0
NodeImplSharedPtr parent()
Definition: NodeImpl.cpp:59
virtual NodeImplSharedPtr get(const ustring &pathName)
Definition: NodeImpl.cpp:233
void setParent(NodeImplSharedPtr parent, const ustring &elementName)
Definition: NodeImpl.cpp:155
virtual void dump(int indent=0, std::ostream &os=std::cout) const
Definition: NodeImpl.cpp:372
bool isRoot() const
Definition: NodeImpl.cpp:52
ustring pathName() const
Definition: NodeImpl.cpp:74
bool isTypeConstrained()
Definition: NodeImpl.cpp:195
NodeImplWeakPtr parent_
Definition: NodeImpl.h:95
virtual int64_t childCount() const
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
std::shared_ptr< class NodeImpl > NodeImplSharedPtr
Definition: Common.h:190
std::weak_ptr< class ImageFileImpl > ImageFileImplWeakPtr
Definition: Common.h:189
std::shared_ptr< class ImageFileImpl > ImageFileImplSharedPtr
Definition: Common.h:188
@ E57_ERROR_BUFFER_DUPLICATE_PATHNAME
duplicate pathname in CompressedVectorNode read/write
Definition: E57Exception.h:72
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
Definition: E57Exception.h:56
@ E57_ERROR_IMAGEFILE_NOT_OPEN
destImageFile is no longer open
Definition: E57Exception.h:91
@ E57_ERROR_BUFFER_SIZE_MISMATCH
SourceDestBuffers not all same size.
Definition: E57Exception.h:71
@ E57_ERROR_ALREADY_HAS_PARENT
node already has a parent
Definition: E57Exception.h:89
@ E57_ERROR_BAD_PATH_NAME
E57 path name is not well formed.
Definition: E57Exception.h:83
@ E57_ERROR_PATH_UNDEFINED
E57 element path well formed but not defined.
Definition: E57Exception.h:67
std::string ustring
UTF-8 encodeded Unicode string.
Definition: E57Format.h:54
std::set< std::string > StringSet
Definition: Common.h:194
@ E57_COMPRESSED_VECTOR
CompressedVectorNode class.
Definition: E57Format.h:61
@ E57_BLOB
BlobNode class.
Definition: E57Format.h:66
@ E57_STRUCTURE
StructureNode class.
Definition: E57Format.h:59
@ E57_VECTOR
VectorNode class.
Definition: E57Format.h:60
@ E57_INTEGER
IntegerNode class.
Definition: E57Format.h:62
@ E57_SCALED_INTEGER
ScaledIntegerNode class.
Definition: E57Format.h:63
@ E57_FLOAT
FloatNode class.
Definition: E57Format.h:64
@ E57_STRING
StringNode class.
Definition: E57Format.h:65
std::string toString(T x)
Definition: Common.h:80
std::vector< std::string > StringList
Definition: Common.h:193
std::string space(size_t n)
Definition: Common.h:73