How should I go about storing resources in C - c

What system should I use to store resources (Images, SoundEffects etc) in C?
One example would be storing them in a struct type system:
struct _Resource {
struct _Image {
SDL_Surface *MenuButton;
} Image;
struct _SoundEffect {
Mix_Chunk *MenuButtonSound;
} SoundEffect;
} Resource;
Another example would be storing them in an array:
SDL_Surface *Image[5];
Mix_Chunk *SoundEffect[5];
What are your thoughts?

There are millions of ways of doing it. Asking about what is the best way is not really constructive. You may want to see how others do it (if not re-using those components/libraries to avoid re-inventing a wheel):
GTK Resource Files
Qt Resource System
OS X bundle
Windows resource files

This question is very general, so here's the general answer:
First, you should know that struct an array are orthogonal concepts. You don't need to choose between them, you can have both.
Now usually, when you decide to have a struct, it's because the data are somehow related. For example, if you have resource that is clickable and has a position, a struct such as the following
typedef struct Resource
{
int x, y;
SDL_Surface MenuBotton;
void (*click_callback)(struct Resource *);
} Resource;
makes sense. However, if you have two unrelated concepts, such as image and sound, it absolutely doesn't make sense to put them together in one struct (unless for special cases, such as sending the pointer to a thread!)
So what you need to do is, divide different concepts and group information that are relevant to each other. Make structs out of the relevant information and create arrays of them if you have many instances of them.
In the end, you may want to have one big struct containing everything worked on by a manager of some sort, but that certainly depends on your application.

Related

Linked list node with pointer to struct in C

I am new to C programming. Familiarising muself with struct pointers and linekd lists. I came across concept of linked list node with pointer to struct.
typedef struct
{
string name, surname;
int matriculation_num;
}Student_typedef;
typedef struct
{
Tstudent* student;
Node_typedef* next;
} Node_typedef;
Can anyone tell me what exactly is the purpose of Node_typedef. Where are such implementations usefull ?
Any useful link is much appreciated.
The two shown struct type definitions separate the stored data from the storing mechanism.
You can see that Student_typedef has only members which relate to information to store, but none relating to storing. The goal is to have a mechanism which can store a multitude of this data structure.
On the other hand Node_typedef does not contain any of the information to store, only a single pointer to the complete data. If the structure of the inforamtion to store would change (though still be reflected by the same type identifier Student_typedef), then nothing about this storage mechanism would have to be changed.
Or to describe it from a different angle, two developers working on a student database would only have to agree that all the needed information for each student is inside Student_typedef. Then one developer could handle programming functions to enter or edit a given struct (based on a pointer to the struct provided by the storage), while the other developer could handle storage aspects, like adding a new struct to fill, deleting, optimising memory, etc.
Such methods of interface definition and abstraction of code parts are necessary for efficiently handling large projects.

Incomplete type with size

I'm writing a C library, and have a struct that looks (roughly) like:
struct Obj {
char tag,
union {
int i,
void *v
} val
};
I do not want to expose the internals of this struct through the API, because users do not need to know the implementation and they could change in future versions. Users can interact with the struct via functions in the API.
I used incomplete types in the header for other, larger types in my API, which can only be accessed via pointer by the user. I do not want to restrict users to accessing Obj via pointer, as Obj will likely only be 16 bytes maximum.
I have not been able to use an incomplete type here, because I do not know of a way to expose only the size of the struct to users, without fields.
My question is:
Is there a way to expose a type with size only in C (no knowledge of the fields in the struct given to user), some other hack to accomplish what I want, or should I implement this in some completely different way?
Please comment if I haven't provided enough details or anything is unclear.
The standard pattern for this is to create a function which allocates the struct for the user:
struct Obj* obj_new(void) {
return malloc(sizeof(struct Obj));
}
Then just leave the type as incomplete in your public header.
Of course, if you really want to expose only the size, you could just create a function which returns sizeof(struct Obj). Obviously people can misuse it (e.g., hardcoding the value into their code as an "optimization" to avoid calling that function), but that's not on you. It is something that is done occasionally, usually to help facilitate inheritance.

Is there a more efficient way to store an n-ary tree in a file in C?

Say I'm writing an adventure game. The map is built of tiles of different types. I have tiles that form paths, and tiles that form doors, and so on.
I will use a struct to describe the type and content of a tile, and to which other tiles it connects.
Then I'll make a quadruple-linked list to connect them all together.
But a struct that will describe a room will have far more elements than one that will describe a door, so many elements in a door struct will be redundant. I could make a smaller door struct, but structs can only point to structs of the same type*, so I couldn't connect a room struct to a door struct. The redundancy may be negligible but I wondered if there's another way.
Another option is using an array of structs, but then I'd have lots of 'padding' structs wasting even more space. However an array would make reading and re-building a map from file much easier.
Is there any way around the limitation that a struct can only point to a struct of the same type? Or is there another common solution to this problem that I haven't mentioned?
One idea I had was that each tile could have pointers for every other type of tile. Some would be redundant, but it would be a lesser redundancy that the option above.
*By this I mean that typically in a linked list, structs contain pointers to struct of the same type that they're in.
You really don't have to have a uniform struct describing everything. Instead, you could do the following (this is somewhat like writing your own C++ virtual tables in C, and is very widely used).
Your basic tile struct can look like this:
struct tile
{
// common tile stuff
...
enum tile_type type;
void *type_info;
};
So in this struct you store stuff that's common to every tile type. Then you make other structs for other types: one for a room, one for a path, etc. Within an object of tile, you make the enum describe the actual type, and store a pointer to the concrete type within the void *.
There are many links describing variations of this technique. Here's one.
Instead of storing elements in a tile, store only a pointer to the linked list of elements.

Common datastructure library in C

Hello I have started writing common data structure library in C similar to STL.
Here is the link . http://code.google.com/p/cstl/
I struggled a lot of whether to go ahead with having void* as basic element for data structure. and End up with structure which has two elements
typedef struct __c_lib__object {
void* raw_data;
size_t size;
} clib_object, *clib_object_ptr;
This approach allow me to store each element, but it requires lot of memory allocation , during saving and returning back the element from the container.
Can anybody please review this , and let me know if there is any other approach.
Thanks
Avinash
Names starting with double-underscore are reserved to 'the implementation' and should be avoided in user code.
Personally, I dislike typedefs for pointers; I'd rather use clib_object *x; than clib_object_ptr x;.
Why do you need to record the size of the object?

Serialize Data Structures in C

I'd like a C library that can serialize my data structures to disk, and then load them again later. It should accept arbitrarily nested structures, possibly with circular references.
I presume that this tool would need a configuration file describing my data structures. The library is allowed to use code generation, although I'm fairly sure it's possible to do this without it.
Note I'm not interested in data portability. I'd like to use it as a cache, so I can rely on the environment not changing.
Thanks.
Results
Someone suggested Tpl which is an awesome library, but I believe that it does not do arbitrary object graphs, such as a tree of Nodes that each contain two other Nodes.
Another candidate is Eet, which is a project of the Enlightenment window manager. Looks interesting but, again, seems not to have the ability to serialize nested structures.
Check out tpl. From the overview:
Tpl is a library for serializing C
data. The data is stored in its
natural binary form. The API is small
and tries to stay "out of the way".
Compared to using XML, tpl is faster
and easier to use in C programs. Tpl
can serialize many C data types,
including structures.
I know you're asking for a library. If you can't find one (::boggle::, you'd think this was a solved problem!), here is an outline for a solution:
You should be able to write a code generator[1] to serialize trees/graphs without (run-time) pre-processing fairly simply.
You'll need to parse the node structure (typedef handling?), and write the included data values in a straight ahead fashion, but treat the pointers with some care.
For pointer to other objects (i.e. char *name;) which you know are singly referenced, you can serialize the target data directly.
For objects that might be multiply refernced and for other nodes of your tree you'll have to represent the pointer structure. Each object gets assigned a serialization number, which is what is written out in-place of the pointer. Maintain a translation structure between current memory position and serialization number. On encountering a pointer, see if it is already assigned a number, if not, give it one and queue that object up for serialization.
Reading back also requires a node-#/memory-location translation step, and might be easier to do in two passes: regenerate the nodes with the node numbers in the pointer slots (bad pointer, be warned) to find out where each node gets put, then walk the structure again fixing the pointers.
I don't know anything about tpl, but you might be able to piggy-back on it.
The on-disk/network format should probably be framed with some type information. You'll need a name-mangling scheme.
[1] ROOT uses this mechanism to provide very flexible serialization support in C++.
Late addition: It occurs to me that this is not always as easy as I implied above. Consider the following (contrived and badly designed) declaration:
enum {
mask_none = 0x00,
mask_something = 0x01,
mask_another = 0x02,
/* ... */
mask_all = 0xff
};
typedef struct mask_map {
int mask_val;
char *mask_name;
} mask_map_t;
mask_map_t mask_list[] = {
{mask_something, "mask_something"},
{mask_another, "mask_another"},
/* ... */
};
struct saved_setup {
char* name;
/* various configuration data */
char* mask_name;
/* ... */
};
and assume that we initalize out struct saved_setup items so that mask_name points at mask_list[foo].mask_name.
When we go to serialize the data, what do we do with struct saved_setup.mask_name?
You will need to take care in designing your data structures and/or bring some case-specific intelligence to the serialization process.
This is my solution. It uses my own implementation of malloc, free and mmap, munmap system calls. Follow the given example codes. Ref: http://amscata.blogspot.com/2013/02/serialize-your-memory.html
In my approach I create a char array as my own RAM space. Then there are functions for allocate the memory and free them. After creating the data structure, by using mmap, I write the char array to a file.
Whenever you want to load it back to the memory there is a function which used munmap to put the data structure again to the char array. Since it has virtual addresses for your pointers, you can re use your data structure. That means, you can create data structure, save it, load it, again edit it, and save it again.
You can take a look on eet. A library of the enlightenment project to store C data types (including nested structures). Although nearly all libs of the enlightenment project are in pre-alpha state, eet is already released. I'm not sure, however, if it can handle circular references. Probably not.
http://s11n.net/c11n/
HTH
you should checkout gwlib. the serializer/deserializer is extensive. and there are extensive tests available to look at. http://gwlib.com/
I'm assuming you are talking about storing a graph structure, if not then disregard...
If your storing a graph, I personally think the best idea would be implementing a function that converts your graph into an adjacency matrix. You can then make a function that converts an adjacency matrix to your graph data structure.
This has three benefits (that may or may not matter in your application):
adjacency matrix are a very natural way to create and store a graph
You can create an adjacency matrix and import them into your applications
You can store and read your data in a meaningful way.
I used this method during a CS project and is definitely how I would do it again.
You can read more about adjacency matrix here: http://en.wikipedia.org/wiki/Modified_adjacency_matrix
Another option is Avro C, an implementation of Apache Avro in C.
Here is an example using the Binn library (my creation):
binn *obj;
// create a new object
obj = binn_object();
// add values to it
binn_object_set_int32(obj, "id", 123);
binn_object_set_str(obj, "name", "Samsung Galaxy Charger");
binn_object_set_double(obj, "price", 12.50);
binn_object_set_blob(obj, "picture", picptr, piclen);
// send over the network
send(sock, binn_ptr(obj), binn_size(obj));
// release the buffer
binn_free(obj);
If you don't want to use strings as keys you can use a binn_map which uses integers as keys.
There is also support for lists, and all these structures can be nested:
binn *list;
// create a new list
list = binn_list();
// add values to it
binn_list_add_int32(list, 123);
binn_list_add_double(list, 2.50);
// add the list to the object
binn_object_set_list(obj, "items", list);
// or add the object to the list
binn_list_add_object(list, obj);
In theory YAML should do what you want http://code.google.com/p/yaml-cpp/
Please let me know if it works for you.

Resources