A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 218 lines 7.9 kB view raw
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 */