1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - util.h *
3 * Mupen64Plus homepage: https://mupen64plus.org/ *
4 * Copyright (C) 2012 CasualJames *
5 * Copyright (C) 2002 Hacktarux *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22
23#ifndef __UTIL_H__
24#define __UTIL_H__
25
26#include <stddef.h>
27#include <stdint.h>
28#include <string.h>
29
30#include "osal/preproc.h"
31
32#if defined(__GNUC__)
33#define ATTR_FMT(fmtpos, attrpos) __attribute__ ((format (printf, fmtpos, attrpos)))
34#else
35#define ATTR_FMT(fmtpos, attrpos)
36#endif
37
38/**********************
39 File utilities
40 **********************/
41
42typedef enum _file_status
43{
44 file_ok,
45 file_open_error,
46 file_read_error,
47 file_write_error,
48 file_size_error
49} file_status_t;
50
51/** read_from_file
52 * opens a file and reads the specified number of bytes.
53 * returns zero on success, nonzero on failure
54 */
55file_status_t read_from_file(const char *filename, void *data, size_t size);
56
57/** write_to_file
58 * opens a file and writes the specified number of bytes.
59 * returns zero on success, nonzero on failure
60 */
61file_status_t write_to_file(const char *filename, const void *data, size_t size);
62
63/** load_file
64 * load the file content into a newly allocated buffer.
65 * returns zero on success, nonzero on failure
66 */
67file_status_t load_file(const char* filename, void** buffer, size_t* size);
68
69/**********************
70 Byte swap utilities
71 **********************/
72#ifdef _MSC_VER
73#include <stdlib.h>
74#endif
75
76/* GCC has also byte swap intrinsics (__builtin_bswap32, etc.), but they were
77 * added in relatively recent versions. In addition, GCC can detect the byte
78 * swap code and optimize it with a high enough optimization level. */
79
80static osal_inline unsigned short m64p_swap16(unsigned short x)
81{
82 #ifdef _MSC_VER
83 return _byteswap_ushort(x);
84 #else
85 return ((x & 0x00FF) << 8) |
86 ((x & 0xFF00) >> 8);
87 #endif
88}
89
90static osal_inline unsigned int m64p_swap32(unsigned int x)
91{
92 #ifdef _MSC_VER
93 return _byteswap_ulong(x); // long is always 32-bit in Windows
94 #else
95 return ((x & 0x000000FF) << 24) |
96 ((x & 0x0000FF00) << 8) |
97 ((x & 0x00FF0000) >> 8) |
98 ((x & 0xFF000000) >> 24);
99 #endif
100}
101
102static osal_inline unsigned long long int m64p_swap64(unsigned long long int x)
103{
104 #ifdef _MSC_VER
105 return _byteswap_uint64(x);
106 #else
107 return ((x & 0x00000000000000FFULL) << 56) |
108 ((x & 0x000000000000FF00ULL) << 40) |
109 ((x & 0x0000000000FF0000ULL) << 24) |
110 ((x & 0x00000000FF000000ULL) << 8) |
111 ((x & 0x000000FF00000000ULL) >> 8) |
112 ((x & 0x0000FF0000000000ULL) >> 24) |
113 ((x & 0x00FF000000000000ULL) >> 40) |
114 ((x & 0xFF00000000000000ULL) >> 56);
115 #endif
116}
117
118#ifdef M64P_BIG_ENDIAN
119#define big16(x) (x)
120#define big32(x) (x)
121#define big64(x) (x)
122#define little16(x) m64p_swap16(x)
123#define little32(x) m64p_swap32(x)
124#define little64(x) m64p_swap64(x)
125#else
126#define big16(x) m64p_swap16(x)
127#define big32(x) m64p_swap32(x)
128#define big64(x) m64p_swap64(x)
129#define little16(x) (x)
130#define little32(x) (x)
131#define little64(x) (x)
132#endif
133
134/* Byte swaps, converts to little endian or converts to big endian a buffer,
135 * containing 'count' elements, each of size 'length'. */
136void swap_buffer(void *buffer, size_t length, size_t count);
137void to_little_endian_buffer(void *buffer, size_t length, size_t count);
138void to_big_endian_buffer(void *buffer, size_t length, size_t count);
139
140/**********************
141 GUI utilities
142 **********************/
143void countrycodestring(uint16_t countrycode, char *string);
144void imagestring(unsigned char imagetype, char *string);
145
146/**********************
147 Path utilities
148 **********************/
149
150/* Extracts the full file name (with extension) from a path string.
151 * Returns the same string, advanced until the file name. */
152const char* namefrompath(const char* path);
153
154/* Creates a path string by joining two path strings.
155 * The given path strings may or may not start or end with a path separator.
156 * Returns a malloc'd string with the resulting path. */
157char* combinepath(const char* first, const char *second);
158
159/**********************
160 String utilities
161 **********************/
162
163/** trim
164 * Removes leading and trailing whitespace from str. Function modifies str
165 * and also returns modified string.
166 */
167char *trim(char *str);
168
169/* Converts an string to an integer.
170 * Returns 1 on success, 0 on failure. 'result' is undefined on failure.
171 *
172 * The following conditions cause this function to fail:
173 * - Empty string
174 * - Leading characters (including whitespace)
175 * - Trailing characters (including whitespace)
176 * - Overflow or underflow.
177 */
178int string_to_int(const char *str, int *result);
179
180/* Converts an string of hexadecimal characters to a byte array.
181 * 'output_size' is the number of bytes (hex digraphs) to convert.
182 * Returns 1 on success, 0 on failure. 'output' is undefined on failure. */
183int parse_hex(const char *str, unsigned char *output, size_t output_size);
184
185/* Formats an string, using the same syntax as printf.
186 * Returns the result in a malloc'd string. */
187char* formatstr(const char* fmt, ...) ATTR_FMT(1, 2);
188
189typedef enum _ini_line_type
190{
191 INI_BLANK,
192 INI_COMMENT,
193 INI_SECTION,
194 INI_PROPERTY,
195 INI_TRASH
196} ini_line_type;
197
198typedef struct _ini_line
199{
200 ini_line_type type;
201 char *name;
202 char *value;
203} ini_line;
204
205/* Parses the INI file line pointer by 'lineptr'.
206 * The first line pointed by 'lineptr' may be modifed.
207 * 'lineptr' will point to the next line after this function runs.
208 *
209 * Returns a ini_line structure with information about the line.
210 * For INI_COMMENT, the value field contains the comment.
211 * For INI_SECTION, the name field contains the section name.
212 * For INI_PROPERTY, the name and value fields contain the property parameters.
213 * The line type is INI_BLANK if the line is blank or invalid.
214 *
215 * The name and value fields (if any) of ini_line point to 'lineptr'
216 * (so their lifetime is associated to that of 'lineptr').
217 */
218ini_line ini_parse_line(char **lineptr);
219
220#endif // __UTIL_H__
221
222