UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
infostring.cpp
Go to the documentation of this file.
1 
6 /*
7 All original material Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 Copyright (C) 1997-2001 Id Software, Inc.
10 
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 See the GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 
26 */
27 
28 #include "infostring.h"
29 #include "../common/common.h"
30 
39 const char* Info_ValueForKey (const char* s, const char* key)
40 {
41  char pkey[512];
42  /* use two buffers so compares */
43  static char value[2][512] = {"", ""};
44 
45  /* work without stomping on each other */
46  static int valueindex = 0;
47 
48  valueindex ^= 1;
49  if (*s == '\\' && *s != '\n')
50  s++;
51  while (1) {
52  char* o = pkey;
53  while (*s != '\\' && *s != '\n') {
54  if (!*s)
55  return "";
56  *o++ = *s++;
57  }
58  *o = '\0';
59  s++;
60 
61  o = value[valueindex];
62 
63  while (*s != '\\' && *s != '\n' && *s)
64  *o++ = *s++;
65  *o = '\0';
66 
67  if (!Q_strcasecmp(key, pkey))
68  return value[valueindex];
69 
70  if (!*s)
71  return "";
72  s++;
73  }
74 }
75 
76 const char* Info_BoolForKey (const char* s, const char* key)
77 {
78  const char* boolStr = Info_ValueForKey(s, key);
79  if (boolStr[0] == '0' || boolStr[0] == '\0' || Q_streq(boolStr, "No"))
80  return "No";
81  return "Yes";
82 }
83 
84 int Info_IntegerForKey (const char* s, const char* key)
85 {
86  return atoi(Info_ValueForKey(s, key));
87 }
88 
95 void Info_RemoveKey (char* s, const char* key)
96 {
97  char pkey[512];
98  char value[512];
99 
100  if (strstr(key, "\\")) {
101 /* Com_Printf("Can't use a key with a \\\n"); */
102  return;
103  }
104 
105  while (1) {
106  char* start = s;
107  if (*s == '\\')
108  s++;
109  char* o = pkey;
110  while (*s != '\\') {
111  if (!*s)
112  return;
113  *o++ = *s++;
114  }
115  *o = 0;
116  s++;
117 
118  o = value;
119  while (*s != '\\' && *s) {
120  if (!*s)
121  return;
122  *o++ = *s++;
123  }
124  *o = 0;
125 
126  if (!strncmp(key, pkey, sizeof(pkey))) {
127  const size_t size = strlen(s);
128  memmove(start, s, size);
129  start[size] = 0;
130  return;
131  }
132 
133  if (!*s)
134  return;
135  }
136 }
137 
138 
142 bool Info_Validate (const char* s)
143 {
144  if (strstr(s, "\""))
145  return false;
146  if (strstr(s, ";"))
147  return false;
148  return true;
149 }
150 
154 void Info_SetValueForKeyAsInteger (char* s, const size_t size, const char* key, const int value)
155 {
156  Info_SetValueForKey(s, size, key, va("%i", value));
157 }
158 
169 void Info_SetValueForKey (char* s, const size_t size, const char* key, const char* value)
170 {
171  char newi[MAX_INFO_STRING];
172 
173  if (strstr(key, "\\") || strstr(value, "\\")) {
174  Com_Printf("Can't use keys or values with a \\\n");
175  return;
176  }
177 
178  if (strstr(key, ";")) {
179  Com_Printf("Can't use keys or values with a semicolon\n");
180  return;
181  }
182 
183  if (strstr(key, "\"") || strstr(value, "\"")) {
184  Com_Printf("Can't use keys or values with a \"\n");
185  return;
186  }
187 
188  if (strlen(key) > MAX_INFO_KEY - 1) {
189  Com_Printf("Keys must be < " DOUBLEQUOTE(MAX_INFO_KEY) " characters.\n");
190  return;
191  }
192 
193  if (strlen(key) > MAX_INFO_VALUE - 1) {
194  Com_Printf("Values must be < " DOUBLEQUOTE(MAX_INFO_VALUE) " characters.\n");
195  return;
196  }
197 
198  Info_RemoveKey(s, key);
199  if (Q_strnull(value))
200  return;
201 
202  Com_sprintf(newi, sizeof(newi), "\\%s\\%s%s", key, value, s);
203  Q_strncpyz(s, newi, size);
204 }
205 
209 void Info_Print (const char* s)
210 {
211  if (*s == '\\')
212  s++;
213  while (*s) {
214  char const* key;
215  int key_len = 0;
216  char const* value;
217  int value_len = 0;
218 
219  key = s;
220  while (*s && *s != '\\') {
221  ++s;
222  ++key_len;
223  }
224 
225  if (!*s) {
226  Com_Printf("%-40.*sMISSING VALUE\n", key_len, key);
227  return;
228  }
229 
230  value = ++s;
231  while (*s && *s != '\\') {
232  ++s;
233  ++value_len;
234  }
235 
236  if (*s)
237  s++;
238 
239  Com_Printf("%-40.*s%.*s\n", key_len, key, value_len, value);
240  }
241 }
bool Q_strnull(const char *string)
Definition: shared.h:138
void Info_SetValueForKeyAsInteger(char *s, const size_t size, const char *key, const int value)
Definition: infostring.cpp:154
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition: shared.cpp:410
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
Info string handling.
const char * Info_ValueForKey(const char *s, const char *key)
Searches the string for the given key and returns the associated value, or an empty string...
Definition: infostring.cpp:39
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
unsigned int key
Definition: cl_input.cpp:68
#define MAX_INFO_STRING
Definition: infostring.h:36
GLsizei size
Definition: r_gl.h:152
bool Info_Validate(const char *s)
Some characters are illegal in info strings because they can mess up the server's parsing...
Definition: infostring.cpp:142
#define MAX_INFO_KEY
Definition: infostring.h:34
#define Q_strcasecmp(a, b)
Definition: shared.h:131
void Info_SetValueForKey(char *s, const size_t size, const char *key, const char *value)
Adds a new entry into string with given value.
Definition: infostring.cpp:169
void Info_RemoveKey(char *s, const char *key)
Searches through s for key and remove is.
Definition: infostring.cpp:95
void Info_Print(const char *s)
Prints info strings (like userinfo or serverinfo - CVAR_USERINFO, CVAR_SERVERINFO) ...
Definition: infostring.cpp:209
#define Q_streq(a, b)
Definition: shared.h:136
#define MAX_INFO_VALUE
Definition: infostring.h:35
#define DOUBLEQUOTE(x)
Definition: shared.h:90
const char * Info_BoolForKey(const char *s, const char *key)
Definition: infostring.cpp:76
int Info_IntegerForKey(const char *s, const char *key)
Definition: infostring.cpp:84