blob: 94e1ed513c8f7b6209810c2232dc3c78b6aac88d [file] [log] [blame]
Kevin O'Connor59d6ca52012-05-31 00:20:55 -04001// Access to pseudo "file" interface for configuration information.
2//
3// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
4//
5// This file may be distributed under the terms of the GNU LGPLv3 license.
6
7#include "config.h" // CONFIG_*
8#include "util.h" // dprintf
Kevin O'Connor41639f82013-09-14 19:37:36 -04009#include "romfile.h" // struct romfile_s
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040010#include "string.h" // memcmp
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040011
Kevin O'Connor70c94dd2013-03-08 19:39:49 -050012static struct romfile_s *RomfileRoot VARVERIFY32INIT;
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040013
14void
15romfile_add(struct romfile_s *file)
16{
Kevin O'Connorc40e3fa2013-02-09 14:55:30 -050017 dprintf(3, "Add romfile: %s (size=%d)\n", file->name, file->size);
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040018 file->next = RomfileRoot;
19 RomfileRoot = file;
20}
21
22// Search for the specified file.
23static struct romfile_s *
24__romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev)
25{
26 struct romfile_s *cur = RomfileRoot;
27 if (prev)
28 cur = prev->next;
29 while (cur) {
30 if (memcmp(prefix, cur->name, prefixlen) == 0)
31 return cur;
32 cur = cur->next;
33 }
34 return NULL;
35}
36
37struct romfile_s *
38romfile_findprefix(const char *prefix, struct romfile_s *prev)
39{
40 return __romfile_findprefix(prefix, strlen(prefix), prev);
41}
42
43struct romfile_s *
44romfile_find(const char *name)
45{
46 return __romfile_findprefix(name, strlen(name) + 1, NULL);
47}
48
49// Helper function to find, malloc_tmphigh, and copy a romfile. This
50// function adds a trailing zero to the malloc'd copy.
51void *
52romfile_loadfile(const char *name, int *psize)
53{
54 struct romfile_s *file = romfile_find(name);
55 if (!file)
56 return NULL;
57
58 int filesize = file->size;
59 if (!filesize)
60 return NULL;
61
62 char *data = malloc_tmphigh(filesize+1);
63 if (!data) {
64 warn_noalloc();
65 return NULL;
66 }
67
68 dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
69 int ret = file->copy(file, data, filesize);
70 if (ret < 0) {
71 free(data);
72 return NULL;
73 }
74 if (psize)
75 *psize = filesize;
76 data[filesize] = '\0';
77 return data;
78}
79
80// Attempt to load an integer from the given file - return 'defval'
81// if unsuccesful.
82u64
83romfile_loadint(const char *name, u64 defval)
84{
85 struct romfile_s *file = romfile_find(name);
86 if (!file)
87 return defval;
88
89 int filesize = file->size;
90 if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
91 // Doesn't look like a valid integer.
92 return defval;
93
94 u64 val = 0;
95 int ret = file->copy(file, &val, sizeof(val));
96 if (ret < 0)
97 return defval;
98 return val;
99}