A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 158 lines 5.3 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2002 Daniel Stenberg 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 <stdio.h> 23#include "file.h" 24 25#include "language.h" 26#include "lang.h" 27#include "debug.h" 28#include "string.h" 29#include "viewport.h" 30 31/* The following header is generated by the build system and only defines 32 MAX_LANGUAGE_SIZE to be the size of the largest currently available 33 language! */ 34#include "max_language_size.h" 35 36/* These defines must match the initial bytes in the binary lang file */ 37/* See tools/genlang (TODO: Use common include for both) */ 38#define LANGUAGE_COOKIE 0x1a 39#define LANGUAGE_VERSION 0x06 40 41#define LANGUAGE_FLAG_RTL 0x01 42#define LANGUAGE_FLAG_UNITS_FIRST 0x02 43 44#define HEADER_SIZE 4 45#define SUBHEADER_SIZE 6 46 47static unsigned char language_buffer[MAX_LANGUAGE_SIZE]; 48static unsigned char lang_options = 0; 49 50void lang_init(const unsigned char *builtin, unsigned char **dest, int count) 51{ 52 while(count--) { 53 *dest++ = (unsigned char *)builtin; 54 /* advance pointer to next string */ 55 builtin += strlen((char *)builtin) + 1; 56 } 57} 58 59int lang_load(const char *filename, const unsigned char *builtin, 60 unsigned char **dest, unsigned char *buffer, 61 unsigned int user_num, int max_lang_size, 62 unsigned int max_id) 63{ 64 int lang_size; 65 int fd = open(filename, O_RDONLY); 66 int retcode=0; 67 unsigned char lang_header[HEADER_SIZE]; 68 unsigned char sub_header[SUBHEADER_SIZE]; 69 unsigned int id, foffset; 70 71 if(fd < 0) 72 return 1; 73 74 if(read(fd, lang_header, HEADER_SIZE) == HEADER_SIZE && 75 ((lang_header[0] == LANGUAGE_COOKIE) && 76 (lang_header[1] == LANGUAGE_VERSION) && 77 (lang_header[2] == TARGET_ID))) { 78 /* jump to the proper entry in the table of subheaders */ 79 lseek(fd, user_num * SUBHEADER_SIZE, SEEK_CUR); 80 if (read(fd, sub_header, SUBHEADER_SIZE) != SUBHEADER_SIZE) 81 { 82 DEBUGF("Language %s bad subheader %u\n", filename, user_num); 83 retcode = 4; 84 } 85 /* read in information about the requested lang */ 86#if 0 /* unused */ 87 unsigned int num_strings = (sub_header[0]<<8) | sub_header[1]; 88#endif 89 lang_size = (sub_header[2]<<8) | sub_header[3]; 90 foffset = (sub_header[4]<<8) | sub_header[5]; 91 if(lang_size <= max_lang_size) { 92 /* initialize with builtin */ 93 lang_init(builtin, dest, max_id); 94 lseek(fd, foffset, SEEK_SET); 95 read(fd, buffer, lang_size); 96 buffer[max_lang_size - 1] = '\0'; /* ensure buffer is null terminated */ 97 while(lang_size>3) { 98 id = ((buffer[0]<<8) | buffer[1]); /* get two-byte id */ 99 buffer += 2; /* pass the id */ 100 if(id < max_id) { 101#if 0 102 DEBUGF("%2x New: %30s ", id, buffer); 103 DEBUGF("Replaces: %s\n", dest[id]); 104#endif 105 dest[id] = buffer; /* point to this string */ 106 } 107 while(*buffer) { /* pass the string */ 108 lang_size--; 109 buffer++; 110 } 111 lang_size-=3; /* the id and the terminating zero */ 112 buffer++; /* pass the terminating zero-byte */ 113 } 114 } 115 else { 116 DEBUGF("Language %s too large: %d\n", filename, lang_size); 117 retcode = 2; 118 } 119 } 120 else { 121 DEBUGF("Illegal language file\n"); 122 retcode = 3; 123 } 124 close(fd); 125 lang_options = retcode ? 0 : lang_header[3]; 126 return retcode; 127} 128 129int lang_core_load(const char *filename) 130{ 131 return lang_load(filename, core_language_builtin, language_strings, 132 language_buffer, 0, MAX_LANGUAGE_SIZE, 133 LANG_LAST_INDEX_IN_ARRAY); 134} 135 136int lang_english_to_id(const char *english) 137{ 138 int i; 139 unsigned char *ptr = (unsigned char *) core_language_builtin; 140 size_t ptrlen, len = strlen(english); 141 for (i = 0; i < LANG_LAST_INDEX_IN_ARRAY; i++) { 142 ptrlen = strlen((char *)ptr); 143 if ((ptrlen == len) && memcmp(ptr, english, ptrlen) == 0) 144 return i; 145 ptr += ptrlen + 1; /* advance pointer to next string */ 146 } 147 return -1; 148} 149 150int lang_is_rtl(void) 151{ 152 return (lang_options & LANGUAGE_FLAG_RTL) != 0; 153} 154 155int lang_units_first(void) 156{ 157 return (lang_options & LANGUAGE_FLAG_UNITS_FIRST) != 0; 158}