@@ -257,6 +257,85 @@ public void CheckForUnknownCompressionMethods ()
257257 }
258258 }
259259
260+ [ Test ]
261+ public void SimulateXamarinAndroidUsage ( [ Values ( true , false ) ] bool copyArchive , [ Values ( true , false ) ] bool useFiles )
262+ {
263+ string filePath = Path . GetFullPath ( "packaged_resources" ) ;
264+ if ( ! File . Exists ( filePath ) ) {
265+ filePath = Path . GetFullPath ( Path . Combine ( "LibZipSharp.UnitTest" , "packaged_resources" ) ) ;
266+ }
267+
268+ string baseArchive = $ "base_{ copyArchive } _{ useFiles } .zip";
269+
270+ if ( File . Exists ( baseArchive ) )
271+ File . Delete ( baseArchive ) ;
272+
273+ var mode = FileMode . Create ;
274+ if ( copyArchive ) {
275+ File . Copy ( filePath , baseArchive ) ;
276+ mode = FileMode . Open ;
277+ }
278+
279+ List < ( string name , CompressionMethod c , ulong size ) > expectedFiles = new List < ( string name , CompressionMethod c , ulong size ) > ( ) ;
280+ // use a specific seed so we always generate the same files
281+ Random rnd = new Random ( 3456464 ) ;
282+
283+ using ( var baseZip = new ZipWrapper ( baseArchive , mode ) ) {
284+ using ( var zip = ZipArchive . Open ( filePath , FileMode . Open ) ) {
285+ foreach ( var entry in zip ) {
286+ var entryName = entry . FullName ;
287+ if ( entryName . Contains ( "\\ " ) ) {
288+ entryName = entryName . Replace ( '\\ ' , '/' ) ;
289+ }
290+ expectedFiles . Add ( ( entryName , entry . CompressionMethod , entry . Size ) ) ;
291+ if ( copyArchive )
292+ continue ;
293+ var ms = new MemoryStream ( ) ;
294+ entry . Extract ( ms ) ;
295+ TestContext . Out . WriteLine ( $ "Adding { entryName } to base.zip") ;
296+ baseZip . Archive . AddStream ( ms , entryName , compressionMethod : entry . CompressionMethod ) ;
297+ }
298+ }
299+
300+ baseZip . FixupWindowsPathSeparators ( ( a , b ) => TestContext . Out . WriteLine ( $ "Fixing up malformed entry `{ a } ` -> `{ b } `") ) ;
301+
302+ for ( int i = 0 ; i < 200 ; i ++ ) {
303+ uint fileSize = ( uint ) rnd . Next ( 341 , 3535592 ) ;
304+ byte [ ] buffer = new byte [ fileSize ] ;
305+ rnd . NextBytes ( buffer ) ;
306+ CompressionMethod compression = rnd . NextDouble ( ) < 0.8 ? CompressionMethod . Deflate : CompressionMethod . Store ;
307+ string entryName = $ "temp/file_{ i } _size_{ fileSize } _{ compression } .bin";
308+ string archivePath = rnd . NextDouble ( ) < 0.3 ? entryName : Path . GetFileName ( entryName ) ;
309+ TestContext . Out . WriteLine ( $ "Adding { entryName } to base.zip") ;
310+ if ( useFiles ) {
311+ Directory . CreateDirectory ( "temp" ) ;
312+ File . WriteAllBytes ( entryName , buffer ) ;
313+ baseZip . Archive . AddFile ( entryName , archivePath , compressionMethod : compression ) ;
314+ } else {
315+ var ms = new MemoryStream ( buffer ) ;
316+ ms . Position = 0 ;
317+ baseZip . Archive . AddStream ( ms , archivePath , compressionMethod : compression ) ;
318+ }
319+ expectedFiles . Add ( ( archivePath , compression , fileSize ) ) ;
320+
321+ if ( rnd . NextDouble ( ) < 0.2 )
322+ baseZip . Flush ( ) ;
323+ }
324+
325+ }
326+ using ( var zip = ZipArchive . Open ( baseArchive , FileMode . Open , strictConsistencyChecks : true ) ) {
327+ foreach ( var file in expectedFiles ) {
328+ Assert . IsTrue ( zip . ContainsEntry ( file . name ) , $ "zip should contain { file } .") ;
329+ var e = zip . ReadEntry ( file . name ) ;
330+ Assert . AreEqual ( file . size , e . Size , $ "{ file } should be { file . size } but was { e . Size } .") ;
331+ Assert . AreEqual ( file . c , e . CompressionMethod , $ "{ file } should be { file . c } but was { e . CompressionMethod } .") ;
332+ }
333+ }
334+
335+ if ( File . Exists ( baseArchive ) )
336+ File . Delete ( baseArchive ) ;
337+ }
338+
260339 [ Test ]
261340 public void InMemoryZipFile ( )
262341 {
0 commit comments