Manage stream data reading (without filter interpretation)

This commit is contained in:
Grégory Soutadé 2021-12-18 17:27:35 +01:00
parent 29a93e2cfc
commit d8bbf8a21d
2 changed files with 65 additions and 6 deletions

View File

@ -266,15 +266,31 @@ namespace uPDFParser
class Stream : public DataType
{
public:
Stream(int startOffset, int endOffset):
DataType(DataType::TYPE::STREAM), startOffset(startOffset),
endOffset(endOffset)
Stream(Dictionary& dict, int startOffset, int endOffset, unsigned char* data=0, unsigned int dataLength=0,
bool freeData=false, int fd=0):
DataType(DataType::TYPE::STREAM), dict(dict), fd(fd),
startOffset(startOffset), endOffset(endOffset),
_data(data), _dataLength(dataLength), freeData(false)
{}
virtual DataType* clone() {return new Stream(startOffset, endOffset);}
virtual std::string str() { return "stream\nendstream\n";}
~Stream() {
if (_data && freeData) delete[] _data;
}
virtual DataType* clone() {return new Stream(dict, startOffset, endOffset,
_data, _dataLength, false, fd);}
virtual std::string str();
unsigned char* data();
unsigned int dataLength() {return _dataLength;}
void setData(unsigned char* data, unsigned int dataLength, bool freeData=false);
private:
Dictionary& dict;
int fd;
int startOffset, endOffset;
unsigned char* _data;
unsigned int _dataLength;
bool freeData;
};
class Null : public DataType

View File

@ -17,6 +17,8 @@
along with uPDFParser. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include "uPDFTypes.h"
#include "uPDFParser_common.h"
@ -71,7 +73,7 @@ namespace uPDFParser
res += (*it)->str();
}
return res + std::string("]");
return res + " ]";
}
void Dictionary::addData(const std::string& key, DataType* value)
@ -93,4 +95,45 @@ namespace uPDFParser
return res + std::string(">>\n");
}
std::string Stream::str()
{
std::string res = "stream\n";
const char* streamData = (const char*)data(); // Force reading if not in memory
res += std::string(streamData, _dataLength);
res += "endstream\n";
return res;
}
unsigned char* Stream::data()
{
if (!_data)
{
if (!fd)
EXCEPTION(INVALID_STREAM, "Accessing data, but no file descriptor supplied");
_dataLength = endOffset - startOffset;
_data = new unsigned char[_dataLength];
freeData = true;
lseek(fd, startOffset, SEEK_SET);
int ret = ::read(fd, _data, _dataLength);
if ((unsigned int)ret != _dataLength)
EXCEPTION(INVALID_STREAM, "Not enough data to read (" << ret << ")");
}
return _data;
}
void Stream::setData(unsigned char* data, unsigned int dataLength, bool freeData)
{
if (_data && freeData)
delete[] _data;
this->_data = data;
this->_dataLength = dataLength;
this->freeData = freeData;
}
}