@@ -51,21 +51,89 @@ class ASiC_E::Private
5151/* *
5252 * Initialize BDOC container.
5353 */
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)
5656 , d(make_unique<Private>())
5757{
58- }
58+ if (create)
59+ return ;
60+ auto z = load (true , {MIMETYPE_ASIC_E, MIMETYPE_ADOC});
5961
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+ }
69137}
70138
71139ASiC_E::~ASiC_E ()
@@ -110,9 +178,7 @@ void ASiC_E::save(const ZipSerialize &s)
110178unique_ptr<Container> ASiC_E::createInternal (const string &path)
111179{
112180 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 ));
116182}
117183
118184/* *
@@ -146,7 +212,7 @@ void ASiC_E::canSave()
146212unique_ptr<Container> ASiC_E::openInternal (const string &path)
147213{
148214 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 ));
150216}
151217
152218void ASiC_E::loadSignatures (istream &data, const string &file)
@@ -157,94 +223,6 @@ void ASiC_E::loadSignatures(istream &data, const string &file)
157223 addSignature (make_unique<SignatureXAdES_LTA>(signatures, s, this ));
158224}
159225
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-
248226Signature* ASiC_E::prepareSignature (Signer *signer)
249227{
250228 if (mediaType () != MIMETYPE_ASIC_E)
0 commit comments