diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/poppler/Object.h')
-rw-r--r-- | Build/source/libs/poppler/poppler-src/poppler/Object.h | 308 |
1 files changed, 168 insertions, 140 deletions
diff --git a/Build/source/libs/poppler/poppler-src/poppler/Object.h b/Build/source/libs/poppler/poppler-src/poppler/Object.h index 312a8eb32cb..f2ca20d1559 100644 --- a/Build/source/libs/poppler/poppler-src/poppler/Object.h +++ b/Build/source/libs/poppler/poppler-src/poppler/Object.h @@ -15,11 +15,11 @@ // // Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org> // Copyright (C) 2008 Kees Cook <kees@outflux.net> -// Copyright (C) 2008, 2010 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2008, 2010, 2017 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2009 Jakub Wilk <jwilk@jwilk.net> // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it> // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de> -// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com> +// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com> // Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com> // Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com> // @@ -38,6 +38,7 @@ #include <set> #include <stdio.h> #include <string.h> +#include <limits.h> #include "goo/gtypes.h" #include "goo/gmem.h" #include "goo/GooString.h" @@ -65,6 +66,12 @@ abort(); \ } +#define CHECK_NOT_DEAD \ + if (unlikely(type == objDead)) { \ + error(errInternal, 0, "Call to dead object"); \ + abort(); \ + } + class XRef; class Array; class Dict; @@ -105,165 +112,187 @@ enum ObjType { objNone, // uninitialized object // poppler-only objects - objInt64 // integer with at least 64-bits + objInt64, // integer with at least 64-bits + objDead // and object after shallowCopy }; -#define numObjTypes 15 // total number of object types +#define numObjTypes 16 // total number of object types //------------------------------------------------------------------------ // Object //------------------------------------------------------------------------ #ifdef DEBUG_MEM -#define initObj(t) zeroUnion(); ++numAlloc[type = t] +#define initObj(t) free(); zeroUnion(); ++numAlloc[type = t] #else -#define initObj(t) zeroUnion(); type = t +#define initObj(t) free(); zeroUnion(); type = t +#endif + +#ifdef DEBUG_MEM +#define constructObj(t) ++numAlloc[type = t] +#else +#define constructObj(t) type = t #endif class Object { public: // clear the anonymous union as best we can -- clear at least a pointer - void zeroUnion() { this->name = NULL; } + void zeroUnion() { this->cString = NULL; } // Default constructor. Object(): type(objNone) { zeroUnion(); } - - // Initialize an object. - Object *initBool(GBool boolnA) - { initObj(objBool); booln = boolnA; return this; } - Object *initInt(int intgA) - { initObj(objInt); intg = intgA; return this; } - Object *initReal(double realA) - { initObj(objReal); real = realA; return this; } - Object *initString(GooString *stringA) - { initObj(objString); string = stringA; return this; } - Object *initName(const char *nameA) - { initObj(objName); name = copyString(nameA); return this; } - Object *initNull() - { initObj(objNull); return this; } - Object *initArray(XRef *xref); - Object *initDict(XRef *xref); - Object *initDict(Dict *dictA); - Object *initStream(Stream *streamA); - Object *initRef(int numA, int genA) - { initObj(objRef); ref.num = numA; ref.gen = genA; return this; } - Object *initCmd(const char *cmdA) - { initObj(objCmd); cmd = copyString(cmdA); return this; } - Object *initError() - { initObj(objError); return this; } - Object *initEOF() - { initObj(objEOF); return this; } - Object *initInt64(long long int64gA) - { initObj(objInt64); int64g = int64gA; return this; } - - // Copy an object. - Object *copy(Object *obj); - Object *shallowCopy(Object *obj) { - *obj = *this; - return obj; - } + ~Object(); + + explicit Object(GBool boolnA) + { constructObj(objBool); booln = boolnA; } + explicit Object(int intgA) + { constructObj(objInt); intg = intgA; } + explicit Object(ObjType typeA) + { constructObj(typeA); } + explicit Object(double realA) + { constructObj(objReal); real = realA; } + explicit Object(GooString *stringA) + { constructObj(objString); string = stringA; } + Object(ObjType typeA, const char *stringA) + { constructObj(typeA); cString = copyString(stringA); } + explicit Object(long long int64gA) + { constructObj(objInt64); int64g = int64gA; } + explicit Object(Array *arrayA) + { constructObj(objArray); array = arrayA; } + explicit Object(Dict *dictA) + { constructObj(objDict); dict = dictA; } + explicit Object(Stream *streamA) + { constructObj(objStream); stream = streamA; } + Object(int numA, int genA) + { constructObj(objRef); ref.num = numA; ref.gen = genA; } + template<typename T> Object(T) = delete; + + Object(Object&& other); + Object& operator=(Object&& other); + + Object &operator=(const Object &other) = delete; + Object(const Object &other) = delete; + + // Set object to null. + void setToNull() { initObj(objNull); } + + // Copy this to obj + Object copy() const; // If object is a Ref, fetch and return the referenced object. // Otherwise, return a copy of the object. - Object *fetch(XRef *xref, Object *obj, int recursion = 0); - - // Free object contents. - void free(); + Object fetch(XRef *xref, int recursion = 0) const; // Type checking. - ObjType getType() { return type; } - GBool isBool() { return type == objBool; } - GBool isInt() { return type == objInt; } - GBool isReal() { return type == objReal; } - GBool isNum() { return type == objInt || type == objReal || type == objInt64; } - GBool isString() { return type == objString; } - GBool isName() { return type == objName; } - GBool isNull() { return type == objNull; } - GBool isArray() { return type == objArray; } - GBool isDict() { return type == objDict; } - GBool isStream() { return type == objStream; } - GBool isRef() { return type == objRef; } - GBool isCmd() { return type == objCmd; } - GBool isError() { return type == objError; } - GBool isEOF() { return type == objEOF; } - GBool isNone() { return type == objNone; } - GBool isInt64() { return type == objInt64; } - GBool isIntOrInt64() { return type == objInt || type == objInt64; } + ObjType getType() const { CHECK_NOT_DEAD; return type; } + GBool isBool() const { CHECK_NOT_DEAD; return type == objBool; } + GBool isInt() const { CHECK_NOT_DEAD; return type == objInt; } + GBool isReal() const { CHECK_NOT_DEAD; return type == objReal; } + GBool isNum() const { CHECK_NOT_DEAD; return type == objInt || type == objReal || type == objInt64; } + GBool isString() const { CHECK_NOT_DEAD; return type == objString; } + GBool isName() const { CHECK_NOT_DEAD; return type == objName; } + GBool isNull() const { CHECK_NOT_DEAD; return type == objNull; } + GBool isArray() const { CHECK_NOT_DEAD; return type == objArray; } + GBool isDict() const { CHECK_NOT_DEAD; return type == objDict; } + GBool isStream() const { CHECK_NOT_DEAD; return type == objStream; } + GBool isRef() const { CHECK_NOT_DEAD; return type == objRef; } + GBool isCmd() const { CHECK_NOT_DEAD; return type == objCmd; } + GBool isError() const { CHECK_NOT_DEAD; return type == objError; } + GBool isEOF() const { CHECK_NOT_DEAD; return type == objEOF; } + GBool isNone() const { CHECK_NOT_DEAD; return type == objNone; } + GBool isInt64() const { CHECK_NOT_DEAD; return type == objInt64; } + GBool isIntOrInt64() const { CHECK_NOT_DEAD; return type == objInt || type == objInt64; } // Special type checking. - GBool isName(const char *nameA) - { return type == objName && !strcmp(name, nameA); } - GBool isDict(const char *dictType); - GBool isStream(const char *dictType); - GBool isCmd(const char *cmdA) - { return type == objCmd && !strcmp(cmd, cmdA); } + GBool isName(const char *nameA) const + { return type == objName && !strcmp(cString, nameA); } + GBool isDict(const char *dictType) const; + GBool isStream(char *dictType) const; + GBool isCmd(const char *cmdA) const + { return type == objCmd && !strcmp(cString, cmdA); } // Accessors. - GBool getBool() { OBJECT_TYPE_CHECK(objBool); return booln; } - int getInt() { OBJECT_TYPE_CHECK(objInt); return intg; } - double getReal() { OBJECT_TYPE_CHECK(objReal); return real; } + GBool getBool() const { OBJECT_TYPE_CHECK(objBool); return booln; } + int getInt() const { OBJECT_TYPE_CHECK(objInt); return intg; } + double getReal() const { OBJECT_TYPE_CHECK(objReal); return real; } // Note: integers larger than 2^53 can not be exactly represented by a double. // Where the exact value of integers up to 2^63 is required, use isInt64()/getInt64(). - double getNum() { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal); + double getNum() const { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal); return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; } - GooString *getString() { OBJECT_TYPE_CHECK(objString); return string; } + double getNum(bool *ok) const { + if (unlikely(type != objInt && type != objInt64 && type != objReal)) { + *ok = false; + return 0.; + } + return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; + } + GooString *getString() const { OBJECT_TYPE_CHECK(objString); return string; } // After takeString() the only method that should be called for the object is free() // because the object it's not expected to have a NULL string. GooString *takeString() { OBJECT_TYPE_CHECK(objString); GooString *s = string; string = NULL; return s; } - char *getName() { OBJECT_TYPE_CHECK(objName); return name; } - Array *getArray() { OBJECT_TYPE_CHECK(objArray); return array; } - Dict *getDict() { OBJECT_TYPE_CHECK(objDict); return dict; } - Stream *getStream() { OBJECT_TYPE_CHECK(objStream); return stream; } - Ref getRef() { OBJECT_TYPE_CHECK(objRef); return ref; } - int getRefNum() { OBJECT_TYPE_CHECK(objRef); return ref.num; } - int getRefGen() { OBJECT_TYPE_CHECK(objRef); return ref.gen; } - char *getCmd() { OBJECT_TYPE_CHECK(objCmd); return cmd; } - long long getInt64() { OBJECT_TYPE_CHECK(objInt64); return int64g; } - long long getIntOrInt64() { OBJECT_2TYPES_CHECK(objInt, objInt64); + char *getName() const { OBJECT_TYPE_CHECK(objName); return cString; } + Array *getArray() const { OBJECT_TYPE_CHECK(objArray); return array; } + Dict *getDict() const { OBJECT_TYPE_CHECK(objDict); return dict; } + Stream *getStream() const { OBJECT_TYPE_CHECK(objStream); return stream; } + Ref getRef() const { OBJECT_TYPE_CHECK(objRef); return ref; } + int getRefNum() const { OBJECT_TYPE_CHECK(objRef); return ref.num; } + int getRefGen() const { OBJECT_TYPE_CHECK(objRef); return ref.gen; } + char *getCmd() const { OBJECT_TYPE_CHECK(objCmd); return cString; } + long long getInt64() const { OBJECT_TYPE_CHECK(objInt64); return int64g; } + long long getIntOrInt64() const { OBJECT_2TYPES_CHECK(objInt, objInt64); return type == objInt ? intg : int64g; } // Array accessors. - int arrayGetLength(); - void arrayAdd(Object *elem); + int arrayGetLength() const; + void arrayAdd(Object &&elem); void arrayRemove(int i); - Object *arrayGet(int i, Object *obj, int recursion); - Object *arrayGetNF(int i, Object *obj); + Object arrayGet(int i, int recursion) const; + Object arrayGetNF(int i) const; // Dict accessors. - int dictGetLength(); - void dictAdd(char *key, Object *val); - void dictSet(const char *key, Object *val); + int dictGetLength() const; + void dictAdd(char *key, Object &&val); + void dictSet(const char *key, Object &&val); void dictRemove(const char *key); - GBool dictIs(const char *dictType); - Object *dictLookup(const char *key, Object *obj, int recursion = 0); - Object *dictLookupNF(const char *key, Object *obj); - char *dictGetKey(int i); - Object *dictGetVal(int i, Object *obj); - Object *dictGetValNF(int i, Object *obj); + GBool dictIs(const char *dictType) const; + Object dictLookup(const char *key, int recursion = 0) const; + Object dictLookupNF(const char *key) const; + char *dictGetKey(int i) const; + Object dictGetVal(int i) const; + Object dictGetValNF(int i) const; // Stream accessors. - GBool streamIs(const char *dictType); + GBool streamIs(char *dictType) const; void streamReset(); void streamClose(); - int streamGetChar(); - int streamGetChars(int nChars, Guchar *buffer); - int streamLookChar(); - char *streamGetLine(char *buf, int size); - Goffset streamGetPos(); + int streamGetChar() const; + int streamGetChars(int nChars, Guchar *buffer) const; + int streamLookChar() const; + char *streamGetLine(char *buf, int size) const; + Goffset streamGetPos() const; void streamSetPos(Goffset pos, int dir = 0); - Dict *streamGetDict(); + Dict *streamGetDict() const; // Output. - const char *getTypeName(); - void print(FILE *f = stdout); + const char *getTypeName() const; + void print(FILE *f = stdout) const; // Memory testing. static void memCheck(FILE *f); private: + friend class Array; // Needs free and initNullAfterMalloc + friend class Dict; // Needs free and initNullAfterMalloc + friend class XRef; // Needs free and initNullAfterMalloc + + // Free object contents. + void free(); + + // Only use if are mallocing Objects + void initNullAfterMalloc() { constructObj(objNull); } ObjType type; // object type union { // value for each type: @@ -272,12 +301,11 @@ private: long long int64g; // 64-bit integer double real; // real GooString *string; // string - char *name; // name + char *cString; // name or command, depending on objType Array *array; // array Dict *dict; // dictionary Stream *stream; // stream Ref ref; // indirect reference - char *cmd; // command }; #ifdef DEBUG_MEM @@ -292,20 +320,20 @@ private: #include "Array.h" -inline int Object::arrayGetLength() +inline int Object::arrayGetLength() const { OBJECT_TYPE_CHECK(objArray); return array->getLength(); } -inline void Object::arrayAdd(Object *elem) - { OBJECT_TYPE_CHECK(objArray); array->add(elem); } +inline void Object::arrayAdd(Object &&elem) + { OBJECT_TYPE_CHECK(objArray); array->add(std::move(elem)); } inline void Object::arrayRemove(int i) { OBJECT_TYPE_CHECK(objArray); array->remove(i); } -inline Object *Object::arrayGet(int i, Object *obj, int recursion = 0) - { OBJECT_TYPE_CHECK(objArray); return array->get(i, obj, recursion); } +inline Object Object::arrayGet(int i, int recursion = 0) const + { OBJECT_TYPE_CHECK(objArray); return array->get(i, recursion); } -inline Object *Object::arrayGetNF(int i, Object *obj) - { OBJECT_TYPE_CHECK(objArray); return array->getNF(i, obj); } +inline Object Object::arrayGetNF(int i) const + { OBJECT_TYPE_CHECK(objArray); return array->getNF(i); } //------------------------------------------------------------------------ // Dict accessors. @@ -313,38 +341,38 @@ inline Object *Object::arrayGetNF(int i, Object *obj) #include "Dict.h" -inline int Object::dictGetLength() +inline int Object::dictGetLength() const { OBJECT_TYPE_CHECK(objDict); return dict->getLength(); } -inline void Object::dictAdd(char *key, Object *val) - { OBJECT_TYPE_CHECK(objDict); dict->add(key, val); } +inline void Object::dictAdd(char *key, Object &&val) + { OBJECT_TYPE_CHECK(objDict); dict->add(key, std::move(val)); } -inline void Object::dictSet(const char *key, Object *val) - { OBJECT_TYPE_CHECK(objDict); dict->set(key, val); } +inline void Object::dictSet(const char *key, Object &&val) + { OBJECT_TYPE_CHECK(objDict); dict->set(key, std::move(val)); } inline void Object::dictRemove(const char *key) { OBJECT_TYPE_CHECK(objDict); dict->remove(key); } -inline GBool Object::dictIs(const char *dictType) +inline GBool Object::dictIs(const char *dictType) const { OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); } -inline GBool Object::isDict(const char *dictType) +inline GBool Object::isDict(const char *dictType) const { return type == objDict && dictIs(dictType); } -inline Object *Object::dictLookup(const char *key, Object *obj, int recursion) - { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, obj, recursion); } +inline Object Object::dictLookup(const char *key, int recursion) const + { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, recursion); } -inline Object *Object::dictLookupNF(const char *key, Object *obj) - { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key, obj); } +inline Object Object::dictLookupNF(const char *key) const + { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key); } -inline char *Object::dictGetKey(int i) +inline char *Object::dictGetKey(int i) const { OBJECT_TYPE_CHECK(objDict); return dict->getKey(i); } -inline Object *Object::dictGetVal(int i, Object *obj) - { OBJECT_TYPE_CHECK(objDict); return dict->getVal(i, obj); } +inline Object Object::dictGetVal(int i) const + { OBJECT_TYPE_CHECK(objDict); return dict->getVal(i); } -inline Object *Object::dictGetValNF(int i, Object *obj) - { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i, obj); } +inline Object Object::dictGetValNF(int i) const + { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i); } //------------------------------------------------------------------------ // Stream accessors. @@ -352,10 +380,10 @@ inline Object *Object::dictGetValNF(int i, Object *obj) #include "Stream.h" -inline GBool Object::streamIs(const char *dictType) +inline GBool Object::streamIs(char *dictType) const { OBJECT_TYPE_CHECK(objStream); return stream->getDict()->is(dictType); } -inline GBool Object::isStream(const char *dictType) +inline GBool Object::isStream(char *dictType) const { return type == objStream && streamIs(dictType); } inline void Object::streamReset() @@ -364,25 +392,25 @@ inline void Object::streamReset() inline void Object::streamClose() { OBJECT_TYPE_CHECK(objStream); stream->close(); } -inline int Object::streamGetChar() +inline int Object::streamGetChar() const { OBJECT_TYPE_CHECK(objStream); return stream->getChar(); } -inline int Object::streamGetChars(int nChars, Guchar *buffer) +inline int Object::streamGetChars(int nChars, Guchar *buffer) const { OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); } -inline int Object::streamLookChar() +inline int Object::streamLookChar() const { OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); } -inline char *Object::streamGetLine(char *buf, int size) +inline char *Object::streamGetLine(char *buf, int size) const { OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); } -inline Goffset Object::streamGetPos() +inline Goffset Object::streamGetPos() const { OBJECT_TYPE_CHECK(objStream); return stream->getPos(); } inline void Object::streamSetPos(Goffset pos, int dir) { OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); } -inline Dict *Object::streamGetDict() +inline Dict *Object::streamGetDict() const { OBJECT_TYPE_CHECK(objStream); return stream->getDict(); } #endif |