1 #include "malloc.h" // realloc() and free()
2 #include <string.h> // strncasecmp()
6 // how is our flag organized?
8 #define FLAG_VALID(flag) (flag == 0xCF)
10 static int do_resize(struct song_entry
*e
, const uint32_t name_len
, const uint32_t genre_len
, const int zero_fill
);
12 struct song_entry
* new_song_entry(const uint32_t name_len
, const uint32_t genre_len
) {
13 // Start my allocating memory
14 struct song_entry
*e
= (struct song_entry
*)malloc(sizeof(struct song_entry
));
16 DEBUGF("new_song_entry: could not allocate memory\n");
29 e
->size
.genre_len
= 0;
39 // and resize to the requested size
40 if( do_resize(e
, name_len
, genre_len
, 1) ) {
47 int song_entry_destruct(struct song_entry
*e
) {
49 assert(FLAG_VALID(e
->flag
));
59 static int do_resize(struct song_entry
*e
, const uint32_t name_len
, const uint32_t genre_len
, const int zero_fill
) {
63 assert(FLAG_VALID(e
->flag
));
66 if( name_len
!= e
->size
.name_len
) {
67 temp
= realloc(e
->name
, name_len
);
68 if(temp
== NULL
&& name_len
> 0) { // if realloc(,0) don't complain about NULL-pointer
69 DEBUGF("song_entry_resize: out of memory to resize name\n");
72 e
->name
= (char*)temp
;
74 // if asked, fill it with zero's
77 for(i
=e
->size
.name_len
; i
<name_len
; i
++)
78 e
->name
[i
] = (char)0x00;
81 e
->size
.name_len
= name_len
;
85 if( genre_len
!= e
->size
.genre_len
) {
86 temp
= realloc(e
->genre
, genre_len
);
87 if(temp
== NULL
&& genre_len
> 0) { // if realloc(,0) don't complain about NULL-pointer
88 DEBUGF("song_entry_resize: out of memory to resize genre\n");
91 e
->genre
= (char*)temp
;
93 // if asked, fill it with zero's
96 for(i
=e
->size
.genre_len
; i
<genre_len
; i
++)
97 e
->genre
[i
] = (char)0x00;
100 e
->size
.genre_len
= genre_len
;
106 inline int song_entry_resize(struct song_entry
*e
, const uint32_t name_len
, const uint32_t genre_len
) {
107 return do_resize(e
, name_len
, genre_len
, 1);
110 int song_entry_serialize(FILE *fd
, const struct song_entry
*e
) {
113 assert(FLAG_VALID(e
->flag
));
115 // First byte we write is a flag-byte to indicate this is a valid record
116 if( fwrite(&e
->flag
, 1, 1, fd
) != 1 ) {
117 DEBUGF("song_entry_serialize: failed to write flag-byte\n");
121 // Write the length of the name field
122 if( fwrite(&e
->size
.name_len
, sizeof(e
->size
.name_len
), 1, fd
) != 1 ) {
123 DEBUGF("song_entry_serialize: failed to write name_len\n");
127 // now the name field itself
128 if( fwrite(e
->name
, 1, e
->size
.name_len
, fd
) != e
->size
.name_len
) {
129 DEBUGF("song_entry_serialize: failed to write name\n");
134 if( fwrite(&e
->artist
, sizeof(e
->artist
), 1, fd
) != 1 ) {
135 DEBUGF("song_entry_serialize: failed to write artist\n");
140 if( fwrite(&e
->album
, sizeof(e
->album
), 1, fd
) != 1 ) {
141 DEBUGF("song_entry_serialize: failed to write album\n");
146 if( fwrite(&e
->file
, sizeof(e
->file
), 1, fd
) != 1 ) {
147 DEBUGF("song_entry_serialize: failed to write file\n");
151 // length of genre field
152 if( fwrite(&e
->size
.genre_len
, sizeof(e
->size
.genre_len
), 1, fd
) != 1 ) {
153 DEBUGF("song_entry_serialize: failed to write genre_len\n");
158 if( fwrite(e
->genre
, 1, e
->size
.genre_len
, fd
) != e
->size
.genre_len
) {
159 DEBUGF("song_entry_serialize: failed to write genre\n");
164 if( fwrite(&e
->bitrate
, sizeof(e
->bitrate
), 1, fd
) != 1 ) {
165 DEBUGF("song_entry_serialize: failed to write bitrate\n");
170 if( fwrite(&e
->year
, sizeof(e
->year
), 1, fd
) != 1 ) {
171 DEBUGF("song_entry_serialize: failed to write year\n");
176 if( fwrite(&e
->playtime
, sizeof(e
->playtime
), 1, fd
) != 1 ) {
177 DEBUGF("song_entry_serialize: failed to write playtime\n");
182 if( fwrite(&e
->track
, sizeof(e
->track
), 1, fd
) != 1 ) {
183 DEBUGF("song_entry_serialize: failed to write track\n");
188 if( fwrite(&e
->samplerate
, sizeof(e
->samplerate
), 1, fd
) != 1 ) {
189 DEBUGF("song_entry_serialize: failed to write samplerate\n");
196 int song_entry_unserialize(struct song_entry
**dest
, FILE *fd
) {
198 struct song_entry
* e
;
200 assert(dest
!= NULL
);
204 e
= new_song_entry(0, 0);
206 DEBUGF("song_entry_unserialize: could not create new song_entry\n");
210 // First we read the length of the name field
211 if( fread(&length
, sizeof(length
), 1, fd
) != 1 ) {
212 DEBUGF("song_entry_unserialize: failed to read name_len\n");
213 song_entry_destruct(e
);
217 // allocate memory for the upcomming name-field
218 if( do_resize(e
, length
, 0, 0) ) {
219 DEBUGF("song_entry_unserialize: failed to allocate memory for name\n");
220 song_entry_destruct(e
);
225 if( fread(e
->name
, 1, e
->size
.name_len
, fd
) != e
->size
.name_len
) {
226 DEBUGF("song_entry_unserialize: failed to read name\n");
227 song_entry_destruct(e
);
232 if( fread(&e
->artist
, sizeof(e
->artist
), 1, fd
) != 1 ) {
233 DEBUGF("song_entry_unserialize: failed to read artist\n");
234 song_entry_destruct(e
);
239 if( fread(&e
->album
, sizeof(e
->album
), 1, fd
) != 1 ) {
240 DEBUGF("song_entry_unserialize: failed to read album\n");
241 song_entry_destruct(e
);
246 if( fread(&e
->file
, sizeof(e
->file
), 1, fd
) != 1 ) {
247 DEBUGF("song_entry_unserialize: failed to read file\n");
248 song_entry_destruct(e
);
252 // Next the length of genre
253 if( fread(&length
, sizeof(length
), 1, fd
) != 1 ) {
254 DEBUGF("song_entry_unserialize: failed to read genre_len\n");
255 song_entry_destruct(e
);
259 // allocate memory for the upcomming name-field
260 if( do_resize(e
, e
->size
.name_len
, length
, 0) ) {
261 DEBUGF("song_entry_unserialize: failed to allocate memory for song\n");
262 song_entry_destruct(e
);
267 if( fread(e
->genre
, 1, e
->size
.genre_len
, fd
) != e
->size
.genre_len
) {
268 DEBUGF("song_entry_unserialize: failed to read genre\n");
269 song_entry_destruct(e
);
274 if( fread(&e
->bitrate
, sizeof(e
->bitrate
), 1, fd
) != 1 ) {
275 DEBUGF("song_entry_unserialize: failed to read bitrate\n");
276 song_entry_destruct(e
);
281 if( fread(&e
->year
, sizeof(e
->year
), 1, fd
) != 1 ) {
282 DEBUGF("song_entry_unserialize: failed to read year\n");
283 song_entry_destruct(e
);
288 if( fread(&e
->playtime
, sizeof(e
->playtime
), 1, fd
) != 1 ) {
289 DEBUGF("song_entry_unserialize: failed to read playtime\n");
290 song_entry_destruct(e
);
295 if( fread(&e
->track
, sizeof(e
->track
), 1, fd
) != 1 ) {
296 DEBUGF("song_entry_unserialize: failed to read track\n");
297 song_entry_destruct(e
);
302 if( fread(&e
->samplerate
, sizeof(e
->samplerate
), 1, fd
) != 1 ) {
303 DEBUGF("song_entry_unserialize: failed to read samplerate\n");
304 song_entry_destruct(e
);
312 int song_entry_write(FILE *fd
, struct song_entry
*e
, struct song_size
*s
) {
319 assert(FLAG_VALID(e
->flag
));
322 if( fwrite(e
->name
, 1, e
->size
.name_len
, fd
) != e
->size
.name_len
) {
323 DEBUGF("song_entry_write: failed to write name\n");
326 // pad the rest (abuse be32 for counter)
327 be32
= e
->size
.name_len
;
328 while( s
!= NULL
&& s
->name_len
> be32
) {
329 if( fwrite(&pad
, 1, 1, fd
) == 1 ) {
332 DEBUGF("genre_entry_write: failed to pad name\n");
338 be32
= BE32(e
->artist
);
339 if( fwrite(&be32
, sizeof(be32
), 1, fd
) != 1 ) {
340 DEBUGF("song_entry_write: failed to write artist\n");
345 be32
= BE32(e
->album
);
346 if( fwrite(&be32
, sizeof(be32
), 1, fd
) != 1 ) {
347 DEBUGF("song_entry_write: failed to write album\n");
352 be32
= BE32(e
->file
);
353 if( fwrite(&be32
, sizeof(be32
), 1, fd
) != 1 ) {
354 DEBUGF("song_entry_write: failed to write file\n");
359 if( fwrite(e
->genre
, 1, e
->size
.genre_len
, fd
) != e
->size
.genre_len
) {
360 DEBUGF("song_entry_write: failed to write genre\n");
363 // pad the rest (abuse be32 for counter)
364 be32
= e
->size
.genre_len
;
365 while( s
!= NULL
&& s
->genre_len
> be32
) {
366 if( fwrite(&pad
, 1, 1, fd
) == 1 ) {
369 DEBUGF("genre_entry_write: failed to pad genre\n");
375 be16
= BE16(e
->bitrate
);
376 if( fwrite(&be16
, sizeof(be16
), 1, fd
) != 1 ) {
377 DEBUGF("song_entry_write: failed to write bitrate\n");
382 be16
= BE16(e
->year
);
383 if( fwrite(&be16
, sizeof(be16
), 1, fd
) != 1 ) {
384 DEBUGF("song_entry_write: failed to write year\n");
389 be32
= BE32(e
->playtime
);
390 if( fwrite(&be32
, sizeof(be32
), 1, fd
) != 1 ) {
391 DEBUGF("song_entry_write: failed to write playtime\n");
396 be16
= BE16(e
->track
);
397 if( fwrite(&be16
, sizeof(be16
), 1, fd
) != 1 ) {
398 DEBUGF("song_entry_write: failed to write track\n");
403 be16
= BE16(e
->samplerate
);
404 if( fwrite(&be16
, sizeof(be16
), 1, fd
) != 1 ) {
405 DEBUGF("song_entry_write: failed to write samplerate\n");
412 inline int song_entry_compare(const struct song_entry
*a
, const struct song_entry
*b
) {
415 return strncasecmp(a
->name
, b
->name
, (a
->size
.name_len
<= b
->size
.name_len
? a
->size
.name_len
: b
->size
.name_len
) );
418 struct song_size
* new_song_size() {
420 s
= (struct song_size
*)malloc(sizeof(struct song_size
));
422 DEBUGF("new_song_size: failed to allocate memory\n");
431 inline uint32_t song_size_get_length(const struct song_size
*size
) {
432 assert(size
!= NULL
);
433 return size
->name_len
+ size
->genre_len
+ 6*4;
436 inline int song_size_max(struct song_size
*s
, const struct song_entry
*e
) {
439 assert(FLAG_VALID(e
->flag
));
440 s
->name_len
= ( s
->name_len
>= e
->size
.name_len
? s
->name_len
: e
->size
.name_len
);
441 s
->genre_len
= ( s
->genre_len
>= e
->size
.genre_len
? s
->genre_len
: e
->size
.genre_len
);
445 int song_size_destruct(struct song_size
*s
) {