Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
4.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "info_key.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "tier1/strtools.h"
  11. #define MAX_KV_LEN 127
  12. /*
  13. ===============
  14. Info_ValueForKey
  15. Searches the string for the given
  16. key and returns the associated value, or an empty string.
  17. ===============
  18. */
  19. const char *Info_ValueForKey ( const char *s, const char *key )
  20. {
  21. char pkey[512];
  22. static char value[4][512]; // use two buffers so compares
  23. // work without stomping on each other
  24. static int valueindex;
  25. char *o;
  26. valueindex = (valueindex + 1) % 4;
  27. if (*s == '\\')
  28. s++;
  29. while (1)
  30. {
  31. o = pkey;
  32. while (*s != '\\')
  33. {
  34. if (!*s)
  35. return "";
  36. *o++ = *s++;
  37. }
  38. *o = 0;
  39. s++;
  40. o = value[valueindex];
  41. while (*s != '\\' && *s)
  42. {
  43. if (!*s)
  44. return "";
  45. *o++ = *s++;
  46. }
  47. *o = 0;
  48. if (!stricmp(key, pkey) )
  49. return value[valueindex];
  50. if (!*s)
  51. return "";
  52. s++;
  53. }
  54. }
  55. void Info_RemoveKey ( char *s, const char *key )
  56. {
  57. char *start;
  58. char pkey[512];
  59. char value[512];
  60. char *o;
  61. if (strstr (key, "\\"))
  62. {
  63. return;
  64. }
  65. while (1)
  66. {
  67. start = s;
  68. if (*s == '\\')
  69. s++;
  70. o = pkey;
  71. while (*s != '\\')
  72. {
  73. if (!*s)
  74. return;
  75. *o++ = *s++;
  76. }
  77. *o = 0;
  78. s++;
  79. o = value;
  80. while (*s != '\\' && *s)
  81. {
  82. if (!*s)
  83. return;
  84. *o++ = *s++;
  85. }
  86. *o = 0;
  87. if (!stricmp (key, pkey) )
  88. {
  89. // This is safe because we're copying within the same string
  90. Q_strcpy (start, s); // remove this part
  91. return;
  92. }
  93. if (!*s)
  94. return;
  95. }
  96. }
  97. void Info_RemovePrefixedKeys (char *start, char prefix)
  98. {
  99. char *s;
  100. char pkey[512];
  101. char value[512];
  102. char *o;
  103. s = start;
  104. while (1)
  105. {
  106. if (*s == '\\')
  107. s++;
  108. o = pkey;
  109. while (*s != '\\')
  110. {
  111. if (!*s)
  112. return;
  113. *o++ = *s++;
  114. }
  115. *o = 0;
  116. s++;
  117. o = value;
  118. while (*s != '\\' && *s)
  119. {
  120. if (!*s)
  121. return;
  122. *o++ = *s++;
  123. }
  124. *o = 0;
  125. if (pkey[0] == prefix)
  126. {
  127. Info_RemoveKey (start, pkey);
  128. s = start;
  129. }
  130. if (!*s)
  131. return;
  132. }
  133. }
  134. bool Info_IsKeyImportant( const char *key )
  135. {
  136. if ( key[0] == '*' )
  137. return true;
  138. if ( !stricmp( key, "tracker" ) )
  139. return true;
  140. return false;
  141. }
  142. char *Info_FindLargestKey( char *s, int maxsize )
  143. {
  144. char key[256];
  145. char value[256];
  146. char *o;
  147. int l;
  148. static char largest_key[256];
  149. int largest_size = 0;
  150. *largest_key = 0;
  151. if (*s == '\\')
  152. s++;
  153. while (*s)
  154. {
  155. int size = 0;
  156. o = key;
  157. while (*s && *s != '\\')
  158. *o++ = *s++;
  159. l = o - key;
  160. *o = 0;
  161. size = strlen( key );
  162. if (!*s)
  163. {
  164. return largest_key;
  165. }
  166. o = value;
  167. s++;
  168. while (*s && *s != '\\')
  169. *o++ = *s++;
  170. *o = 0;
  171. if (*s)
  172. s++;
  173. size += strlen( value );
  174. if ( (size > largest_size) && !Info_IsKeyImportant(key) )
  175. {
  176. largest_size = size;
  177. Q_strncpy( largest_key, key, sizeof( largest_key ) );
  178. }
  179. }
  180. return largest_key;
  181. }
  182. void Info_SetValueForStarKey ( char *s, const char *key, const char *value, int maxsize )
  183. {
  184. char news[1024], *v;
  185. int c;
  186. if (strstr (key, "\\") || strstr (value, "\\") )
  187. {
  188. return;
  189. }
  190. if (strstr (key, "..") || strstr (value, "..") )
  191. {
  192. // Con_Printf ("Can't use keys or values with a ..\n");
  193. return;
  194. }
  195. if (strstr (key, "\"") || strstr (value, "\"") )
  196. {
  197. return;
  198. }
  199. if (strlen(key) > MAX_KV_LEN || strlen(value) > MAX_KV_LEN)
  200. {
  201. return;
  202. }
  203. Info_RemoveKey (s, key);
  204. if (!value || !strlen(value))
  205. return;
  206. Q_snprintf (news, sizeof( news ), "\\%s\\%s", key, value);
  207. if ( (int)(strlen(news) + strlen(s)) >= maxsize)
  208. {
  209. // no more room in buffer to add key/value
  210. if ( Info_IsKeyImportant( key ) )
  211. {
  212. // keep removing the largest key/values until we have room
  213. char *largekey;
  214. do {
  215. largekey = Info_FindLargestKey( s, maxsize );
  216. Info_RemoveKey( s, largekey );
  217. } while ( ((int)(strlen(news) + strlen(s)) >= maxsize) && *largekey != 0 );
  218. if ( largekey[0] == 0 )
  219. {
  220. // no room to add setting
  221. return;
  222. }
  223. }
  224. else
  225. {
  226. // no room to add setting
  227. return;
  228. }
  229. }
  230. // only copy ascii values
  231. s += strlen(s);
  232. v = news;
  233. while (*v)
  234. {
  235. c = (unsigned char)*v++;
  236. // Strip out high ascii characters
  237. c &= 127;
  238. if (c > 13)
  239. {
  240. *s++ = c;
  241. }
  242. }
  243. *s = 0;
  244. }
  245. void Info_SetValueForKey (char *s, const char *key, const char *value, int maxsize)
  246. {
  247. if (key[0] == '*')
  248. {
  249. return;
  250. }
  251. Info_SetValueForStarKey (s, key, value, maxsize);
  252. }