@@ -51,21 +51,89 @@ class ASiC_E::Private
51
51
/* *
52
52
* Initialize BDOC container.
53
53
*/
54
- ASiC_E::ASiC_E ()
55
- : ASiContainer(MIMETYPE_ASIC_E)
54
+ ASiC_E::ASiC_E (const string &path, bool create )
55
+ : ASiContainer(path, MIMETYPE_ASIC_E)
56
56
, d(make_unique<Private>())
57
57
{
58
- }
58
+ if (create)
59
+ return ;
60
+ auto z = load (true , {MIMETYPE_ASIC_E, MIMETYPE_ADOC});
59
61
60
- /* *
61
- * Opens ASiC container from a file
62
- */
63
- ASiC_E::ASiC_E (const string &path)
64
- : ASiContainer(MIMETYPE_ASIC_E)
65
- , d(make_unique<Private>())
66
- {
67
- auto zip = load (path, true , {MIMETYPE_ASIC_E, MIMETYPE_ADOC});
68
- parseManifestAndLoadFiles (zip);
62
+ try
63
+ {
64
+ auto manifestdata = z.extract <stringstream>(" META-INF/manifest.xml" );
65
+ auto doc = XMLDocument::openStream (manifestdata, {" manifest" , MANIFEST_NS});
66
+ doc.validateSchema (File::path (Conf::instance ()->xsdPath (), " OpenDocument_manifest_v1_2.xsd" ));
67
+
68
+ set<string_view> manifestFiles;
69
+ bool mimeFound = false ;
70
+ for (auto file = doc/" file-entry" ; file; file++)
71
+ {
72
+ auto full_path = file[{" full-path" , MANIFEST_NS}];
73
+ auto media_type = file[{" media-type" , MANIFEST_NS}];
74
+ DEBUG (" full_path = '%s', media_type = '%s'" , full_path.data (), media_type.data ());
75
+
76
+ if (manifestFiles.find (full_path) != manifestFiles.end ())
77
+ THROW (" Manifest multiple entries defined for file '%s'." , full_path.data ());
78
+
79
+ // ODF does not specify that mimetype should be first in manifest
80
+ if (full_path == " /" )
81
+ {
82
+ if (mediaType () != media_type)
83
+ THROW (" Manifest has incorrect container media type defined '%s', expecting '%s'." , media_type.data (), mediaType ().c_str ());
84
+ mimeFound = true ;
85
+ continue ;
86
+ }
87
+ if (full_path.back () == ' /' ) // Skip Directory entries
88
+ continue ;
89
+
90
+ manifestFiles.insert (full_path);
91
+ if (mediaType () == MIMETYPE_ADOC &&
92
+ (full_path.compare (0 , 9 , " META-INF/" ) == 0 ||
93
+ full_path.compare (0 , 9 , " metadata/" ) == 0 ))
94
+ d->metadata .push_back (new DataFilePrivate (dataStream (full_path, z), string (full_path), string (media_type)));
95
+ else
96
+ addDataFilePrivate (dataStream (full_path, z), string (full_path), string (media_type));
97
+ }
98
+ if (!mimeFound)
99
+ THROW (" Manifest is missing mediatype file entry." );
100
+
101
+ for (const string &file: z.list ())
102
+ {
103
+ /* *
104
+ * http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.03.01_60/ts_102918v010301p.pdf
105
+ * 6.2.2 Contents of Container
106
+ * 3) The root element of each "*signatures*.xml" content shall be either:
107
+ */
108
+ if (file.compare (0 , 9 , " META-INF/" ) == 0 &&
109
+ file.find (" signatures" ) != string::npos)
110
+ {
111
+ try
112
+ {
113
+ auto data = z.extract <stringstream>(file);
114
+ loadSignatures (data, file);
115
+ }
116
+ catch (const Exception &e)
117
+ {
118
+ THROW_CAUSE (e, " Failed to parse signature '%s'." , file.c_str ());
119
+ }
120
+ continue ;
121
+ }
122
+
123
+ if (file == " mimetype" || file.compare (0 , 8 ," META-INF" ) == 0 )
124
+ continue ;
125
+ if (manifestFiles.count (file) == 0 )
126
+ THROW (" File '%s' found in container is not described in manifest." , file.c_str ());
127
+ }
128
+ }
129
+ catch (const Exception &e)
130
+ {
131
+ THROW_CAUSE (e, " Failed to parse manifest" );
132
+ }
133
+ catch (...)
134
+ {
135
+ THROW (" Failed to parse manifest XML: Unknown exception" );
136
+ }
69
137
}
70
138
71
139
ASiC_E::~ASiC_E ()
@@ -110,9 +178,7 @@ void ASiC_E::save(const ZipSerialize &s)
110
178
unique_ptr<Container> ASiC_E::createInternal (const string &path)
111
179
{
112
180
DEBUG (" ASiC_E::createInternal(%s)" , path.c_str ());
113
- unique_ptr<ASiC_E> doc = unique_ptr<ASiC_E>(new ASiC_E);
114
- doc->zpath (path);
115
- return doc;
181
+ return unique_ptr<Container>(new ASiC_E (path, true ));
116
182
}
117
183
118
184
/* *
@@ -146,7 +212,7 @@ void ASiC_E::canSave()
146
212
unique_ptr<Container> ASiC_E::openInternal (const string &path)
147
213
{
148
214
DEBUG (" ASiC_E::openInternal(%s)" , path.c_str ());
149
- return unique_ptr<Container>(new ASiC_E (path));
215
+ return unique_ptr<Container>(new ASiC_E (path, false ));
150
216
}
151
217
152
218
void ASiC_E::loadSignatures (istream &data, const string &file)
@@ -157,94 +223,6 @@ void ASiC_E::loadSignatures(istream &data, const string &file)
157
223
addSignature (make_unique<SignatureXAdES_LTA>(signatures, s, this ));
158
224
}
159
225
160
- /* *
161
- * Parses manifest file and checks that files described in manifest exist, also
162
- * checks that no extra file do exist that are not described in manifest.xml.
163
- *
164
- * @param path directory on disk of the BDOC container.
165
- * @throws Exception exception is thrown if the manifest.xml file parsing failed.
166
- */
167
- void ASiC_E::parseManifestAndLoadFiles (const ZipSerialize &z)
168
- {
169
- DEBUG (" ASiC_E::readManifest()" );
170
-
171
- try
172
- {
173
- auto manifestdata = z.extract <stringstream>(" META-INF/manifest.xml" );
174
- auto doc = XMLDocument::openStream (manifestdata, {" manifest" , MANIFEST_NS});
175
- doc.validateSchema (File::path (Conf::instance ()->xsdPath (), " OpenDocument_manifest_v1_2.xsd" ));
176
-
177
- set<string_view> manifestFiles;
178
- bool mimeFound = false ;
179
- for (auto file = doc/" file-entry" ; file; file++)
180
- {
181
- auto full_path = file[{" full-path" , MANIFEST_NS}];
182
- auto media_type = file[{" media-type" , MANIFEST_NS}];
183
- DEBUG (" full_path = '%s', media_type = '%s'" , full_path.data (), media_type.data ());
184
-
185
- if (manifestFiles.find (full_path) != manifestFiles.end ())
186
- THROW (" Manifest multiple entries defined for file '%s'." , full_path.data ());
187
-
188
- // ODF does not specify that mimetype should be first in manifest
189
- if (full_path == " /" )
190
- {
191
- if (mediaType () != media_type)
192
- THROW (" Manifest has incorrect container media type defined '%s', expecting '%s'." , media_type.data (), mediaType ().c_str ());
193
- mimeFound = true ;
194
- continue ;
195
- }
196
- if (full_path.back () == ' /' ) // Skip Directory entries
197
- continue ;
198
-
199
- manifestFiles.insert (full_path);
200
- if (mediaType () == MIMETYPE_ADOC &&
201
- (full_path.compare (0 , 9 , " META-INF/" ) == 0 ||
202
- full_path.compare (0 , 9 , " metadata/" ) == 0 ))
203
- d->metadata .push_back (new DataFilePrivate (dataStream (full_path, z), string (full_path), string (media_type)));
204
- else
205
- addDataFilePrivate (dataStream (full_path, z), string (full_path), string (media_type));
206
- }
207
- if (!mimeFound)
208
- THROW (" Manifest is missing mediatype file entry." );
209
-
210
- for (const string &file: z.list ())
211
- {
212
- /* *
213
- * http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.03.01_60/ts_102918v010301p.pdf
214
- * 6.2.2 Contents of Container
215
- * 3) The root element of each "*signatures*.xml" content shall be either:
216
- */
217
- if (file.compare (0 , 9 , " META-INF/" ) == 0 &&
218
- file.find (" signatures" ) != string::npos)
219
- {
220
- try
221
- {
222
- auto data = z.extract <stringstream>(file);
223
- loadSignatures (data, file);
224
- }
225
- catch (const Exception &e)
226
- {
227
- THROW_CAUSE (e, " Failed to parse signature '%s'." , file.c_str ());
228
- }
229
- continue ;
230
- }
231
-
232
- if (file == " mimetype" || file.compare (0 , 8 ," META-INF" ) == 0 )
233
- continue ;
234
- if (manifestFiles.count (file) == 0 )
235
- THROW (" File '%s' found in container is not described in manifest." , file.c_str ());
236
- }
237
- }
238
- catch (const Exception &e)
239
- {
240
- THROW_CAUSE (e, " Failed to parse manifest" );
241
- }
242
- catch (...)
243
- {
244
- THROW (" Failed to parse manifest XML: Unknown exception" );
245
- }
246
- }
247
-
248
226
Signature* ASiC_E::prepareSignature (Signer *signer)
249
227
{
250
228
if (mediaType () != MIMETYPE_ASIC_E)
0 commit comments