|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "info_key.h"
#include <stdio.h>
#include <string.h>
#include "tier1/strtools.h"
#define MAX_KV_LEN 127
/*
=============== Info_ValueForKey
Searches the string for the given key and returns the associated value, or an empty string. =============== */ const char *Info_ValueForKey ( const char *s, const char *key ) { char pkey[512]; static char value[4][512]; // use two buffers so compares
// work without stomping on each other
static int valueindex; char *o; valueindex = (valueindex + 1) % 4; if (*s == '\\') s++; while (1) { o = pkey; while (*s != '\\') { if (!*s) return ""; *o++ = *s++; } *o = 0; s++;
o = value[valueindex];
while (*s != '\\' && *s) { if (!*s) return ""; *o++ = *s++; } *o = 0;
if (!stricmp(key, pkey) ) return value[valueindex];
if (!*s) return ""; s++; } }
void Info_RemoveKey ( char *s, const char *key ) { char *start; char pkey[512]; char value[512]; char *o;
if (strstr (key, "\\")) { return; }
while (1) { start = s; if (*s == '\\') s++; o = pkey; while (*s != '\\') { if (!*s) return; *o++ = *s++; } *o = 0; s++;
o = value; while (*s != '\\' && *s) { if (!*s) return; *o++ = *s++; } *o = 0;
if (!stricmp (key, pkey) ) { // This is safe because we're copying within the same string
Q_strcpy (start, s); // remove this part
return; }
if (!*s) return; }
}
void Info_RemovePrefixedKeys (char *start, char prefix) { char *s; char pkey[512]; char value[512]; char *o;
s = start;
while (1) { if (*s == '\\') s++; o = pkey; while (*s != '\\') { if (!*s) return; *o++ = *s++; } *o = 0; s++;
o = value; while (*s != '\\' && *s) { if (!*s) return; *o++ = *s++; } *o = 0;
if (pkey[0] == prefix) { Info_RemoveKey (start, pkey); s = start; }
if (!*s) return; } }
bool Info_IsKeyImportant( const char *key ) { if ( key[0] == '*' ) return true; if ( !stricmp( key, "tracker" ) ) return true;
return false; }
char *Info_FindLargestKey( char *s, int maxsize ) { char key[256]; char value[256]; char *o; int l; static char largest_key[256]; int largest_size = 0;
*largest_key = 0;
if (*s == '\\') s++; while (*s) { int size = 0;
o = key; while (*s && *s != '\\') *o++ = *s++;
l = o - key; *o = 0; size = strlen( key );
if (!*s) { return largest_key; }
o = value; s++; while (*s && *s != '\\') *o++ = *s++; *o = 0;
if (*s) s++;
size += strlen( value );
if ( (size > largest_size) && !Info_IsKeyImportant(key) ) { largest_size = size; Q_strncpy( largest_key, key, sizeof( largest_key ) ); } }
return largest_key; }
void Info_SetValueForStarKey ( char *s, const char *key, const char *value, int maxsize ) { char news[1024], *v; int c;
if (strstr (key, "\\") || strstr (value, "\\") ) { return; }
if (strstr (key, "..") || strstr (value, "..") ) { // Con_Printf ("Can't use keys or values with a ..\n");
return; }
if (strstr (key, "\"") || strstr (value, "\"") ) { return; }
if (strlen(key) > MAX_KV_LEN || strlen(value) > MAX_KV_LEN) { return; } Info_RemoveKey (s, key); if (!value || !strlen(value)) return;
Q_snprintf (news, sizeof( news ), "\\%s\\%s", key, value);
if ( (int)(strlen(news) + strlen(s)) >= maxsize) { // no more room in buffer to add key/value
if ( Info_IsKeyImportant( key ) ) { // keep removing the largest key/values until we have room
char *largekey; do { largekey = Info_FindLargestKey( s, maxsize ); Info_RemoveKey( s, largekey ); } while ( ((int)(strlen(news) + strlen(s)) >= maxsize) && *largekey != 0 );
if ( largekey[0] == 0 ) { // no room to add setting
return; } } else { // no room to add setting
return; } }
// only copy ascii values
s += strlen(s); v = news; while (*v) { c = (unsigned char)*v++;
// Strip out high ascii characters
c &= 127;
if (c > 13) { *s++ = c; } } *s = 0; }
void Info_SetValueForKey (char *s, const char *key, const char *value, int maxsize) { if (key[0] == '*') { return; }
Info_SetValueForStarKey (s, key, value, maxsize); }
|