A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Miika Pekkarinen
11 * Copyright (C) 2014 by Michael Sevakis
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#ifndef _DIRCACHE_H
23#define _DIRCACHE_H
24
25#include "mv.h"
26#include <string.h> /* size_t */
27#include <sys/types.h> /* ssize_t */
28
29#ifdef HAVE_DIRCACHE
30
31/****************************************************************************
32 ** Configurable values
33 **/
34
35#if 0
36/* enable dumping code */
37#define DIRCACHE_DUMPSTER
38#define DIRCACHE_DUMPSTER_BIN "/dircache_dump.bin"
39#define DIRCACHE_DUMPSTER_CSV "/dircache_dump.csv"
40#endif
41
42/* dircache builds won't search below this but will work down to this point
43 while below it the cache will just pass requests through to the storage;
44 the limiting factor is the scanning thread stack size, not the
45 implementation -- tune the two together */
46#define DIRCACHE_MAX_DEPTH 15
47#define DIRCACHE_STACK_SIZE (DEFAULT_STACK_SIZE + 0x100)
48
49/* memory buffer constants that control allocation */
50#define DIRCACHE_RESERVE (1024*64) /* 64 KB - new entry slack */
51#define DIRCACHE_MIN (1024*1024*1) /* 1 MB - provision min size */
52#define DIRCACHE_LIMIT (1024*1024*6) /* 6 MB - provision max size */
53
54/* make it easy to change serialnumber size without modifying anything else;
55 32 bits allows 21845 builds before wrapping in a 6MB cache that is filled
56 exclusively with entries and nothing else (32 byte entries), making that
57 figure pessimistic */
58typedef uint32_t dc_serial_t;
59
60/* these should agree with size of dc_serial_t */
61#define DC_SERHASH_START 0xffffffff
62
63/* I was originally using FNV hash but decided this is probably okay
64 (for now) */
65#define dc_hash_serialnum(s, h) \
66 ({ dc_serial_t __x = (s); crc_32(&(__x), sizeof(dc_serial_t), (h)); })
67#define DC_SERIAL_FMT "0x%08lX"
68
69/**
70 ****************************************************************************/
71
72#define IF_DIRCACHE(...) __VA_ARGS__
73#define IFN_DIRCACHE(...)
74
75#if CONFIG_PLATFORM & PLATFORM_NATIVE
76/* native dircache is lower-level than on a hosted target */
77#define DIRCACHE_NATIVE
78#endif
79
80struct dircache_file
81{
82 int idx; /* this file's cache index */
83 dc_serial_t serialnum; /* this file's serial number */
84};
85
86enum dircache_status
87{
88 DIRCACHE_IDLE = 0, /* no volume is initialized */
89 DIRCACHE_SCANNING = 1, /* dircache is scanning a volume */
90 DIRCACHE_READY = 2, /* dircache is ready to be used */
91};
92
93/** Dircache control **/
94void dircache_wait(void);
95void dircache_suspend(void);
96int dircache_resume(void);
97int dircache_enable(void);
98void dircache_disable(void);
99void dircache_free_buffer(void);
100
101/** Volume mounting **/
102void dircache_mount(void); /* always tries building everything it can */
103void dircache_unmount(IF_MV_NONVOID(int volume));
104
105
106/** File API service functions **/
107
108/* avoid forcing #include of file_internal.h, fat.h and dir.h */
109struct filestr_base;
110struct file_base_info;
111struct file_base_binding;
112struct dirent;
113struct dirscan_info;
114struct dirinfo_native;
115
116int dircache_readdir_dirent(struct filestr_base *stream,
117 struct dirscan_info *scanp,
118 struct dirent *entry);
119void dircache_rewinddir_dirent(struct dirscan_info *scanp);
120
121#ifdef DIRCACHE_NATIVE
122struct fat_direntry;
123int dircache_readdir_internal(struct filestr_base *stream,
124 struct file_base_info *infop,
125 struct fat_direntry *fatent);
126void dircache_rewinddir_internal(struct file_base_info *info);
127#endif /* DIRCACHE_NATIVE */
128
129
130/** Dircache live updating **/
131
132void dircache_get_rootinfo(struct file_base_info *infop);
133void dircache_bind_file(struct file_base_binding *bindp);
134void dircache_unbind_file(struct file_base_binding *bindp);
135void dircache_fileop_create(struct file_base_info *dirinfop,
136 struct file_base_binding *bindp,
137 const char *basename,
138 const struct dirinfo_native *dinp);
139void dircache_fileop_rename(struct file_base_info *dirinfop,
140 struct file_base_binding *bindp,
141 const char *basename);
142void dircache_fileop_remove(struct file_base_binding *bindp);
143void dircache_fileop_sync(struct file_base_binding *infop,
144 const struct dirinfo_native *dinp);
145
146
147/** Dircache paths, files and shortcuts **/
148struct dircache_fileref
149{
150 struct dircache_file dcfile;
151 dc_serial_t serialhash; /* Hash of serialnumbers to root */
152};
153
154void dircache_fileref_init(struct dircache_fileref *dcfrefp);
155ssize_t dircache_get_fileref_path(const struct dircache_fileref *dcfrefp,
156 char *buf, size_t size);
157
158/* Bitflags for dircache_search() */
159enum dircache_search_flags
160{
161 DCS_FILEREF = 0x01, /* Check fileref existence and serial number */
162 _DCS_VERIFY_FLAG = 0x02, /* Internal: Only valid with DCS_FILEREF */
163 DCS_FILEREF_VERIFY = 0x03, /* Do DCS_FILEREF check + verify serial hash */
164 DCS_CACHED_PATH = 0x04, /* Check only cache for provided path */
165 _DCS_STORAGE_FLAG = 0x08, /* Internal: Only valid with DCS_CACHED_PATH */
166 DCS_STORAGE_PATH = 0x0c, /* Read-through if needed for provided path */
167 DCS_UPDATE_FILEREF = 0x10, /* If fileref is not valid but path is found or
168 searching a path, update the reference
169 information */
170};
171
172int dircache_search(unsigned int flags, struct dircache_fileref *dcfrefp,
173 const char *path);
174
175int dircache_fileref_cmp(const struct dircache_fileref *dcfrefp1,
176 const struct dircache_fileref *dcfrefp2);
177
178
179/** Debug screen/info stuff **/
180
181struct dircache_info
182{
183 enum dircache_status status; /* current composite status value */
184 const char *statusdesc; /* pointer to string describing 'status' */
185 size_t last_size; /* cache size after last build */
186 size_t size; /* total size of entries (with holes) */
187 size_t sizeused; /* bytes of 'size' actually utilized */
188 size_t size_limit; /* maximum possible size */
189 size_t reserve; /* size of reserve area */
190 size_t reserve_used; /* amount of reserve used */
191 unsigned int entry_count; /* number of cache entries */
192 long build_ticks; /* total time used to build cache */
193};
194
195void dircache_get_info(struct dircache_info *info);
196#ifdef DIRCACHE_DUMPSTER
197void dircache_dump(void);
198#endif /* DIRCACHE_DUMPSTER */
199
200
201/** Misc. stuff **/
202void dircache_dcfile_init(struct dircache_file *dcfilep);
203
204#ifdef HAVE_EEPROM_SETTINGS
205int dircache_load(void);
206int dircache_save(void);
207#endif /* HAVE_EEPROM_SETTINGS */
208
209void dircache_init(size_t last_size) INIT_ATTR;
210
211#else /* !HAVE_DIRCACHE */
212
213#define IF_DIRCACHE(...)
214#define IFN_DIRCACHE(...) __VA_ARGS__
215
216#endif /* HAVE_DIRCACHE */
217
218#endif /* _DIRCACHE_H */