Skip to content

Commit 564f364

Browse files
committed
Resync
1 parent 60d1b5b commit 564f364

4 files changed

Lines changed: 105 additions & 97 deletions

File tree

formats/m3u/m3u_file.c

Lines changed: 83 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <lists/string_list.h>
2727
#include <file/file_path.h>
2828
#include <streams/file_stream.h>
29+
#include <array/rbuf.h>
2930

3031
#include <formats/m3u_file.h>
3132

@@ -50,8 +51,6 @@
5051
struct content_m3u_file
5152
{
5253
char *path;
53-
size_t size;
54-
size_t capacity;
5554
m3u_file_entry_t *entries;
5655
};
5756

@@ -66,6 +65,7 @@ static bool m3u_file_load(m3u_file_t *m3u_file)
6665
int64_t file_len = 0;
6766
uint8_t *file_buf = NULL;
6867
struct string_list *lines = NULL;
68+
bool success = false;
6969
size_t i;
7070
char entry_path[PATH_MAX_LENGTH];
7171
char entry_label[PATH_MAX_LENGTH];
@@ -74,27 +74,28 @@ static bool m3u_file_load(m3u_file_t *m3u_file)
7474
entry_label[0] = '\0';
7575

7676
if (!m3u_file)
77-
return false;
77+
goto end;
7878

7979
/* Check whether file exists
8080
* > If path is empty, then an error
8181
* has occurred... */
8282
if (string_is_empty(m3u_file->path))
83-
return false;
83+
goto end;
8484

8585
/* > File must have the correct extension */
8686
file_ext = path_get_extension(m3u_file->path);
8787

88-
if (string_is_empty(file_ext))
89-
return false;
90-
91-
if (!string_is_equal_noncase(file_ext, M3U_FILE_EXT))
92-
return false;
88+
if (string_is_empty(file_ext) ||
89+
!string_is_equal_noncase(file_ext, M3U_FILE_EXT))
90+
goto end;
9391

9492
/* > If file does not exist, no action
9593
* is required */
9694
if (!path_is_valid(m3u_file->path))
97-
return true;
95+
{
96+
success = true;
97+
goto end;
98+
}
9899

99100
/* Read file from disk */
100101
if (filestream_read_file(m3u_file->path, (void**)&file_buf, &file_len) >= 0)
@@ -105,52 +106,50 @@ static bool m3u_file_load(m3u_file_t *m3u_file)
105106

106107
/* File buffer no longer required */
107108
if (file_buf)
109+
{
108110
free(file_buf);
111+
file_buf = NULL;
112+
}
109113
}
114+
/* File IO error... */
110115
else
111-
{
112-
/* File IO error... */
113-
if (file_buf)
114-
free(file_buf);
115-
return false;
116-
}
116+
goto end;
117117

118118
/* If file was empty, no action is required */
119119
if (!lines)
120-
return true;
120+
{
121+
success = true;
122+
goto end;
123+
}
121124

122125
/* Parse lines of file */
123126
for (i = 0; i < lines->size; i++)
124127
{
125-
size_t m3u_size;
126128
const char *line = lines->elems[i].data;
127129

128130
if (string_is_empty(line))
129131
continue;
130132

131133
/* Determine line 'type' */
132-
m3u_size = STRLEN_CONST(M3U_FILE_NONSTD_LABEL);
133134

134135
/* > '#LABEL:' */
135-
if (!strncmp(
136-
line, M3U_FILE_NONSTD_LABEL,
137-
m3u_size))
136+
if (string_starts_with_size(line, M3U_FILE_NONSTD_LABEL,
137+
STRLEN_CONST(M3U_FILE_NONSTD_LABEL)))
138138
{
139139
/* Label is the string to the right
140140
* of '#LABEL:' */
141-
const char *label = line + m3u_size;
141+
const char *label = line + STRLEN_CONST(M3U_FILE_NONSTD_LABEL);
142142

143143
if (!string_is_empty(label))
144144
{
145145
strlcpy(
146-
entry_label, line + m3u_size,
146+
entry_label, line + STRLEN_CONST(M3U_FILE_NONSTD_LABEL),
147147
sizeof(entry_label));
148148
string_trim_whitespace(entry_label);
149149
}
150150
}
151151
/* > '#EXTINF:' */
152-
else if (!strncmp(
153-
line, M3U_FILE_EXTSTD_LABEL,
152+
else if (string_starts_with_size(line, M3U_FILE_EXTSTD_LABEL,
154153
STRLEN_CONST(M3U_FILE_EXTSTD_LABEL)))
155154
{
156155
/* Label is the string to the right
@@ -210,24 +209,37 @@ static bool m3u_file_load(m3u_file_t *m3u_file)
210209
}
211210

212211
/* Add entry to file
213-
* > Ignore errors here - invalid entries
214-
* will just be omitted */
215-
m3u_file_add_entry(m3u_file, entry_path, entry_label);
212+
* > Note: The only way that m3u_file_add_entry()
213+
* can fail here is if we run out of memory.
214+
* This is a critical error, and m3u_file must
215+
* be considered invalid in this case */
216+
if (!string_is_empty(entry_path) &&
217+
!m3u_file_add_entry(m3u_file, entry_path, entry_label))
218+
goto end;
216219

217220
/* Reset entry_path/entry_label */
218221
entry_path[0] = '\0';
219222
entry_label[0] = '\0';
220223
}
221224
}
222225

226+
success = true;
227+
228+
end:
223229
/* Clean up */
224230
if (lines)
225231
{
226232
string_list_free(lines);
227233
lines = NULL;
228234
}
229235

230-
return true;
236+
if (file_buf)
237+
{
238+
free(file_buf);
239+
file_buf = NULL;
240+
}
241+
242+
return success;
231243
}
232244

233245
/* Creates and initialises an M3U file
@@ -238,16 +250,15 @@ static bool m3u_file_load(m3u_file_t *m3u_file)
238250
* - Returned m3u_file_t object must be free'd using
239251
* m3u_file_free()
240252
* - Returns NULL in the event of an error */
241-
m3u_file_t *m3u_file_init(const char *path, size_t size)
253+
m3u_file_t *m3u_file_init(const char *path)
242254
{
243-
m3u_file_entry_t *entries = NULL;
244-
m3u_file_t *m3u_file = NULL;
255+
m3u_file_t *m3u_file = NULL;
245256
char m3u_path[PATH_MAX_LENGTH];
246257

247258
m3u_path[0] = '\0';
248259

249260
/* Sanity check */
250-
if (string_is_empty(path) || (size < 1))
261+
if (string_is_empty(path))
251262
return NULL;
252263

253264
/* Get 'real' file path */
@@ -258,27 +269,17 @@ m3u_file_t *m3u_file_init(const char *path, size_t size)
258269
return NULL;
259270

260271
/* Create m3u_file_t object */
261-
m3u_file = (m3u_file_t*)calloc(1, sizeof(*m3u_file));
272+
m3u_file = (m3u_file_t*)malloc(sizeof(*m3u_file));
262273

263274
if (!m3u_file)
264275
return NULL;
265276

266-
/* Create m3u_file_entry_t array */
267-
entries = (m3u_file_entry_t*)calloc(size, sizeof(*entries));
268-
269-
if (!entries)
270-
{
271-
free(m3u_file);
272-
return NULL;
273-
}
277+
/* Initialise members */
278+
m3u_file->path = NULL;
279+
m3u_file->entries = NULL;
274280

275281
/* Copy file path */
276-
m3u_file->path = strdup(m3u_path);
277-
278-
/* Set remaining values */
279-
m3u_file->size = 0;
280-
m3u_file->capacity = size;
281-
m3u_file->entries = entries;
282+
m3u_file->path = strdup(m3u_path);
282283

283284
/* Read existing file contents from
284285
* disk, if required */
@@ -327,15 +328,14 @@ void m3u_file_free(m3u_file_t *m3u_file)
327328
/* Free entries */
328329
if (m3u_file->entries)
329330
{
330-
for (i = 0; i < m3u_file->size; i++)
331+
for (i = 0; i < RBUF_LEN(m3u_file->entries); i++)
331332
{
332333
m3u_file_entry_t *entry = &m3u_file->entries[i];
333334
m3u_file_free_entry(entry);
334335
}
335336

336-
free(m3u_file->entries);
337+
RBUF_FREE(m3u_file->entries);
337338
}
338-
m3u_file->entries = NULL;
339339

340340
free(m3u_file);
341341
}
@@ -357,17 +357,7 @@ size_t m3u_file_get_size(m3u_file_t *m3u_file)
357357
if (!m3u_file)
358358
return 0;
359359

360-
return m3u_file->size;
361-
}
362-
363-
/* Returns maximum number of entries permitted
364-
* in M3U file */
365-
size_t m3u_file_get_capacity(m3u_file_t *m3u_file)
366-
{
367-
if (!m3u_file)
368-
return 0;
369-
370-
return m3u_file->capacity;
360+
return RBUF_LEN(m3u_file->entries);
371361
}
372362

373363
/* Fetches specified M3U file entry
@@ -378,8 +368,7 @@ bool m3u_file_get_entry(
378368
{
379369
if (!m3u_file ||
380370
!entry ||
381-
(idx >= m3u_file->size) ||
382-
!m3u_file->entries)
371+
(idx >= RBUF_LEN(m3u_file->entries)))
383372
return false;
384373

385374
*entry = &m3u_file->entries[idx];
@@ -393,30 +382,35 @@ bool m3u_file_get_entry(
393382
/* Setters */
394383

395384
/* Adds specified entry to the M3U file
396-
* - Returns false if path is invalid, or M3U
397-
* file capacity is exceeded */
385+
* - Returns false if path is invalid, or
386+
* memory could not be allocated for the
387+
* entry */
398388
bool m3u_file_add_entry(
399389
m3u_file_t *m3u_file, const char *path, const char *label)
400390
{
401391
m3u_file_entry_t *entry = NULL;
392+
size_t num_entries;
402393
char full_path[PATH_MAX_LENGTH];
403394

404395
full_path[0] = '\0';
405396

406-
if (!m3u_file ||
407-
!m3u_file->entries ||
408-
(m3u_file->size >= m3u_file->capacity) ||
409-
string_is_empty(path))
397+
if (!m3u_file || string_is_empty(path))
410398
return false;
411399

412-
/* Get new entry at end of list */
413-
entry = &m3u_file->entries[m3u_file->size];
400+
/* Get current number of file entries */
401+
num_entries = RBUF_LEN(m3u_file->entries);
414402

415-
if (!entry)
403+
/* Attempt to allocate memory for new entry */
404+
if (!RBUF_TRYFIT(m3u_file->entries, num_entries + 1))
416405
return false;
417406

418-
/* Ensure entry is free'd */
419-
m3u_file_free_entry(entry);
407+
/* Allocation successful - increment array size */
408+
RBUF_RESIZE(m3u_file->entries, num_entries + 1);
409+
410+
/* Fetch entry at end of list, and zero-initialise
411+
* members */
412+
entry = &m3u_file->entries[num_entries];
413+
memset(entry, 0, sizeof(*entry));
420414

421415
/* Copy path and label */
422416
entry->path = strdup(path);
@@ -444,9 +438,6 @@ bool m3u_file_add_entry(
444438

445439
entry->full_path = strdup(full_path);
446440

447-
/* Increment size counter */
448-
m3u_file->size++;
449-
450441
return true;
451442
}
452443

@@ -460,14 +451,14 @@ void m3u_file_clear(m3u_file_t *m3u_file)
460451

461452
if (m3u_file->entries)
462453
{
463-
for (i = 0; i < m3u_file->size; i++)
454+
for (i = 0; i < RBUF_LEN(m3u_file->entries); i++)
464455
{
465456
m3u_file_entry_t *entry = &m3u_file->entries[i];
466457
m3u_file_free_entry(entry);
467458
}
468-
}
469459

470-
m3u_file->size = 0;
460+
RBUF_FREE(m3u_file->entries);
461+
}
471462
}
472463

473464
/* Saving */
@@ -510,7 +501,7 @@ bool m3u_file_save(
510501
return false;
511502

512503
/* Loop over entries */
513-
for (i = 0; i < m3u_file->size; i++)
504+
for (i = 0; i < RBUF_LEN(m3u_file->entries); i++)
514505
{
515506
m3u_file_entry_t *entry = &m3u_file->entries[i];
516507
char entry_path[PATH_MAX_LENGTH];
@@ -593,13 +584,18 @@ static int m3u_file_qsort_func(
593584
/* Sorts M3U file entries in alphabetical order */
594585
void m3u_file_qsort(m3u_file_t *m3u_file)
595586
{
596-
if (!m3u_file ||
597-
!m3u_file->entries ||
598-
(m3u_file->size < 2))
587+
size_t num_entries;
588+
589+
if (!m3u_file)
590+
return;
591+
592+
num_entries = RBUF_LEN(m3u_file->entries);
593+
594+
if (num_entries < 2)
599595
return;
600596

601597
qsort(
602-
m3u_file->entries, m3u_file->size,
598+
m3u_file->entries, num_entries,
603599
sizeof(m3u_file_entry_t),
604600
(int (*)(const void *, const void *))m3u_file_qsort_func);
605601
}

include/array/rbuf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
* The first time an element is added, memory for 16 elements are allocated.
3434
* Then every time length is about to exceed capacity, capacity is doubled.
3535
*
36+
* Be careful not to supply modifying statements to the macro arguments.
37+
* Something like RBUF_REMOVE(buf, i--); would have unintended results.
38+
*
3639
* Sample usage:
3740
*
3841
* mytype_t* buf = NULL;
@@ -74,6 +77,7 @@
7477
#define RBUF_RESIZE(b, sz) (RBUF_FIT((b), (sz)), ((b) ? RBUF__HDR(b)->len = (sz) : 0))
7578
#define RBUF_CLEAR(b) ((b) ? RBUF__HDR(b)->len = 0 : 0)
7679
#define RBUF_TRYFIT(b, n) (RBUF_FIT((b), (n)), (((b) && RBUF_CAP(b) >= (size_t)(n)) || !(n)))
80+
#define RBUF_REMOVE(b, idx) memmove((b) + (idx), (b) + (idx) + 1, (--RBUF__HDR(b)->len - (idx)) * sizeof(*(b)))
7781

7882
struct rbuf__hdr
7983
{

0 commit comments

Comments
 (0)