]> git.xonotic.org Git - xonotic/netradiant.git/blob - libs/profile/profile.cpp
gcc: appease the hardening warnings
[xonotic/netradiant.git] / libs / profile / profile.cpp
1 /*
2    Copyright (c) 2001, Loki software, inc.
3    All rights reserved.
4
5    Redistribution and use in source and binary forms, with or without modification,
6    are permitted provided that the following conditions are met:
7
8    Redistributions of source code must retain the above copyright notice, this list
9    of conditions and the following disclaimer.
10
11    Redistributions in binary form must reproduce the above copyright notice, this
12    list of conditions and the following disclaimer in the documentation and/or
13    other materials provided with the distribution.
14
15    Neither the name of Loki software nor the names of its contributors may be used
16    to endorse or promote products derived from this software without specific prior
17    written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
20    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22    DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
23    DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 //
32 // Application settings load/save
33 //
34 // Leonardo Zide (leo@lokigames.com)
35 //
36
37 #include "profile.h"
38
39 #include <string.h>
40 #include <stdio.h>
41 #include <math.h>
42
43 #include "file.h"
44
45 #include <stdlib.h>
46 #include <cassert>
47
48 #include "str.h"
49
50
51 // =============================================================================
52 // Static functions
53
54 bool read_var( const char *filename, const char *section, const char *key, char *value ){
55         char line[1024], *ptr;
56         FILE *rc;
57
58         rc = fopen( filename, "rt" );
59
60         if ( rc == NULL ) {
61                 return false;
62         }
63
64         while ( fgets( line, 1024, rc ) != 0 )
65         {
66                 // First we find the section
67                 if ( line[0] != '[' ) {
68                         continue;
69                 }
70
71                 ptr = strchr( line, ']' );
72                 *ptr = '\0';
73
74                 if ( strcmp( &line[1], section ) == 0 ) {
75                         while ( fgets( line, 1024, rc ) != 0 )
76                         {
77                                 ptr = strchr( line, '=' );
78
79                                 if ( ptr == NULL ) {
80                                         // reached the end of the section
81                                         fclose( rc );
82                                         return false;
83                                 }
84                                 *ptr = '\0';
85
86                                 // remove spaces
87                                 while ( line[strlen( line ) - 1] == ' ' )
88                                         line[strlen( line ) - 1] = '\0';
89
90                                 if ( strcmp( line, key ) == 0 ) {
91                                         strcpy( value, ptr + 1 );
92                                         fclose( rc );
93
94                                         if ( value[strlen( value ) - 1] == 10 || value[strlen( value ) - 1] == 13 || value[strlen( value ) - 1] == 32 ) {
95                                                 value[strlen( value ) - 1] = 0;
96                                         }
97
98                                         return true;
99                                 }
100                         }
101                 }
102         }
103
104         fclose( rc );
105         return false;
106 }
107
108 bool save_var( const char *filename, const char *section, const char *key, const char *value ){
109         char line[1024], *ptr;
110         MemStream old_rc;
111         bool found;
112         FILE *rc;
113
114         rc = fopen( filename, "rb" );
115
116         if ( rc != NULL ) {
117                 unsigned int len;
118                 void *buf;
119
120                 fseek( rc, 0, SEEK_END );
121                 len = ftell( rc );
122                 rewind( rc );
123                 buf = malloc( len );
124         assert(fread( buf, len, 1, rc ));
125                 old_rc.write( reinterpret_cast<MemStream::byte_type*>( buf ), len );
126                 free( buf );
127                 fclose( rc );
128                 old_rc.Seek( 0, SEEK_SET );
129         }
130
131         // TTimo: changed to binary writing. It doesn't seem to affect linux version, and win32 version was happending a lot of '\n'
132         rc = fopen( filename, "wb" );
133
134         if ( rc == NULL ) {
135                 return false;
136         }
137
138         // First we need to find the section
139         found = false;
140         while ( old_rc.ReadString( line, 1024 ) != NULL )
141         {
142                 fputs( line, rc );
143
144                 if ( line[0] == '[' ) {
145                         ptr = strchr( line, ']' );
146                         *ptr = '\0';
147
148                         if ( strcmp( &line[1], section ) == 0 ) {
149                                 found = true;
150                                 break;
151                         }
152                 }
153         }
154
155         if ( !found ) {
156                 fputs( "\n", rc );
157                 fprintf( rc, "[%s]\n", section );
158         }
159
160         fprintf( rc, "%s=%s\n", key, value );
161
162         while ( old_rc.ReadString( line, 1024 ) != NULL )
163         {
164                 ptr = strchr( line, '=' );
165
166                 if ( ptr != NULL ) {
167                         *ptr = '\0';
168
169                         if ( strcmp( line, key ) == 0 ) {
170                                 break;
171                         }
172
173                         *ptr = '=';
174                         fputs( line, rc );
175                 }
176                 else
177                 {
178                         fputs( line, rc );
179                         break;
180                 }
181         }
182
183         while ( old_rc.ReadString( line, 1024 ) != NULL )
184                 fputs( line, rc );
185
186         fclose( rc );
187         return true;
188 }
189
190 // =============================================================================
191 // Global functions
192
193 bool profile_save_int( const char *filename, const char *section, const char *key, int value ){
194         char buf[16];
195         sprintf( buf, "%d", value );
196         return save_var( filename, section, key, buf );
197 }
198
199 bool profile_save_float( const char *filename, const char *section, const char *key, float value ){
200         char buf[16];
201         sprintf( buf, "%f", value );
202         return save_var( filename, section, key, buf );
203 }
204
205 bool profile_save_string( const char * filename, const char *section, const char *key, const char *value ){
206         return save_var( filename, section, key, value );
207 }
208
209 bool profile_save_buffer( const char * rc_path, const char *name, void *buffer, unsigned int size ){
210         bool ret = false;
211         char filename[1024];
212         sprintf( filename, "%s/%s.bin", rc_path, name );
213         FILE *f;
214
215         f = fopen( filename, "wb" );
216
217         if ( f != NULL ) {
218                 if ( fwrite( buffer, size, 1, f ) == 1 ) {
219                         ret = true;
220                 }
221
222                 fclose( f );
223         }
224
225         return ret;
226 }
227
228 bool profile_load_buffer( const char * rc_path, const char *name, void *buffer, unsigned int *plSize ){
229         char filename[1024];
230         sprintf( filename, "%s/%s.bin", rc_path, name );
231         bool ret = false;
232         unsigned int len;
233         FILE *f;
234
235         f = fopen( filename, "rb" );
236
237         if ( f != NULL ) {
238                 fseek( f, 0, SEEK_END );
239                 len = ftell( f );
240                 rewind( f );
241
242                 if ( len > *plSize ) {
243                         len = *plSize;
244                 }
245                 else{
246                         *plSize = len;
247                 }
248
249                 if ( fread( buffer, len, 1, f ) == 1 ) {
250                         ret = true;
251                 }
252
253                 fclose( f );
254         }
255
256         return ret;
257 }
258
259 int profile_load_int( const char *filename, const char *section, const char *key, int default_value ){
260         char value[1024];
261
262         if ( read_var( filename, section, key, value ) ) {
263                 return atoi( value );
264         }
265         else{
266                 return default_value;
267         }
268 }
269
270 float profile_load_float( const char *filename, const char *section, const char *key, float default_value ){
271         char value[1024];
272
273         if ( read_var( filename, section, key, value ) ) {
274                 return static_cast<float>( atof( value ) );
275         }
276         else{
277                 return default_value;
278         }
279 }
280
281 char* profile_load_string( const char *filename, const char *section, const char *key, const char *default_value ){
282         static Str ret;
283         char value[1024];
284
285         if ( read_var( filename, section, key, value ) ) {
286                 ret = value;
287         }
288         else{
289                 ret = default_value;
290         }
291
292         return (char*)ret.GetBuffer();
293 }