@@ -46,6 +46,7 @@ class ASiContainer::Private
4646 vector<DataFile*> documents;
4747 vector<Signature*> signatures;
4848 map<string, ZipSerialize::Properties> properties;
49+ unique_ptr<ZipSerialize> z;
4950};
5051
5152const string_view ASiContainer::ASICE_EXTENSION = " asice" ;
@@ -76,12 +77,12 @@ ASiContainer::ASiContainer(const string &mimetype)
7677 * @param supported supported mimetypes.
7778 * @return returns zip serializer for the container.
7879 */
79- unique_ptr< ZipSerialize> ASiContainer::load (const string &path, bool mimetypeRequired, const set<string> &supported)
80+ ZipSerialize* ASiContainer::load (const string &path, bool mimetypeRequired, const set<string> &supported)
8081{
8182 DEBUG (" ASiContainer::ASiContainer(path = '%s')" , path.c_str ());
82- auto z = make_unique<ZipSerialize>(d->path = path, false );
83+ d-> z = make_unique<ZipSerialize>(d->path = path, false );
8384
84- vector<string> list = z->list ();
85+ vector<string> list = d-> z ->list ();
8586 if (list.empty ())
8687 THROW (" Failed to parse container" );
8788
@@ -91,16 +92,16 @@ unique_ptr<ZipSerialize> ASiContainer::load(const string &path, bool mimetypeReq
9192 // ETSI TS 102 918: mimetype has to be the first in the archive
9293 if (list.front () == " mimetype" )
9394 {
94- d->mimetype = readMimetype (*z);
95+ d->mimetype = readMimetype (*d-> z );
9596 DEBUG (" mimetype = '%s'" , d->mimetype .c_str ());
9697 if (supported.find (d->mimetype ) == supported.cend ())
9798 THROW (" Incorrect mimetype '%s'" , d->mimetype .c_str ());
9899 }
99100
100101 for (const string &file: list)
101- d->properties [file] = z->properties (file);
102+ d->properties [file] = d-> z ->properties (file);
102103
103- return z ;
104+ return d-> z . get () ;
104105}
105106
106107string ASiContainer::mediaType () const
@@ -138,25 +139,9 @@ vector<Signature *> ASiContainer::signatures() const
138139 return d->signatures ;
139140}
140141
141- /* *
142- * <p>
143- * Read a datafile from container.
144- * </p>
145- * If expected size of the data is too big, then stream is written to temp file.
146- *
147- * @param path name of the file in zip container stream is used to read from.
148- * @param z Zip container.
149- * @return returns data as a stream.
150- */
151- unique_ptr<iostream> ASiContainer::dataStream (const string &path, const ZipSerialize &z) const
142+ DataFilePrivate* ASiContainer::dataFile (const std::string &path, const std::string &mediaType) const
152143{
153- unique_ptr<iostream> data;
154- if (d->properties [path].size > MAX_MEM_FILE)
155- data = make_unique<fstream>(File::encodeName (File::tempFileName ()), fstream::in|fstream::out|fstream::binary|fstream::trunc);
156- else
157- data = make_unique<stringstream>();
158- z.extract (path, *data);
159- return data;
144+ return new DataFilePrivate (d->z ->stream (path), path, mediaType, d->properties [path].size );
160145}
161146
162147/* *
@@ -191,15 +176,16 @@ void ASiContainer::addDataFile(const string &path, const string &mediaType)
191176 *data << file.rdbuf ();
192177 is = std::move (data);
193178 }
194- addDataFilePrivate ( std::move (is), fileName, mediaType);
179+ d-> documents . push_back ( new DataFilePrivate ( std::move (is), fileName, mediaType, prop. size ) );
195180}
196181
197182void ASiContainer::addDataFile (unique_ptr<istream> is, const string &fileName, const string &mediaType)
198183{
199184 addDataFileChecks (fileName, mediaType);
200185 if (fileName.find_last_of (" /\\ " ) != string::npos)
201186 THROW (" Document file '%s' cannot contain directory path." , fileName.c_str ());
202- addDataFilePrivate (std::move (is), fileName, mediaType);
187+ istream::pos_type pos = is->tellg ();
188+ d->documents .push_back (new DataFilePrivate (std::move (is), fileName, mediaType, pos < 0 ? 0 : (unsigned long )pos));
203189}
204190
205191void ASiContainer::addDataFileChecks (const string &fileName, const string &mediaType)
@@ -214,9 +200,9 @@ void ASiContainer::addDataFileChecks(const string &fileName, const string &media
214200 THROW (" MediaType does not meet format requirements (RFC2045, section 5.1) '%s'." , mediaType.c_str ());
215201}
216202
217- void ASiContainer::addDataFilePrivate (unique_ptr<istream> is, const string &fileName, const string &mediaType)
203+ void ASiContainer::addDataFilePrivate (const string &fileName, const string &mediaType)
218204{
219- d->documents .push_back (new DataFilePrivate ( std::move (is), fileName, mediaType));
205+ d->documents .push_back (dataFile ( fileName, mediaType));
220206}
221207
222208/* *
@@ -298,23 +284,17 @@ void ASiContainer::zproperty(const string &file, ZipSerialize::Properties &&prop
298284string ASiContainer::readMimetype (const ZipSerialize &z)
299285{
300286 DEBUG (" ASiContainer::readMimetype()" );
301- stringstream is;
302- z. extract ( " mimetype " , is) ;
303-
304- array< unsigned char , 3 > bom{};
305- is. read (( char *)bom. data (), bom. size () );
287+ auto is = z. stream ( " mimetype " ) ;
288+ string text ;
289+ *is >> text;
290+ if (!is)
291+ THROW ( " Failed to read mimetype. " );
306292 // Contains UTF-16 BOM
307- if ((bom [0 ] == 0xFF && bom [1 ] == 0xEF ) ||
308- (bom [0 ] == 0xEF && bom [1 ] == 0xFF ))
293+ if ((text [0 ] == 0xFF && text [1 ] == 0xEF ) ||
294+ (text [0 ] == 0xEF && text [1 ] == 0xFF ))
309295 THROW (" Mimetype file must be UTF-8 format." );
310296 // does not contain UTF-8 BOM reset pos
311- if (bom[0 ] != 0xEF || bom[1 ] != 0xBB || bom[2 ] != 0xBF )
312- is.seekg (0 , ios::beg);
313-
314- string text;
315- is >> text;
316- if (is.fail ())
317- THROW (" Failed to read mimetype." );
318-
297+ if (text[0 ] == 0xEF && text[1 ] == 0xBB && text[2 ] != 0xBF )
298+ text.erase (text.cbegin (), text.cbegin () + 3 );
319299 return text;
320300}
0 commit comments