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 Tomas Salfischberger
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "plugin.h"
23#include "lib/simple_viewer.h"
24
25
26
27#define MIN_DESC_BUF_SIZE 0x400 /* arbitrary minimum size for description */
28
29/* Some lenghts */
30#define WORDLEN 32 /* has to be the same in rdf2binary.c */
31
32/* Struct packing */
33#ifdef __GNUC__
34#define STRUCT_PACKED __attribute__((packed))
35#else
36#define STRUCT_PACKED
37#pragma pack (push, 2)
38#endif
39
40/* The word struct :) */
41struct stWord
42{
43 char word[WORDLEN];
44 long offset;
45} STRUCT_PACKED;
46
47/* for endian problems */
48#ifdef ROCKBOX_BIG_ENDIAN
49#define reverse(x) x
50#else
51static long reverse (long N) {
52 unsigned char B[4];
53 B[0] = (N & 0x000000FF) >> 0;
54 B[1] = (N & 0x0000FF00) >> 8;
55 B[2] = (N & 0x00FF0000) >> 16;
56 B[3] = (N & 0xFF000000) >> 24;
57 return ((B[0] << 24) | (B[1] << 16) | (B[2] << 8) | (B[3] << 0));
58}
59#endif
60
61
62/* data files */
63#define DICT_INDEX PLUGIN_APPS_DIR "/dict.index"
64#define DICT_DESC PLUGIN_APPS_DIR "/dict.desc"
65
66/* the main plugin function */
67enum plugin_status plugin_start(const void* parameter)
68{
69 char searchword[WORDLEN]; /* word to search for */
70 char *description; /* pointer to description buffer */
71 struct stWord word; /* the struct to read into */
72 int fIndex, fData; /* files */
73 int filesize, high, low, probe;
74 char *buffer;
75 size_t buffer_size;
76
77 /* plugin stuff */
78 (void)parameter;
79
80 /* allocate buffer. */
81 buffer = rb->plugin_get_buffer(&buffer_size);
82 if (buffer == NULL || buffer_size < MIN_DESC_BUF_SIZE)
83 {
84 DEBUGF("Err: Failed to allocate buffer.\n");
85 rb->splash(HZ*2, "Failed to allocate buffer.");
86 return PLUGIN_ERROR;
87 }
88
89 description = buffer;
90
91 /* "clear" input buffer */
92 searchword[0] = '\0';
93
94 /* get the word to search */
95 if (rb->kbd_input(searchword, sizeof(searchword), NULL) < 0)
96 return PLUGIN_OK; /* input cancelled */
97
98 fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */
99 if (fIndex < 0)
100 {
101 DEBUGF("Err: Failed to open index file.\n");
102 rb->splash(HZ*2, "Failed to open index.");
103 return PLUGIN_ERROR;
104 }
105
106 filesize = rb->filesize(fIndex); /* get filesize */
107
108 DEBUGF("Filesize: %d bytes = %d words \n", filesize,
109 (filesize / (int)sizeof(struct stWord)));
110
111 /* for the searching algorithm */
112 high = filesize / sizeof( struct stWord );
113 low = -1;
114
115 while (high - low > 1)
116 {
117 probe = (high + low) / 2;
118
119 /* Jump to word pointed by probe, and read it. */
120 rb->lseek(fIndex, sizeof(struct stWord) * probe, SEEK_SET);
121 rb->read(fIndex, &word, sizeof(struct stWord));
122
123 /* jump according to the found word. */
124 if (rb->strcasecmp(searchword, word.word) < 0)
125 {
126 high = probe;
127 }
128 else
129 {
130 low = probe;
131 }
132 }
133
134 /* read in the word */
135 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
136 rb->read(fIndex, &word, sizeof(struct stWord));
137 rb->close(fIndex);
138
139 /* Check if we found something */
140 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
141 {
142 DEBUGF("Not found.\n");
143 rb->splash(HZ*2, "Not found.");
144 return PLUGIN_OK;
145 }
146
147 DEBUGF("Found %s at offset %ld\n", word.word, reverse(word.offset));
148
149 /* now open the description file */
150 fData = rb->open(DICT_DESC, O_RDONLY);
151 if (fData < 0)
152 {
153 DEBUGF("Err: Failed to open description file.\n");
154 rb->splash(HZ*2, "Failed to open descriptions.");
155 return PLUGIN_ERROR;
156 }
157
158 /* seek to the right offset */
159 rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET);
160
161 /* Read in the description */
162 rb->read_line(fData, description, buffer_size);
163
164 /* And print it to debug. */
165 DEBUGF("Description: %s\n", description);
166
167 rb->close(fData);
168
169 /* display description. */
170 view_text(searchword, description);
171
172 return PLUGIN_OK;
173}