diff --git a/include/uPDFTypes.h b/include/uPDFTypes.h
index b9adf9f..8e94ee3 100644
--- a/include/uPDFTypes.h
+++ b/include/uPDFTypes.h
@@ -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
diff --git a/src/uPDFTypes.cpp b/src/uPDFTypes.cpp
index 087e308..a4b6835 100644
--- a/src/uPDFTypes.cpp
+++ b/src/uPDFTypes.cpp
@@ -17,6 +17,8 @@
along with uPDFParser. If not, see .
*/
+#include
+
#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;
+ }
}