OSDN Git Service

binding with libharu.
[putex/putex.git] / src / texsourc / lib / libhpdf / src / hpdf_namedict.c
1 /*
2  * << Haru Free PDF Library >> -- hpdf_namedict.c
3  *
4  * URL: http://libharu.org
5  *
6  * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7  * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8  *
9  * Permission to use, copy, modify, distribute and sell this software
10  * and its documentation for any purpose is hereby granted without fee,
11  * provided that the above copyright notice appear in all copies and
12  * that both that copyright notice and this permission notice appear
13  * in supporting documentation.
14  * It is provided "as is" without express or implied warranty.
15  *
16  */
17
18 #include "hpdf_conf.h"
19 #include "hpdf_utils.h"
20 #include "hpdf_consts.h"
21 #include "hpdf_namedict.h"
22
23 #ifndef HPDF_UNUSED
24 #define HPDF_UNUSED(a) ((void)(a))
25 #endif
26
27 static const char * const HPDF_NAMEDICT_KEYS[] = {
28                                         "EmbeddedFiles"
29                                         };
30
31 HPDF_NameDict
32 HPDF_NameDict_New  (HPDF_MMgr  mmgr,
33                     HPDF_Xref  xref)
34 {
35     HPDF_NameDict ndict;
36
37     HPDF_PTRACE((" HPDF_NameDict_New\n"));
38
39     ndict = HPDF_Dict_New (mmgr);
40     if (!ndict)
41         return NULL;
42
43     if (HPDF_Xref_Add (xref, ndict) != HPDF_OK)
44         return NULL;
45
46     ndict->header.obj_class |= HPDF_OSUBCLASS_NAMEDICT;
47
48     return ndict;
49 }
50
51 HPDF_NameTree
52 HPDF_NameDict_GetNameTree  (HPDF_NameDict     namedict,
53                             HPDF_NameDictKey  key)
54 {
55     if (!namedict)
56         return NULL;
57     return HPDF_Dict_GetItem (namedict, HPDF_NAMEDICT_KEYS[key], HPDF_OCLASS_DICT);
58 }
59
60 HPDF_STATUS
61 HPDF_NameDict_SetNameTree  (HPDF_NameDict     namedict,
62                             HPDF_NameDictKey  key,
63                             HPDF_NameTree     ntree)
64 {
65     return HPDF_Dict_Add (namedict, HPDF_NAMEDICT_KEYS[key], ntree);
66 }
67
68 HPDF_BOOL
69 HPDF_NameDict_Validate  (HPDF_NameDict  namedict)
70 {
71     if (!namedict)
72         return HPDF_FALSE;
73
74     if (namedict->header.obj_class != (HPDF_OSUBCLASS_NAMEDICT |
75                 HPDF_OCLASS_DICT)) {
76         HPDF_SetError (namedict->error, HPDF_INVALID_OBJECT, 0);
77         return HPDF_FALSE;
78     }
79
80     return HPDF_TRUE;
81 }
82
83
84 /*------- NameTree -------*/
85
86 HPDF_NameTree
87 HPDF_NameTree_New  (HPDF_MMgr  mmgr,
88                     HPDF_Xref  xref)
89 {
90     HPDF_STATUS ret = HPDF_OK;
91     HPDF_NameTree ntree;
92     HPDF_Array items;
93
94     HPDF_PTRACE((" HPDF_NameTree_New\n"));
95
96     ntree = HPDF_Dict_New (mmgr);
97     if (!ntree)
98         return NULL;
99
100     if (HPDF_Xref_Add (xref, ntree) != HPDF_OK)
101         return NULL;
102
103     ntree->header.obj_class |= HPDF_OSUBCLASS_NAMETREE;
104
105     items = HPDF_Array_New (mmgr);
106     if (!ntree)
107         return NULL;
108
109     ret += HPDF_Dict_Add (ntree, "Names", items);
110     if (ret != HPDF_OK)
111         return NULL;
112
113     return ntree;
114 }
115
116 HPDF_STATUS
117 HPDF_NameTree_Add  (HPDF_NameTree  tree,
118                     HPDF_String    name,
119                     void          *obj)
120 {
121     HPDF_Array items;
122     HPDF_INT32 i, icount;
123
124     if (!tree || !name)
125         return HPDF_INVALID_PARAMETER;
126
127     items = HPDF_Dict_GetItem (tree, "Names", HPDF_OCLASS_ARRAY);
128     if (!items)
129         return HPDF_INVALID_OBJECT;
130
131     /* "The keys shall be sorted in lexical order" -- 7.9.6, Name Trees.
132      * Since we store keys sorted, it's best to do a linear insertion sort
133      * Find the first element larger than 'key', and insert 'key' and then
134      * 'obj' into the items. */
135
136     icount = HPDF_Array_Items(items);
137
138     /* If we're larger than the last element, append */
139     if (icount) {
140         HPDF_String last = HPDF_Array_GetItem(items, icount - 2, HPDF_OCLASS_STRING);
141
142         if (HPDF_String_Cmp(name, last) > 0) {
143             HPDF_Array_Add(items, name);
144             HPDF_Array_Add(items, obj);
145             return HPDF_OK;
146         }
147     }
148
149     /* Walk backwards through the list until we're smaller than an element=
150      * That's the element to insert in front of. */
151     for (i = icount - 4; i >= 0; i -= 2) {
152         HPDF_String elem = HPDF_Array_GetItem(items, i, HPDF_OCLASS_STRING);
153
154         if (i == 0 || HPDF_String_Cmp(name, elem) < 0) {
155             HPDF_Array_Insert(items, elem, name);
156             HPDF_Array_Insert(items, elem, obj);
157             return HPDF_OK;
158         }
159     }
160
161     /* Items list is empty */
162     HPDF_Array_Add(items, name);
163     HPDF_Array_Add(items, obj);
164     return HPDF_OK;
165 }
166
167 HPDF_BOOL
168 HPDF_NameTree_Validate  (HPDF_NameTree  nametree)
169 {
170     if (!nametree)
171         return HPDF_FALSE;
172
173     if (nametree->header.obj_class != (HPDF_OSUBCLASS_NAMETREE |
174                 HPDF_OCLASS_DICT)) {
175         HPDF_SetError (nametree->error, HPDF_INVALID_OBJECT, 0);
176         return HPDF_FALSE;
177     }
178
179     return HPDF_TRUE;
180 }
181
182
183 /*------- EmbeddedFile -------*/
184
185 HPDF_EmbeddedFile
186 HPDF_EmbeddedFile_New  (HPDF_MMgr  mmgr,
187                         HPDF_Xref  xref,
188                         const char *file)
189 {
190     HPDF_STATUS ret = HPDF_OK;
191     HPDF_Dict ef;               /* the dictionary for the embedded file: /Type /EF */
192     HPDF_String name;           /* the name of the file: /F (name) */
193     HPDF_Dict eff;              /* ef has an /EF <<blah>> key - this is it */
194     HPDF_Dict filestream;       /* the stream that /EF <</F _ _ R>> refers to */
195     HPDF_Stream stream;
196
197     ef = HPDF_Dict_New (mmgr);
198     if (!ef)
199         return NULL;
200     if (HPDF_Xref_Add (xref, ef) != HPDF_OK)
201         return NULL;
202
203     filestream = HPDF_DictStream_New (mmgr, xref);
204     if (!filestream)
205         return NULL;
206     stream = HPDF_FileReader_New (mmgr, file);
207     if (!stream)
208         return NULL;
209     HPDF_Stream_Free(filestream->stream);
210     filestream->stream = stream;
211     filestream->filter = HPDF_STREAM_FILTER_FLATE_DECODE;
212
213     eff = HPDF_Dict_New (mmgr);
214     if (!eff)
215         return NULL;
216
217     name = HPDF_String_New (mmgr, file, NULL);
218     if (!name)
219         return NULL;
220
221     ret += HPDF_Dict_AddName (ef, "Type", "F");
222     ret += HPDF_Dict_Add (ef, "F", name);
223     ret += HPDF_Dict_Add (ef, "EF", eff);
224     ret += HPDF_Dict_Add (eff, "F", filestream);
225
226     if (ret != HPDF_OK)
227         return NULL;
228
229     return ef;
230 }
231
232 HPDF_BOOL
233 HPDF_EmbeddedFile_Validate  (HPDF_EmbeddedFile  emfile)
234 {
235     HPDF_UNUSED (emfile);
236     return HPDF_TRUE;
237 }