mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-15 17:10:27 +08:00
XlsFormat - ...
This commit is contained in:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user