|
Why these extra brackets? |
Doctor Cop
Member #16,833
April 2018
|
I was searching on the GitHub for a simple compression library and I came across zip lib. Its a minimal wrapper on top of miniz library. I have generated the object file successfully but when I came across examples then I got confused by this one. 1struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
2{
3 zip_entry_open(zip, "foo-1.txt");
4 {
5 const char *buf = "Some data here...\0";
6 zip_entry_write(zip, buf, strlen(buf));
7 }
8 zip_entry_close(zip);
9
10 zip_entry_open(zip, "foo-2.txt");
11 {
12 // merge 3 files into one entry and compress them on-the-fly.
13 zip_entry_fwrite(zip, "foo-2.1.txt");
14 zip_entry_fwrite(zip, "foo-2.2.txt");
15 zip_entry_fwrite(zip, "foo-2.3.txt");
16 }
17 zip_entry_close(zip);
18}
19zip_close(zip);
|
dthompson
Member #5,749
April 2005
|
You've basically got it: using arbitrary blocks like this is for readability, but also (in newer C standards) allows for tighter scoping. buf ceases to be accessible after the block it's declared in has ended. As this is a relatively small piece of code, there isn't a huge benefit - but when working with huge functions, block-scoped variables are useful to prevent 'pollution' of the namespace, such that you don't accidentally reuse variables later on when you didn't mean to. ______________________________________________________ |
Edgar Reynaldo
Major Reynaldo
May 2007
|
You might also be interested in learning about the Dangling Else clause. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Neil Roy
Member #2,229
April 2002
|
There's no real need to use them unless you don't want buf to be accessable outside of that scope. As for ZIP file access, you can do that in Allegro with PHYSFS fairly easily, and then simply read and write files as you normally would. Depends on what you want it for of course. --- |
Chris Katko
Member #1,881
January 2002
|
For the 2 obvious reasons: - Code is documentation. Writing code in logical blocks makes it clear the lines of code are related. - RAII. RAII. RAII. And maybe some RAII. In C++ (and even other languages), you make it so objects can never exist in an invalid state. You do this by creating an object with a constructor that has all the required data passed to it. A connection object, is given the URL, port, etc--all it needs. And it either FAILS (and yields a null, or throws an exception), or it's a real object. The second step of RAII? Getting rid of the object when you're done. RAII returns a resource whenever the object is deleted. Like... when it leaves the stack. void my_function() { //code { auto c = new connection("192.168.1.1", 80); c.send_data("Hello world."); } //closes connection. automatically. zero calls. //zero room for user error like forgetting //more code } Other languages actually recognize this pattern so often that they make it an actual construct. It's typically named with() or using(). with(auto c = new connection("192.168.1.1", 80)) { c.send_data("Hello world."); } Additionally, with/using also allows you to embed another scope. So: with(auto c = new connection("192.168.1.1", 80)) { // all of c's namespace is assumed / added to the block // and tried for name resolution. send_data("Hello world."); // no need for c. } That's really nifty when you have a really long one like with(my.object.long.deference.c) { taco(); //calls my.object.long.deference.c.taco() }
-----sig: |
Doctor Cop
Member #16,833
April 2018
|
Thank you all for your responses, it's very helpful. NiteHackr
|
Audric
Member #907
January 2001
|
Note how they use the pattern even when there is no local (block-scope) variable. The zip_entry_open() / zip_entry_close() must be used as a pair, and every zip_entry_*() acts relative to the current entry. The zip_t structure must keep track of the context. It would be more foolproof with a different API, but the API being how it is, I can understand how the coder used an unusual (?) coding style for these functions, in order to avoid errors. |
bamccaig
Member #7,536
July 2006
|
Edgar Reynaldo said: Katko, your RAII is leaking like a sieve It's not the RAII that is leaking. It's the lack thereof. In any case, it looks like the OP's snippet is C so RAII doesn't apply and will likely only confuse the OP. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Unless you're using a GC, the following code will always leak : auto x = new X();
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Chris Katko
Member #1,881
January 2002
|
I wrote it at like 3 am, cut me some slack. The point still stands. I never said it was functional code. Edgar Reynaldo said: You're using a GC Which I am. bamccaig said: OP's snippet is C so RAII doesn't apply and will likely only confuse the OP. He said the construct. That construct exists in many languages. -----sig: |
Doctor Cop
Member #16,833
April 2018
|
Thanks Edgar, now I know how embed resources into executable and now I just need to use Physfs to embed the resources into a separate file and link that file to the executable. I am currently experimenting with stdio.h to use with my logic.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Just use 7Zip to make a zip file, then embed your object into your executable and use PhysFS to load it. Edit My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Doctor Cop
Member #16,833
April 2018
|
I don't want to embed it into executable, I want to make a separate file which will have all the resources and I will load resources from that file. That's what I'm trying to do.
|
Neil Roy
Member #2,229
April 2002
|
In my Deluxe Pacman 2 game, I have all my resources inside a ZIP file, complete with folders in it etc... to organize the data. I renamed the .zip extension as .pak, but you can use whatever you wish, doesn't have to be .zip. I then use Allegro 5 with PhysFS to load in my resources as needed like you would any other file. It's really quite simple. I recently released the source code to my Deluxe Pacman 2 game, it is written in C (not C++), and uses only Allegro 5. If you're curious, you can download it. PhysFS is pretty simple to use thanks to Allegro 5. It's at my website anyhow, the game and below the download for it, is the source code. https://nitehackr.github.io/games_index.html if you download the game itself, it contains the .PAK file which is the renamed ZIP, you can open it with something like 7ZIP easy and examine, extract all the data etc. It's all I did to create it. --- |
Doctor Cop
Member #16,833
April 2018
|
Thanks NiteHackr, I'll check it out once I successfully implement AI part in my game. If only I had any clue what I'm doing ... Any suggestions on good game design? Right now I'm following 'tutorial's point' and From next time when I plan a project I will use DFD first and then code. This is my resolution for 2019!
|
princeofspace
Member #11,874
April 2010
|
As an aside, Python comes with a built-in zip encoder that I use for my projects. At the top of your script: import zipfile Then, when you get around to writing those files into a zip PhysFS can read, do this: with zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) as z: for f in [files to write]: z.write(f) This has saved me a lot of time, because I can just keep a folder of project content and run a script every time I want to update what's in the program. I've thought about uploading this to my github, but then I'd have to write documentation on it, which nobody likes to do. |
|