XlsFormat - ...

This commit is contained in:
Elena.Subbotina
2020-07-20 14:46:21 +03:00
parent 3ae5b6b0f9
commit 60b032bb06
27 changed files with 189 additions and 170 deletions

View File

@ -33,18 +33,13 @@
#include "CFStreamCacheReader.h"
#include "CFRecord.h"
#include "CFStream.h"
#include <Logic/Biff_records/BOF.h>
#include "../Logic/Biff_records/BOF.h"
namespace XLS
{
CFStreamCacheReader::CFStreamCacheReader(CFStreamPtr stream, GlobalWorkbookInfoPtr global_info)
: stream_(stream),
global_info_(global_info)
StreamCacheReader::StreamCacheReader(const GlobalWorkbookInfoPtr global_info)
: global_info_(global_info)
{
skippable_records_names.push_back("StartBlock");
skippable_records_names.push_back("EndBlock");
@ -52,12 +47,98 @@ global_info_(global_info)
skippable_records_names.push_back("FrtWrapper");
}
CFStreamCacheReader::~CFStreamCacheReader()
StreamCacheReader::~StreamCacheReader()
{
}
// Check if the next read record would be of desired type
const bool StreamCacheReader::checkNextRecord(const CFRecordType::TypeId desirable_type, const size_t num_records_to_check)
{
readFromStream(num_records_to_check);
// if we would get what was requested
// ANY_TYPE is checked just to make the fake read from stream and get an error if the stream is ended
for(std::list<CFRecordPtr>::const_iterator it = records_cache.begin(), itEnd = records_cache.end(); it != itEnd; ++it)
{
size_t type = (*it)->getTypeId();
if(desirable_type == (*it)->getTypeId() || desirable_type == CFRecordType::ANY_TYPE)
{
return true;
}
}
return false;
}
// Seek to the next substream (Read all records till EOF then skip EOF)
// Doesn't generate EndOfStreamReached if the stream is the last one
void StreamCacheReader::SkipRecord()
{
if (records_cache.begin() != records_cache.end())
{
CFRecordType::TypeString rec_name = records_cache.front()->getTypeString();
if (rec_name.empty())
Log::warning(L"The extracted record has obsoleted or unknown type(0x" + STR::int2hex_wstr(records_cache.front()->getTypeId(), sizeof(CFRecordType::TypeId)) + L")");
else
Log::warning("The record has been skipped (" + rec_name + ")");
records_cache.pop_front();
}
}
const bool StreamCacheReader::SeekToEOF()
{
while(readFromStream(1))
{
if(rt_EOF == records_cache.front()->getTypeId())
{
// records_cache.pop_front(); // Skip EOF
break;
}
records_cache.pop_front(); // Skip non-EOF
}
return true;
}
// Extract the next record from the stream leaving it in the cache for future read.
// Always call resetPointerToBegin for the extracted CFRecord after using it
CFRecordPtr StreamCacheReader::touchTheNextRecord()
{
if(readFromStream(1))// make sure something is in cache
{
return records_cache.front();
}
return CFRecordPtr();
}
// Check the next record type
const CFRecordType::TypeId StreamCacheReader::getNextRecordType()
{
if(isEOF())
{
return rt_NONE;
}
readFromStream(1); // I don't check the result of readFromStream() because it was done implicitly in isEOF()
return records_cache.front()->getTypeId();
}
//---------------------------------------------------------------------------------------------------------
CFStreamCacheReader::CFStreamCacheReader(CFStreamPtr stream, GlobalWorkbookInfoPtr global_info)
: StreamCacheReader(global_info), stream_(stream)
{
}
CFStreamCacheReader::~CFStreamCacheReader()
{
}
// Skip the specified number of unsigned chars without processing
void CFStreamCacheReader::skipNunBytes(const size_t n)
{
if (stream_)
{
stream_->seekFromCurForward(n);
}
}
// Reads the next CFRecord from the CFStream and if its type is not the desired one, caches it for the next call
CFRecordPtr CFStreamCacheReader::getNextRecord(const CFRecordType::TypeId desirable_type, const bool gen_except)
{
@ -132,26 +213,6 @@ CFRecordPtr CFStreamCacheReader::getNextRecord(const CFRecordType::TypeId desira
}
return CFRecordPtr();
}
// Check if the next read record would be of desired type
const bool CFStreamCacheReader::checkNextRecord(const CFRecordType::TypeId desirable_type, const size_t num_records_to_check)
{
readFromStream(num_records_to_check);
// if we would get what was requested
// ANY_TYPE is checked just to make the fake read from stream and get an error if the stream is ended
for(std::list<CFRecordPtr>::const_iterator it = records_cache.begin(), itEnd = records_cache.end(); it != itEnd; ++it)
{
size_t type = (*it)->getTypeId();
if(desirable_type == (*it)->getTypeId() || desirable_type == CFRecordType::ANY_TYPE)
{
return true;
}
}
return false;
}
// Make sure the internal buffer has concrete number of records. Returns number of records read
const size_t CFStreamCacheReader::readFromStream(const size_t num_of_records_min_necessary)
{
@ -170,7 +231,6 @@ const size_t CFStreamCacheReader::readFromStream(const size_t num_of_records_min
return records_cache.size();
}
// Checks whether the next record is Continue and append its data to the real record if so
void CFStreamCacheReader::checkAndAppendContinueData()
{
@ -197,7 +257,6 @@ void CFStreamCacheReader::checkAndAppendContinueData()
}
}
const bool CFStreamCacheReader::isEOF() const
{
if (stream_ == NULL) return true;
@ -205,71 +264,4 @@ const bool CFStreamCacheReader::isEOF() const
return !records_cache.size() && stream_->isEOF();
}
// Skip the specified number of unsigned chars without processing
void CFStreamCacheReader::skipNunBytes(const size_t n)
{
if (stream_)
{
stream_->seekFromCurForward(n);
}
}
// Seek to the next substream (Read all records till EOF then skip EOF)
// Doesn't generate EndOfStreamReached if the stream is the last one
void CFStreamCacheReader::SkipRecord()
{
if (records_cache.begin() != records_cache.end())
{
CFRecordType::TypeString rec_name = records_cache.front()->getTypeString();
if (rec_name.empty())
Log::warning(L"The extracted record has obsoleted or unknown type(0x" + STR::int2hex_wstr(records_cache.front()->getTypeId(), sizeof(CFRecordType::TypeId)) + L")");
else
Log::warning("The record has been skipped (" + rec_name + ")");
records_cache.pop_front();
}
}
const bool CFStreamCacheReader::SeekToEOF()
{
while(readFromStream(1))
{
if(rt_EOF == records_cache.front()->getTypeId())
{
// records_cache.pop_front(); // Skip EOF
break;
}
records_cache.pop_front(); // Skip non-EOF
}
return true;
}
// Extract the next record from the stream leaving it in the cache for future read.
// Always call resetPointerToBegin for the extracted CFRecord after using it
CFRecordPtr CFStreamCacheReader::touchTheNextRecord()
{
if(readFromStream(1))// make sure something is in cache
{
return records_cache.front();
}
return CFRecordPtr();
}
// Check the next record type
const CFRecordType::TypeId CFStreamCacheReader::getNextRecordType()
{
if(isEOF())
{
return rt_NONE;
}
readFromStream(1); // I don't check the result of readFromStream() because it was done implicitly in isEOF()
return records_cache.front()->getTypeId();
}
} // namespace XLS