Skip to content

Commit

Permalink
Add ability to use char* input (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
jean-noelp authored and asmaloney committed Jun 3, 2019
1 parent bd2af2d commit 100fca5
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/E57Format.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ class ImageFile
public:
ImageFile() = delete;
ImageFile(const ustring& fname, const ustring& mode, ReadChecksumPolicy checksumPolicy = CHECKSUM_POLICY_ALL );
ImageFile(const char* input, const uint64_t size, ReadChecksumPolicy checksumPolicy = CHECKSUM_POLICY_ALL );

StructureNode root() const;
void close();
Expand Down
129 changes: 127 additions & 2 deletions src/CheckedFile.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,68 @@ constexpr size_t CheckedFile::physicalPageSize;
constexpr uint64_t CheckedFile::physicalPageSizeMask;
constexpr size_t CheckedFile::logicalPageSize;


/// Tool class to read buffer efficiently without
/// multiplying copy operations.
///
/// WARNING: pointer input is handled by user!
class e57::BufferView
{
public:
/// @param[IN] input: filled buffer owned by caller.
/// @param[IN] size: size of input
BufferView( const char* input, uint64_t size ) :
stream_( input ),
streamSize_( size )
{
}

uint64_t pos() const
{
return cursorStream_;
}

bool seek( uint64_t offset, int whence )
{
if ( whence == SEEK_CUR )
{
cursorStream_ += offset;
}
else if ( whence == SEEK_SET )
{
cursorStream_ = offset;
}
else if ( whence == SEEK_END )
{
cursorStream_ = streamSize_ - offset;
}

if ( cursorStream_ > streamSize_ )
{
cursorStream_ = streamSize_;
return false;
}

return true;
}

void read( char* buffer, uint64_t count )
{
const uint64_t start = cursorStream_;
for ( uint64_t i = 0; i < count; ++i )
{
buffer[i] = stream_[start + i];
++cursorStream_;
}
}

private:
const uint64_t streamSize_;
uint64_t cursorStream_ = 0;
const char* stream_;
};


CheckedFile::CheckedFile( const ustring &fileName, Mode mode, ReadChecksumPolicy policy ) :
fileName_(fileName),
checkSumPolicy_( policy )
Expand Down Expand Up @@ -110,6 +172,21 @@ CheckedFile::CheckedFile( const ustring &fileName, Mode mode, ReadChecksumPolicy
}
}


CheckedFile::CheckedFile( const char* input, const uint64_t size, ReadChecksumPolicy policy ) :
fileName_( "<StreamBuffer>" ),
checkSumPolicy_( policy )
{
bufView_ = new BufferView(input, size);

readOnly_ = true;

physicalLength_ = lseek64(0LL, SEEK_END);
lseek64( 0, SEEK_SET );

logicalLength_ = physicalToLogical( physicalLength_ );
}

int CheckedFile::open64( const ustring &fileName, int flags, int mode )
{
//??? handle utf-8 file names?
Expand Down Expand Up @@ -384,6 +461,30 @@ void CheckedFile::seek(uint64_t offset, OffsetMode omode)

uint64_t CheckedFile::lseek64(int64_t offset, int whence)
{
if ( fd_ < 0 && bufView_ != nullptr )
{
int64_t result;
if ( bufView_->seek(offset, whence) )
{
result = bufView_->pos();
}
else
{
result = -1;
}

if ( result < 0 )
{
throw E57_EXCEPTION2(E57_ERROR_LSEEK_FAILED,
"fileName=" + fileName_
+ " offset=" + toString(offset)
+ " whence=" + toString(whence)
+ " result=" + toString(result));
}

return static_cast<uint64_t>(result);
}

#if defined(_WIN32)
# if defined(_MSC_VER) || defined(__MINGW32__) //<rs 2010-06-16> mingw _is_ WIN32!
__int64 result = _lseeki64(fd_, offset, whence);
Expand All @@ -403,7 +504,8 @@ uint64_t CheckedFile::lseek64(int64_t offset, int whence)
#else
# error "no supported OS platform defined"
#endif
if (result < 0)

if ( result < 0 )
{
throw E57_EXCEPTION2(E57_ERROR_LSEEK_FAILED,
"fileName=" + fileName_
Expand Down Expand Up @@ -476,7 +578,8 @@ void CheckedFile::extend(uint64_t newLength, OffsetMode omode)
uint64_t currentLogicalLength = length(Logical);

/// Make sure we are trying to make file longer
if (newLogicalLength < currentLogicalLength) {
if (newLogicalLength < currentLogicalLength)
{
throw E57_EXCEPTION2(E57_ERROR_INTERNAL,
"fileName=" + fileName_
+ " newLength=" + toString(newLogicalLength)
Expand Down Expand Up @@ -565,6 +668,15 @@ void CheckedFile::close()

fd_ = -1;
}

if (bufView_ != nullptr)
{
delete bufView_;
bufView_ = nullptr;

// WARNING: do NOT delete buffer of bufView_ because
// pointer is handled by user !!
}
}

void CheckedFile::unlink()
Expand Down Expand Up @@ -658,6 +770,19 @@ void CheckedFile::readPhysicalPage(char* page_buffer, uint64_t page)
/// Seek to start of physical page
seek( page*physicalPageSize, Physical );

if ( fd_ < 0 && bufView_ != nullptr )
{
bufView_->read(page_buffer, physicalPageSize);
size_t result = physicalPageSize;

if ( result < 0 || static_cast<size_t>(result) != physicalPageSize )
{
throw E57_EXCEPTION2(E57_ERROR_READ_FAILED, "fileName=" + fileName_ + " result=" + toString(result));
}

return;
}

#if defined(_MSC_VER)
int result = ::_read( fd_, page_buffer, physicalPageSize );
#elif defined(__GNUC__)
Expand Down
7 changes: 7 additions & 0 deletions src/CheckedFile.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
#include "Common.h"

namespace e57 {
/// Tool class to read buffer efficiently without
/// multiplying copy operations.
///
/// WARNING: pointer input is handled by user!
class BufferView;

class CheckedFile
{
Expand All @@ -56,6 +61,7 @@ namespace e57 {
};

CheckedFile( const e57::ustring &fileName, Mode mode, ReadChecksumPolicy policy );
CheckedFile( const char* input, const uint64_t size, ReadChecksumPolicy policy );
~CheckedFile();

void read(char* buf, size_t nRead, size_t bufSize = 0);
Expand Down Expand Up @@ -97,6 +103,7 @@ namespace e57 {
ReadChecksumPolicy checkSumPolicy_ = CHECKSUM_POLICY_ALL;

int fd_ = -1;
BufferView* bufView_ = nullptr;
bool readOnly_ = false;
};

Expand Down
6 changes: 6 additions & 0 deletions src/E57Format.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4557,6 +4557,12 @@ ImageFile::ImageFile(const ustring& fname, const ustring& mode, ReadChecksumPoli
impl_->construct2(fname, mode);
}

ImageFile::ImageFile(const char* input, const uint64_t size, ReadChecksumPolicy checksumPolicy)
: impl_( new ImageFileImpl( checksumPolicy ) )
{
impl_->construct2(input, size);
}

/*!
@brief Get the pre-established root StructureNode of the E57 ImageFile.
@details The root node of an ImageFile always exists and is always type StructureNode.
Expand Down
63 changes: 63 additions & 0 deletions src/ImageFileImpl.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,69 @@ namespace e57
}
}

void ImageFileImpl::construct2(const char* input, const uint64_t size)
{
/// Second phase of construction, now we have a well-formed ImageFile object.

#ifdef E57_MAX_VERBOSE
std::cout << "ImageFileImpl() called, fileName=" << fileName << " mode=" << mode << std::endl;
#endif
unusedLogicalStart_ = sizeof(E57FileHeader);
fileName_ = "<StreamBuffer>";

/// Get shared_ptr to this object
ImageFileImplSharedPtr imf = shared_from_this();

isWriter_ = false;
file_ = nullptr;

try
{
/// Open file for reading.
file_ = new CheckedFile( input, size, checksumPolicy );

std::shared_ptr<StructureNodeImpl> root(new StructureNodeImpl(imf));
root_ = root;
root_->setAttachedRecursive();

E57FileHeader header;
readFileHeader(file_, header);

xmlLogicalOffset_ = file_->physicalToLogical(header.xmlPhysicalOffset);
xmlLogicalLength_ = header.xmlLogicalLength;
}
catch (...)
{
delete file_;
file_ = nullptr;

throw;
}

try
{
/// Create parser state, attach its event handers to the SAX2 reader
E57XmlParser parser(imf);

parser.init();

/// Create input source (XML section of E57 file turned into a stream).
E57XmlFileInputSource xmlSection(file_, xmlLogicalOffset_, xmlLogicalLength_);

unusedLogicalStart_ = sizeof(E57FileHeader);

/// Do the parse, building up the node tree
parser.parse( xmlSection );
}
catch (...)
{
delete file_;
file_ = nullptr;

throw;
}
}

void ImageFileImpl::incrWriterCount()
{
writerCount_++;
Expand Down
1 change: 1 addition & 0 deletions src/ImageFileImpl.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace e57
public:
ImageFileImpl( ReadChecksumPolicy policy );
void construct2(const ustring& fileName, const ustring& mode);
void construct2(const char* input, const uint64_t size);
std::shared_ptr<StructureNodeImpl> root();
void close();
void cancel();
Expand Down

0 comments on commit 100fca5

Please sign in to comment.