ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
BlobNodeImpl.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 "BlobNodeImpl.h"
29 #include "CheckedFile.h"
30 #include "ImageFileImpl.h"
31 #include "SectionHeaders.h"
32 
33 namespace e57
34 {
35  BlobNodeImpl::BlobNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t byteCount ) : NodeImpl( destImageFile )
36  {
37  // don't checkImageFileOpen, NodeImpl() will do it
38 
40 
42  blobLogicalLength_ = byteCount;
43 
45  binarySectionLogicalLength_ = sizeof( BlobSectionHeader ) + blobLogicalLength_;
46  unsigned remainder = binarySectionLogicalLength_ % 4;
47  if ( remainder > 0 )
48  {
49  binarySectionLogicalLength_ += 4 - remainder;
50  }
51 
54  binarySectionLogicalStart_ = imf->allocateSpace( binarySectionLogicalLength_, true );
55 
57  BlobSectionHeader header;
58  header.sectionLogicalLength = binarySectionLogicalLength_;
59 #ifdef E57_MAX_VERBOSE
60  header.dump(); //???
61 #endif
62 
64  imf->file_->seek( binarySectionLogicalStart_ );
65  imf->file_->write( reinterpret_cast<char *>( &header ), sizeof( header ) );
66  }
67 
68  BlobNodeImpl::BlobNodeImpl( ImageFileImplWeakPtr destImageFile, int64_t fileOffset, int64_t length ) :
69  NodeImpl( destImageFile )
70  {
72 
73  // don't checkImageFileOpen, NodeImpl() will do it
74 
76 
78  blobLogicalLength_ = length;
79  binarySectionLogicalStart_ = imf->file_->physicalToLogical( fileOffset );
80  binarySectionLogicalLength_ = sizeof( BlobSectionHeader ) + blobLogicalLength_;
81  }
82 
84  {
85  // don't checkImageFileOpen, NodeImpl() will do it
86 
88  if ( ni->type() != E57_BLOB )
89  {
90  return ( false );
91  }
92 
94  std::shared_ptr<BlobNodeImpl> bi( std::static_pointer_cast<BlobNodeImpl>( ni ) );
95 
97  if ( blobLogicalLength_ != bi->blobLogicalLength_ )
98  {
99  return ( false );
100  }
101 
103 
105  return ( true );
106  }
107 
108  bool BlobNodeImpl::isDefined( const ustring &pathName )
109  {
110  // don't checkImageFileOpen, NodeImpl() will do it
111 
113  return pathName.empty();
114  }
115 
117  {
118  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
119  return ( blobLogicalLength_ );
120  }
121 
122  void BlobNodeImpl::read( uint8_t *buf, int64_t start, size_t count )
123  {
124  //??? check start not negative
125 
126  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
127  if ( static_cast<uint64_t>( start ) + count > blobLogicalLength_ )
128  {
130  "this->pathName=" + this->pathName() + " start=" + toString( start ) +
131  " count=" + toString( count ) + " length=" + toString( blobLogicalLength_ ) );
132  }
133 
135  imf->file_->seek( binarySectionLogicalStart_ + sizeof( BlobSectionHeader ) + start );
136  imf->file_->read( reinterpret_cast<char *>( buf ),
137  static_cast<size_t>( count ) ); //??? arg1 void* ?
138  }
139 
140  void BlobNodeImpl::write( uint8_t *buf, int64_t start, size_t count )
141  {
142  //??? check start not negative
143  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
144 
146 
147  if ( !destImageFile->isWriter() )
148  {
149  throw E57_EXCEPTION2( E57_ERROR_FILE_IS_READ_ONLY, "fileName=" + destImageFile->fileName() );
150  }
151  if ( !isAttached() )
152  {
153  throw E57_EXCEPTION2( E57_ERROR_NODE_UNATTACHED, "fileName=" + destImageFile->fileName() );
154  }
155 
156  if ( static_cast<uint64_t>( start ) + count > blobLogicalLength_ )
157  {
159  "this->pathName=" + this->pathName() + " start=" + toString( start ) +
160  " count=" + toString( count ) + " length=" + toString( blobLogicalLength_ ) );
161  }
162 
164  imf->file_->seek( binarySectionLogicalStart_ + sizeof( BlobSectionHeader ) + start );
165  imf->file_->write( reinterpret_cast<char *>( buf ),
166  static_cast<size_t>( count ) ); //??? arg1 void* ?
167  }
168 
170  {
171  // don't checkImageFileOpen
172 
175  if ( pathNames.find( relativePathName( origin ) ) == pathNames.end() )
176  {
177  throw E57_EXCEPTION2( E57_ERROR_NO_BUFFER_FOR_ELEMENT, "this->pathName=" + this->pathName() );
178  }
179  }
180 
182  const char *forcedFieldName )
183  {
184  // don't checkImageFileOpen
185 
186  ustring fieldName;
187  if ( forcedFieldName != nullptr )
188  {
189  fieldName = forcedFieldName;
190  }
191  else
192  {
193  fieldName = elementName_;
194  }
195 
196  //??? need to implement
197  //??? Type --> type
198  //??? need to have length?, check same as in section header?
199  uint64_t physicalOffset = cf.logicalToPhysical( binarySectionLogicalStart_ );
200  cf << space( indent ) << "<" << fieldName << " type=\"Blob\" fileOffset=\"" << physicalOffset << "\" length=\""
201  << blobLogicalLength_ << "\"/>\n";
202  }
203 
204 #ifdef E57_DEBUG
205  void BlobNodeImpl::dump( int indent, std::ostream &os ) const
206  {
207  // don't checkImageFileOpen
208  os << space( indent ) << "type: Blob"
209  << " (" << type() << ")" << std::endl;
210  NodeImpl::dump( indent, os );
211  os << space( indent ) << "blobLogicalLength_: " << blobLogicalLength_ << std::endl;
212  os << space( indent ) << "binarySectionLogicalStart: " << binarySectionLogicalStart_ << std::endl;
213  os << space( indent ) << "binarySectionLogicalLength: " << binarySectionLogicalLength_ << std::endl;
214  // size_t i;
215  // for (i = 0; i < blobLogicalLength_ && i < 10; i++) {
216  // uint8_t b;
217  // read(&b, i, 1);
218  // os << space(indent) << "data[" << i << "]: "<< static_cast<int>(b)
219  // << std::endl;
220  // }
221  // if (i < blobLogicalLength_)
222  // os << space(indent) << "more data unprinted..." << std::endl;
223  }
224 #endif
225 
226 }
int count
#define E57_EXCEPTION2(ecode, context)
Definition: Common.h:68
void write(uint8_t *buf, int64_t start, size_t count)
void writeXml(ImageFileImplSharedPtr imf, CheckedFile &cf, int indent, const char *forcedFieldName=nullptr) override
void dump(int indent=0, std::ostream &os=std::cout) const override
void checkLeavesInSet(const StringSet &pathNames, NodeImplSharedPtr origin) override
void read(uint8_t *buf, int64_t start, size_t count)
BlobNodeImpl(ImageFileImplWeakPtr destImageFile, int64_t byteCount)
bool isTypeEquivalent(NodeImplSharedPtr ni) override
NodeType type() const override
Definition: BlobNodeImpl.h:40
bool isDefined(const ustring &pathName) override
static uint64_t logicalToPhysical(uint64_t logicalOffset)
Definition: CheckedFile.h:112
ImageFileImplWeakPtr destImageFile_
Definition: NodeImpl.h:94
ustring elementName_
Definition: NodeImpl.h:96
ImageFileImplSharedPtr destImageFile()
Definition: NodeImpl.cpp:126
ustring relativePathName(const NodeImplSharedPtr &origin, ustring childPathName=ustring()) const
Definition: NodeImpl.cpp:93
bool isAttached() const
Definition: NodeImpl.cpp:132
void checkImageFileOpen(const char *srcFileName, int srcLineNumber, const char *srcFunctionName) const
Definition: NodeImpl.cpp:41
virtual void dump(int indent=0, std::ostream &os=std::cout) const
Definition: NodeImpl.cpp:372
ustring pathName() const
Definition: NodeImpl.cpp:74
__host__ __device__ float length(float2 v)
Definition: cutil_math.h:1162
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_FILE_IS_READ_ONLY
can't modify read only file
Definition: E57Exception.h:60
@ E57_ERROR_BAD_API_ARGUMENT
bad API function argument provided by user
Definition: E57Exception.h:59
@ E57_ERROR_NO_BUFFER_FOR_ELEMENT
Definition: E57Exception.h:69
@ E57_ERROR_NODE_UNATTACHED
node is not yet attached to tree of ImageFile
Definition: E57Exception.h:88
std::string ustring
UTF-8 encodeded Unicode string.
Definition: E57Format.h:54
std::set< std::string > StringSet
Definition: Common.h:194
@ E57_BLOB
BlobNode class.
Definition: E57Format.h:66
std::string toString(T x)
Definition: Common.h:80
std::string space(size_t n)
Definition: Common.h:73
void dump(int indent=0, std::ostream &os=std::cout)