1//========================================================================
2//
3// Dict.h
4//
5// Copyright 1996-2003 Glyph & Cog, LLC
6//
7//========================================================================
8
9//========================================================================
10//
11// Modified under the Poppler project - http://poppler.freedesktop.org
12//
13// All changes made under the Poppler project to this file are licensed
14// under GPL version 2 or later
15//
16// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
17// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
18// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
19// Copyright (C) 2010, 2017-2022 Albert Astals Cid <aacid@kde.org>
20// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
21// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
22// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
23// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
24//
25// To see a description of the changes please see the Changelog file that
26// came with your tarball or type make ChangeLog if you are building from git
27//
28//========================================================================
29
30#ifndef DICT_H
31#define DICT_H
32
33#include <atomic>
34#include <mutex>
35#include <string>
36#include <vector>
37#include <utility>
38
39#include "poppler-config.h"
40#include "poppler_private_export.h"
41#include "Object.h"
42
43//------------------------------------------------------------------------
44// Dict
45//------------------------------------------------------------------------
46
47class POPPLER_PRIVATE_EXPORT Dict
48{
49public:
50 // Constructor.
51 explicit Dict(XRef *xrefA);
52 explicit Dict(const Dict *dictA);
53 Dict *copy(XRef *xrefA) const;
54
55 Dict *deepCopy() const;
56
57 Dict(const Dict &) = delete;
58 Dict &operator=(const Dict &) = delete;
59
60 // Get number of entries.
61 int getLength() const { return static_cast<int>(entries.size()); }
62
63 // Add an entry. (Copies key into Dict.)
64 // val becomes a dead object after the call
65 void add(const char *key, Object &&val);
66
67 // Add an entry. (Takes ownership of key.)
68 void add(char *key, Object &&val) = delete;
69
70 // Update the value of an existing entry, otherwise create it
71 // val becomes a dead object after the call
72 void set(const char *key, Object &&val);
73 // Remove an entry. This invalidate indexes
74 void remove(const char *key);
75
76 // Check if dictionary is of specified type.
77 bool is(const char *type) const;
78
79 // Look up an entry and return the value. Returns a null object
80 // if <key> is not in the dictionary.
81 Object lookup(const char *key, int recursion = 0) const;
82 // Same as above but if the returned object is a fetched Ref returns such Ref in returnRef, otherwise returnRef is Ref::INVALID()
83 Object lookup(const char *key, Ref *returnRef, int recursion = 0) const;
84 // Look up an entry and return the value. Returns a null object
85 // if <key> is not in the dictionary or if it is a ref to a non encrypted object in a partially encrypted document
86 Object lookupEnsureEncryptedIfNeeded(const char *key) const;
87 const Object &lookupNF(const char *key) const;
88 bool lookupInt(const char *key, const char *alt_key, int *value) const;
89
90 // Iterative accessors.
91 const char *getKey(int i) const { return entries[i].first.c_str(); }
92 Object getVal(int i) const { return entries[i].second.fetch(xref); }
93 // Same as above but if the returned object is a fetched Ref returns such Ref in returnRef, otherwise returnRef is Ref::INVALID()
94 Object getVal(int i, Ref *returnRef) const;
95 const Object &getValNF(int i) const { return entries[i].second; }
96
97 // Set the xref pointer. This is only used in one special case: the
98 // trailer dictionary, which is read before the xref table is
99 // parsed.
100 void setXRef(XRef *xrefA) { xref = xrefA; }
101
102 XRef *getXRef() const { return xref; }
103
104 bool hasKey(const char *key) const;
105
106 // Returns a key name that is not in the dictionary
107 // It will be suggestedKey itself if available
108 // otherwise it will start adding 0, 1, 2, 3, etc. to suggestedKey until there's one available
109 std::string findAvailableKey(const std::string &suggestedKey);
110
111private:
112 friend class Object; // for incRef/decRef
113
114 // Reference counting.
115 int incRef() { return ++ref; }
116 int decRef() { return --ref; }
117
118 using DictEntry = std::pair<std::string, Object>;
119 struct CmpDictEntry;
120
121 XRef *xref; // the xref table for this PDF file
122 std::vector<DictEntry> entries;
123 std::atomic_int ref; // reference count
124 std::atomic_bool sorted;
125 mutable std::recursive_mutex mutex;
126
127 const DictEntry *find(const char *key) const;
128 DictEntry *find(const char *key);
129};
130
131#endif
132

source code of poppler/poppler/Dict.h