Decompressing a gzip data stream in Objective-C - objective-c

Is there a simple, standard way to decompress a gzip raw data buffer in Objective-C? I could not find anything useful in the Apple Developer documentation.
If not, can you point me to a code walk-through, a library, anything that will make my life easier? I am not afraid to write C code.

There is a NSData category available at cocoadev that can handle zlib and gzip data:
http://www.cocoadev.com/index.pl?NSDataCategory
If you just need gzip decompression, you can remove the zlib & hash related methods.
Don't forget to add a link libz.dylib (OS X standard library) build phase.
Update
As pointed out by marcos1490 in the comments, the original CocoaDev entry disappeared, but someone extended that NSData category and wrote about it: http://deusty.blogspot.de/2007/07/gzip-compressiondecompression.html

You can try Ziparchive for decompression. I've tried compressing files using it, hope the other would work perfectly.
Here is the code snippet
ZipArchive *zip = [ZipArchive alloc];
[zip UnzipOpenFile:Zip-File-Path];
[zip UnzipFileTo:Unzip-Folder-Path overWrite:As-You-Wish];
Also include libz.dylib in build phase.

Related

Patching Mach-o Binary

I'm looking for a way to patch Mach-o Binaries, although I've come up short of possible (and not too tedious) ways of accomplishing this. I'm very familiar with hex editing and patching bytes by hand, although ultimately what I really need is a way to create a drag'n'drop method of doing this via a compiled Xcode Cocoa application.
Any example, or even better, an actual usable Xcode project template to get start would be very helpful.
If I wanted to do this kind of thing, I'd start with HexFiend. Then I'd look up the implementation of dyld and otool in the Darwin source repository and the Mac OS X ABI Mach-O File Format Reference
If you want to programmatically deal with the Mach-O file format to access load commands, segments, sections and more, you should use libMachObjC which is part of the class-dump project. The API is very easy to use.
Have a look at the deprotect tool source code for an example of reading a Mach-O file, patching some bytes and writing the modified file to disk.

Best way to loop through a lot of files and zip each one separately?

I need to loop through a relatively large set of files (> 5000), zipping and uploading each one separately (not as directories or groups of files) to a server in turn.
The biggest part of my problem is to know which is the best way to do the zipping in terms of ease of implementation and performance. I thought there must be a standard Cocoa framework for something that is apparently a very common requirement but there doesn't seem to be any such framework. Other suggestions and approaches I've found so far:
zip.framework at code.google.com, which "is a cocoa framework for easy zip file listing, reading and writing. The main purpose of this framework is to prevent you from having to use command line utilities in your application by providing a native Cocoa interface" - seems a lot of people have found this link (but I didn't notice anyone who had actually used it before!)
ziparchive also at code.google.com - "base on open source code 'MiniZip'".
Suggestions about using NSTask to call command line utilities such as ditto are common, such as in this CocoaDev question but I don't like the idea of having to do it
Similarly, someone here suggested NSTask to call zip and unzip - but this posting says that the "only problem is that when the files are decompressed, the Mac headers have been stripped, so Mac OS dosen't recognize the file!! (i.e. I zip an application and it stripps the "appl" from the file. When I unzip it, it is unusable."
Someone's framework called ZipKit here
Another CocoaDev question discusses several approaches e.g. creating wrapper for C++ archiving code, creating C wrapper for zlib and minizip (minizip is built around zlib), etc
Something about NSDataCategory (didn't understand it)
An open-source manga/comic book reader(!) from www.feedface.com called FFView which has its own separate archiving framework
The zipped files need to be unzipped in Windows.
Please, I hope someone has real-world experience with a solution that meets similar requirements to mine. As you can see, I've already found a lot of links so just another link to another framework/approach without something that actually indicates its applicability to my problem will not really be very helpful.
Thanks!
This is what I'd consider the "proper Cocoa way" to do it. You may not like it, but it works, it requires no external frameworks, and it requires very little code.
Add a shell script to your application bundle, zipmany.sh.
#!/bin/bash
set -e
SRC="$1"
DEST="$2"
cd "$SRC"
for FILE in $(find . -not -name '.*' -a type f)
do
zip -jD "$DEST"/"$FILE".zip "$FILE"
done
And then, in Cocoa,
NSString *script = [[NSBundle mainBundle] pathForResource:#"zipmany" ofType:#"sh"];
NSTask *task = [[NSTask alloc] init];
[task setArguments:[NSArray arrayWithObjects:#"zipmany.sh", srcDir, destDir, nil]];
[task launch];
[task waitUntilExit];
if ([task terminationReason] == ATASK_SUCCESS_VALUE)
succeeded;
else
failed;
You may balk at this kind of stuff, but delegating this kind of task to a separate process is robust and fairly standard.
If the filenames can have spaces, you'll have to change the shell script a little bit; I considered writing the "safe" version but this is more readable. You can also make a progress bar by echoing output from the script to be read by the application.
The call to waitUntilExit will cause your app to freeze or "beach ball" unless you run the entire thing in a separate thread, or know enough about Unix IPC to handle SIGCHLD.
If you are working with Linux I would use a shell script with a few tools (zip, lftp and maybe find). Then you can zip all the files and upload then by just running the script.
I could give you some help with such a solution.
Or is it a requirement that you implement the compression tool in C or C++ using the libraries you mentioned?
Update
Why is Unicode relevant for your problem? Because of file names?
You could solve this problem by writing a wrapper to convert file names to
latin1 encoding, and store a small text file along with the compressed file.
Regarding efficiency, maybe you can do some research and find out what the best algorithm is and then look for a library supporting it. As far as I know, zip compression is based on lz77 or lzw: you might even look it up somewhere and implement it yourself,
it should not very difficult if you want to compress individual files because you only
need to implement the basic algorithm and apply it to a stream of bytes.
See e.g. http://en.pudn.com/downloads33/sourcecode/zip/detail106575_en.html, http://rosettacode.org/wiki/LZW_compression

How to compress a directory with NSData Category?

I've been playing with an app and I wanted to add the ability to compress a directory and it's children. I found the CocoaDev category often mentioned on here but eventually settled on the category put together for Molecules. My problem is less with the compression category and more with converting a directory into a valid NSData object. I want people to be able to deflate the file with any app out there. I have looked into NSFileManager and serializing the directory contents and compressing that, but I suspect this would prohibit the archive from being deflatable.
Where am I going wrong? Would NSData not be sufficient?
sounds like zip -r (more arguments here) may work for you.

Surefire way of determining the codec of a media file

I'm looking for a surefire way of determining the codec used in an audio or video file. The two things I am currently using are the file extension (obvious), and the mime type as determined by running `file -ib' on the file.
This doesn't seem to get me all the way there: loads of formats are `wrapper' formats that hide the exact codec used within -- for example, '.ogg' files can internally use the Vorbis, Speex, or FLAC codecs. Their MIME type is also usually hidden under 'application/ogg' or similar.
The `file' program is apparently able to tell me which codec is used, but it returns this as human-readable prose:
kb.ogg: Ogg data, Vorbis audio, stereo, 44100 Hz, ~0 bps
and as such it is dodgy to use programmatically.
What I'm essentially asking is: is there a script out there (any language) that can wade through these wrapper formats and tell me what the meat of the file is made of?
ffmpeg includes a library called libavformat that can open and demux pretty much any media format. Obviously that's more than you actually need, but I don't think you can find anything else that's quite as complete. I've used it myself with great success. Take a look at this article for an introduction. There's also bindings for these libraries for some common scripting languages, such as python.
(If you don't want to build something using the library, you can probably use the regular ffmpeg binary.)
You can always use your own magic file, copied and modified from the pre-installed magic file, and change the return string so that it can be easily parsed by your program.
See:
http://linux.die.net/man/1/file
http://linux.die.net/man/5/magic

Modifying elf file

I would like to add a new flag to an elf file. This flag should then be available
to the kernel in the process descriptor. My first idea was to use libelf, but unfortunately
there seems to be a bug with it on Ubuntu. Elfedit would have probably been a nice tool but I have not found a version for Linux, in particular Ubuntu.
So, I am wondering if anyone can suggest to me if there is any other useful tool out there
to add a custom flag to an elf file?
Many thanks for your help!
People who are able to modify the kernel to take advantage of the new flag probably wouldn't be asking how to add the flag to the ELF libraries.
So, how do you plan to have the kernel use this new flag? What is the purpose of the flag?
Since you are adding to the standard libelf, can't you fix the bug for Ubuntu and let them know that you've done so (make the fix available to them - though they'll probably need to relay it back up the chain).
Please look at ELFIO library. It contains WriteObj and Writer examples. By using the library, you will be able to create and/or modify ELF binary files.
(although old question but for reference I am writing answer based on my own experience)
I suggest to read elf file in memory struct, make changes to flags and load process memory with your in-memory struct. This method will need less efford as compare to bug correction. To start, check file elf.c for elf, program header, section headers struct. you can read file header in your struct which should have three struct members for elf, program, section. start read in your struct from elf header. then read program header on offset given in elf header (iteratively for all program headers). In same way you can read all sections through section headers.
encapsulating 3 headers struct in your own struct also give you oppertunity to have extra needed data in your other struct member.