Skip to content

file_io: Zip file support #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 10, 2019
Merged

Conversation

dholm
Copy link
Contributor

@dholm dholm commented Jan 9, 2019

Support for loading files stored inside a zip file.

Treats zipped files as folders and allows loading files from inside the
zip file. Archived folder structures are browsable just as if they were
decompressed.

Compressed files are loaded on-demand from the archive.

Nested zip-files are currently not supported.

dholm added 3 commits January 9, 2019 20:58
Include miniz 2.0.8 for zip file support.
Replace file descriptor with a file stream in preparation for supporting
zipped files.

The API to miniz requires the use of file streams and since a file
descriptor can easily be extracted from a stream using `fileno` it's
much more convenient to use file streams everywhere.
Support for loading files stored inside a zip file.

Treats zipped files as folders and allows loading files from inside the
zip file.  Files are loaded on-demand from the archive.

Nested zip-files are currently not supported.
@dholm
Copy link
Contributor Author

dholm commented Jan 9, 2019

I've tried to address all the issues now.

I have tested it with the NES core as well as Minimig. I would like to test it with some really large image, like a harddrive image for ao486, but I don't have one set up at the moment.

@sorgelig
Copy link
Member

Hard drive images are supposed to be writable, so forget about such usage.
Zip is only for read-only files. Some cores use read-only flag, so you can hardcode this flag for files from zip.

@sorgelig sorgelig merged commit 664045f into MiSTer-devel:master Jan 10, 2019
@sorgelig
Copy link
Member

By quick look at diff file i've noticed you've removed some earlier returns on error in sharpmz. Hope you didn't brake that code.

@sorgelig
Copy link
Member

oh, you again put these std:: types. I really hate them. code is harder to read. And additionally VS code highlight feature doesn't like std types. It seems the tool agrees with me - std:: is evil :)

@sorgelig
Copy link
Member

btw, something wrong with file lister. It doesn't let me enter any folder.


## Usage

Please use the files from the [releases page](https://github.com/richgel999/miniz/releases) in your projects. Do not use the git checkout directly! The different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) into one `miniz.c`/`miniz.h` pair in a build step (`amalgamate.sh`). Include `miniz.c` and `miniz.h` in your project to use Miniz.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you are going against this recommendation?
You could just put two files miniz.c and miniz.h to MiSTer sources, not include the whole source tree of unneeded files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I did download the file from the relese, the contents should be the same as you will find in this tarball:

Copy link

@smokku smokku Jan 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just an archived bundle of source tag.
The actual release is here: https://github.com/richgel999/miniz/releases/download/2.0.8/miniz-2.0.8.zip

@dholm
Copy link
Contributor Author

dholm commented Jan 10, 2019

@sorgelig Hmm, you are of course right about the hard drive images and I already deny opening files anything other than read-only so it should work as expected.

Regarding the change to sharpmz, it comes from the commit that changes from file descriptors til file streams. Since I changed how fileTYPE interacts with miniz I don't think it is needed any longer. If you want me to I can submit a revert of that change. It should still work but I haven't tested sharpmz specifically.

Sorry regarding std::. I thought you were against using them only in C-types like uint32_t and size_t. If you throw in a using namespace std; you can remove all of them.

Is MiSTer printing any helpful error messages when you try to enter folders? I tested both browsing normal folders as well as browsing zipped folders extensively before I pushed this change so I'm not sure what I could have missed. If you can't see anything I will run some more tests after work and perhaps throw in some more debug printouts.

@sorgelig
Copy link
Member

Since i was busy by some cores, i didn't trace the problem and simply rolled back to a working version.
If it works for you then i will debug the problem on my side.

@sorgelig
Copy link
Member

It's not like i totally against std. Dynamic arrays are useful feature and hard to replace without similar solution. But std::min is just a one line define. String usage also barely necessary. I see only one not obvious place to rework is splitting the path to zip file and file itself. Other string usages have equivalents in libc

@sorgelig
Copy link
Member

problem was here:

	return (stat64(path, &st) < 0) ? 0 : st.st_mode;

which must be

 	return (stat64(full_path, &st) < 0) ? 0 : st.st_mode;

@sorgelig
Copy link
Member

btw, i know what will be next request from users: support for 7z ))))

@dholm
Copy link
Contributor Author

dholm commented Jan 10, 2019

@sorgelig Regarding the strings I know. I considered doing it with C strings but out of laziness I used std::string, also because I would have had to add two length arguments as well. My thinking was that if you complain about it I can easily fix it and if not I won't have to obsess about those pesky length arguments I would have to add to the string functions. ;)
If you want it fixed let me know and I will do it.

Thanks for tracking down the problem! I was a bit confused about why the code sometimes uses "full_path" and why it sometimes only uses the partial one and I didn't fully understand when to use one or the other so I tried looking at the surrounding code to see which one was used.

Regarding 7z support I already figured that out as well so I already looked at it a little. The best thing would have been if there was a library that supported both formats but I couldn't find any such thing. In fact, only the LZMA SDK appears to provide 7z support in library form. The SDK is quite big, even if you only take the C parts and I also found it somewhat lacking in terms of documentation. MiSTer is very nice and small in size so I put the 7z work on hold until someone convinces you that it must be supported. :)

@sorgelig
Copy link
Member

sorgelig commented Jan 10, 2019

It's tempting to use std::string instead of char as it's easier to write a = b + c instead of strcpy/strcat/sprintf :)
But it's easy to make a mistake and get memory leak or corruption.
I will see if it will be good to use char*
zip path can be split in-place by replacing '/' to 0.
I will evaluate it myself and by the way I will be more familiar with your addition.

i've also noticed that OSD doesn't remember last selected ROM and always open list at the first entry.

Strange that 7z has no lightweight library. Anyway, zip-only is enough for time being.

@smokku
Copy link

smokku commented Jan 10, 2019

Other option of minimizing errors is using C-native string handling library.
I can recommend https://github.com/antirez/sds (which is also a single .h + single .c file library)

@sorgelig
Copy link
Member

i've made conversion to char. It wasn't hard. some places are even more compact now

@sorgelig
Copy link
Member

With stream file i/o functions it's unclear how to operate with *.sav files.
Originally if sav file is absent then it will be created upon first save and will grow up to the last write. It seems doesn't work with stream functions.

@sorgelig
Copy link
Member

sorgelig commented Jan 10, 2019

It seems problem is much more serious that i've thought. O_SYNC option is not applied to files opened for writing! This is not acceptable behavior - all writing should be done immediately with update in catalog without holding any buffers.
Update: It seems fflush() does the sync

theypsilon pushed a commit to MiSTer-DB9/Main_MiSTer that referenced this pull request Feb 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants