Import of GameData MD5 hashing app.
Import of GameData MD5 hashing app.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tools/gamedata md5/Makefile Sun Jun 29 22:23:14 2008 +0000
1.3 @@ -0,0 +1,74 @@
1.4 +# (C)2004-2008 SourceMod Development Team
1.5 +# Makefile written by David "BAILOPAN" Anderson
1.6 +
1.7 +
1.8 +#####################################
1.9 +### EDIT BELOW FOR OTHER PROJECTS ###
1.10 +#####################################
1.11 +
1.12 +OBJECTS = main.cpp TextParsers.cpp sm_memtable.cpp md5.cpp
1.13 +
1.14 +##############################################
1.15 +### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
1.16 +##############################################
1.17 +
1.18 +C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
1.19 +C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
1.20 +C_GCC4_FLAGS = -fvisibility=hidden
1.21 +CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
1.22 +CPP = gcc-4.1
1.23 +
1.24 +BINARY = gamedatamd5
1.25 +
1.26 +INCLUDE += -I. -I../../public -I../../public/sourcepawn
1.27 +
1.28 +CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
1.29 + -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
1.30 + -Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
1.31 +CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
1.32 +
1.33 +################################################
1.34 +### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
1.35 +################################################
1.36 +
1.37 +ifeq "$(DEBUG)" "true"
1.38 + BIN_DIR = Debug
1.39 + CFLAGS += $(C_DEBUG_FLAGS)
1.40 +else
1.41 + BIN_DIR = Release
1.42 + CFLAGS += $(C_OPT_FLAGS)
1.43 +endif
1.44 +
1.45 +GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
1.46 +ifeq "$(GCC_VERSION)" "4"
1.47 + CFLAGS += $(C_GCC4_FLAGS)
1.48 + CPPFLAGS += $(CPP_GCC4_FLAGS)
1.49 +endif
1.50 +
1.51 +OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
1.52 +OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
1.53 +OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
1.54 +
1.55 +$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
1.56 + $(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
1.57 +
1.58 +$(BIN_DIR)/%.o: %.cpp
1.59 + $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
1.60 +
1.61 +$(BIN_DIR)/%.o: %.c
1.62 + $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
1.63 +
1.64 +all:
1.65 + mkdir -p $(BIN_DIR)
1.66 + $(MAKE) -f Makefile sourcemod
1.67 +
1.68 +sourcemod: $(OBJ_LINUX)
1.69 + $(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -lstdc++ -o$(BIN_DIR)/$(BINARY)
1.70 +
1.71 +debug:
1.72 + $(MAKE) -f Makefile all DEBUG=true
1.73 +
1.74 +default: all
1.75 +
1.76 +clean:
1.77 + rm -rf $(BIN_DIR)/$(BINARY)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tools/gamedata md5/TextParsers.cpp Sun Jun 29 22:23:14 2008 +0000
2.3 @@ -0,0 +1,1082 @@
2.4 +/**
2.5 + * vim: set ts=4 :
2.6 + * =============================================================================
2.7 + * SourceMod
2.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
2.9 + * =============================================================================
2.10 + *
2.11 + * This program is free software; you can redistribute it and/or modify it under
2.12 + * the terms of the GNU General Public License, version 3.0, as published by the
2.13 + * Free Software Foundation.
2.14 + *
2.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
2.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2.18 + * details.
2.19 + *
2.20 + * You should have received a copy of the GNU General Public License along with
2.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
2.22 + *
2.23 + * As a special exception, AlliedModders LLC gives you permission to link the
2.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
2.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
2.26 + * by the Valve Corporation. You must obey the GNU General Public License in
2.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
2.28 + * this exception to all derivative works. AlliedModders LLC defines further
2.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
2.30 + * or <http://www.sourcemod.net/license.php>.
2.31 + *
2.32 + * Version: $Id$
2.33 + */
2.34 +
2.35 +#include <stdio.h>
2.36 +#include <ctype.h>
2.37 +#include <wctype.h>
2.38 +#include <string.h>
2.39 +#include <stdlib.h>
2.40 +#include <assert.h>
2.41 +#include "TextParsers.h"
2.42 +//#include "ShareSys.h"
2.43 +//#include "sm_stringutil.h"
2.44 +//#include "LibrarySys.h"
2.45 +
2.46 +TextParsers g_TextParser;
2.47 +ITextParsers *textparsers = &g_TextParser;
2.48 +
2.49 +static int g_ini_chartable1[255] = {0};
2.50 +static int g_ws_chartable[255] = {0};
2.51 +
2.52 +bool TextParsers::IsWhitespace(const char *stream)
2.53 +{
2.54 + return g_ws_chartable[(unsigned)*stream] == 1;
2.55 +}
2.56 +
2.57 +TextParsers::TextParsers()
2.58 +{
2.59 + g_ini_chartable1[(unsigned)'_'] = 1;
2.60 + g_ini_chartable1[(unsigned)'-'] = 1;
2.61 + g_ini_chartable1[(unsigned)','] = 1;
2.62 + g_ini_chartable1[(unsigned)'+'] = 1;
2.63 + g_ini_chartable1[(unsigned)'.'] = 1;
2.64 + g_ini_chartable1[(unsigned)'$'] = 1;
2.65 + g_ini_chartable1[(unsigned)'?'] = 1;
2.66 + g_ini_chartable1[(unsigned)'/'] = 1;
2.67 + g_ws_chartable[(unsigned)'\n'] = 1;
2.68 + g_ws_chartable[(unsigned)'\v'] = 1;
2.69 + g_ws_chartable[(unsigned)'\r'] = 1;
2.70 + g_ws_chartable[(unsigned)'\t'] = 1;
2.71 + g_ws_chartable[(unsigned)'\f'] = 1;
2.72 + g_ws_chartable[(unsigned)' '] = 1;
2.73 +}
2.74 +
2.75 +unsigned int TextParsers::GetUTF8CharBytes(const char *stream)
2.76 +{
2.77 + return _GetUTF8CharBytes(stream);
2.78 +}
2.79 +
2.80 +/**
2.81 + * Character streams
2.82 + */
2.83 +
2.84 +struct CharStream
2.85 +{
2.86 + const char *curpos;
2.87 +};
2.88 +
2.89 +bool CharStreamReader(void *stream, char *buffer, size_t maxlength, unsigned int *read)
2.90 +{
2.91 + CharStream *srdr = (CharStream *)stream;
2.92 +
2.93 + const char *ptr = srdr->curpos;
2.94 + for (size_t i=0; i<maxlength; i++)
2.95 + {
2.96 + if (*ptr == '\0')
2.97 + {
2.98 + break;
2.99 + }
2.100 + *buffer++ = *ptr++;
2.101 + }
2.102 +
2.103 + *read = ptr - srdr->curpos;
2.104 +
2.105 + srdr->curpos = ptr;
2.106 +
2.107 + return true;
2.108 +}
2.109 +
2.110 +SMCError TextParsers::ParseString_SMC(const char *stream,
2.111 + ITextListener_SMC *smc,
2.112 + SMCStates *states)
2.113 +{
2.114 + CharStream srdr = { stream };
2.115 +
2.116 + return ParseStream_SMC(&srdr, CharStreamReader, smc, states);
2.117 +}
2.118 +
2.119 +/**
2.120 + * File streams
2.121 + */
2.122 +
2.123 +bool FileStreamReader(void *stream, char *buffer, size_t maxlength, unsigned int *read)
2.124 +{
2.125 + size_t num = fread(buffer, 1, maxlength, (FILE *)stream);
2.126 +
2.127 + *read = static_cast<unsigned int>(num);
2.128 +
2.129 + if (num == 0 && feof((FILE *)stream))
2.130 + {
2.131 + return true;
2.132 + }
2.133 +
2.134 + return (ferror((FILE *)stream) == 0);
2.135 +}
2.136 +
2.137 +SMCError TextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc, SMCStates *states)
2.138 +{
2.139 + FILE *fp = fopen(file, "rt");
2.140 +
2.141 + if (!fp)
2.142 + {
2.143 + if (states != NULL)
2.144 + {
2.145 + states->line = 0;
2.146 + states->col = 0;
2.147 + }
2.148 + return SMCError_StreamOpen;
2.149 + }
2.150 +
2.151 + SMCError result = ParseStream_SMC(fp, FileStreamReader, smc, states);
2.152 +
2.153 + fclose(fp);
2.154 +
2.155 + return result;
2.156 +}
2.157 +
2.158 +SMCError TextParsers::ParseSMCFile(const char *file,
2.159 + ITextListener_SMC *smc_listener,
2.160 + SMCStates *states,
2.161 + char *buffer,
2.162 + size_t maxsize)
2.163 +{
2.164 + const char *errstr;
2.165 + FILE *fp = fopen(file, "rt");
2.166 +
2.167 + if (fp == NULL)
2.168 + {
2.169 + char error[256] = "unknown";
2.170 + if (states != NULL)
2.171 + {
2.172 + states->line = 0;
2.173 + states->col = 0;
2.174 + }
2.175 + //g_LibSys.GetPlatformError(error, sizeof(error));
2.176 + UTIL_Format(buffer, maxsize, "File could not be opened: %s", error);
2.177 + return SMCError_StreamOpen;
2.178 + }
2.179 +
2.180 + SMCError result = ParseStream_SMC(fp, FileStreamReader, smc_listener, states);
2.181 +
2.182 + fclose(fp);
2.183 +
2.184 + errstr = GetSMCErrorString(result);
2.185 + UTIL_Format(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
2.186 +
2.187 + return result;
2.188 +}
2.189 +
2.190 +/**
2.191 + * Raw parsing of streams with helper functions
2.192 + */
2.193 +
2.194 +struct StringInfo
2.195 +{
2.196 + StringInfo() : quoted(false), ptr(NULL), end(NULL), special(false) { }
2.197 + bool quoted;
2.198 + char *ptr;
2.199 + char *end;
2.200 + bool special;
2.201 +};
2.202 +
2.203 +const char *FixupString(StringInfo &data)
2.204 +{
2.205 + if (!data.ptr)
2.206 + {
2.207 + return NULL;
2.208 + }
2.209 +
2.210 + if (data.quoted)
2.211 + {
2.212 + data.ptr++;
2.213 + }
2.214 +#if defined _DEBUG
2.215 + else {
2.216 + /* A string will never have beginning whitespace because we ignore it in the stream.
2.217 + * Furthermore, if there is trailing whitespace, the end ptr will point to it, so it is valid
2.218 + * to overwrite! Lastly, the last character must be whitespace or a comment/invalid character.
2.219 + */
2.220 + }
2.221 +#endif
2.222 +
2.223 + /* Do some extra work on strings that have special quoted characters. */
2.224 + if (data.special)
2.225 + {
2.226 + char *outptr = data.ptr;
2.227 + size_t len = data.end - data.ptr;
2.228 + if (len >= 2)
2.229 + {
2.230 + for (size_t i=0; i<len; i++)
2.231 + {
2.232 + if (data.ptr[i] == '\\' && i < len - 1)
2.233 + {
2.234 + /* Resolve the next character. */
2.235 + i++;
2.236 + if (data.ptr[i] == 'n')
2.237 + {
2.238 + data.ptr[i] = '\n';
2.239 + } else if (data.ptr[i] == 't') {
2.240 + data.ptr[i] = '\t';
2.241 + } else if (data.ptr[i] == 'r') {
2.242 + data.ptr[i] = '\r';
2.243 + } else if (data.ptr[i] != '\\'
2.244 + && data.ptr[i] != '"') {
2.245 + /* This character is invalid, so go back one */
2.246 + i--;
2.247 + }
2.248 + }
2.249 + *outptr++ = data.ptr[i];
2.250 + }
2.251 + *outptr = '\0';
2.252 + }
2.253 + }
2.254 +
2.255 + if (data.end)
2.256 + {
2.257 + *(data.end) = '\0';
2.258 + }
2.259 +
2.260 + return data.ptr;
2.261 +}
2.262 +
2.263 +const char *rotate(StringInfo info[3])
2.264 +{
2.265 + if (info[2].ptr != NULL)
2.266 + {
2.267 + return info[2].ptr;
2.268 + }
2.269 +
2.270 + if (info[0].ptr != NULL)
2.271 + {
2.272 + info[2] = info[1];
2.273 + info[1] = info[0];
2.274 + info[0] = StringInfo();
2.275 + }
2.276 +
2.277 + return NULL;
2.278 +}
2.279 +
2.280 +void scrap(StringInfo info[3])
2.281 +{
2.282 + info[2] = StringInfo();
2.283 + info[1] = StringInfo();
2.284 + info[0] = StringInfo();
2.285 +}
2.286 +
2.287 +void reloc(StringInfo &data, unsigned int bytes)
2.288 +{
2.289 + if (data.ptr)
2.290 + {
2.291 + data.ptr -= bytes;
2.292 + }
2.293 + if (data.end)
2.294 + {
2.295 + data.end -= bytes;
2.296 + }
2.297 +}
2.298 +
2.299 +char *lowstring(StringInfo info[3])
2.300 +{
2.301 + for (int i=2; i>=0; i--)
2.302 + {
2.303 + if (info[i].ptr)
2.304 + {
2.305 + return info[i].ptr;
2.306 + }
2.307 + }
2.308 +
2.309 + return NULL;
2.310 +}
2.311 +
2.312 +SMCError TextParsers::ParseStream_SMC(void *stream,
2.313 + STREAMREADER srdr,
2.314 + ITextListener_SMC *smc,
2.315 + SMCStates *pStates)
2.316 +{
2.317 + char *reparse_point = NULL;
2.318 + char in_buf[4096];
2.319 + char *parse_point = in_buf;
2.320 + char *line_begin = in_buf;
2.321 + unsigned int read;
2.322 + unsigned int curlevel = 0;
2.323 + bool in_quote = false;
2.324 + bool ignoring = false;
2.325 + bool eol_comment = false;
2.326 + bool ml_comment = false;
2.327 + unsigned int i;
2.328 + SMCError err = SMCError_Okay;
2.329 + SMCResult res;
2.330 + SMCStates states;
2.331 + char c;
2.332 +
2.333 + StringInfo strings[3];
2.334 + StringInfo emptystring;
2.335 +
2.336 + states.line = 1;
2.337 + states.col = 0;
2.338 +
2.339 + smc->ReadSMC_ParseStart();
2.340 +
2.341 + /**
2.342 + * The stream reader reads in as much as it can fill the buffer with.
2.343 + * It then processes the buffer. If the buffer cannot be fully processed, for example,
2.344 + * a line is left hanging with no newline, then the contents of the buffer is shifted
2.345 + * down, and the buffer is filled from the stream reader again.
2.346 + *
2.347 + * What makes this particularly annoying is that we cache pointers everywhere, so when
2.348 + * the shifting process takes place, all those pointers must be shifted as well.
2.349 + */
2.350 + while (srdr(stream, parse_point, sizeof(in_buf) - (parse_point - in_buf) - 1, &read))
2.351 + {
2.352 + if (!read)
2.353 + {
2.354 + break;
2.355 + }
2.356 +
2.357 + /* Check for BOM markings, which is only relevant on the first line.
2.358 + * Not worth it, but it could be moved out of the loop.
2.359 + */
2.360 + if (states.line == 1 &&
2.361 + in_buf[0] == (char)0xEF &&
2.362 + in_buf[1] == (char)0xBB &&
2.363 + in_buf[2] == (char)0xBF)
2.364 + {
2.365 + /* Move EVERYTHING down :\ */
2.366 + memmove(in_buf, &in_buf[3], read - 3);
2.367 + read -= 3;
2.368 + }
2.369 +
2.370 + if (reparse_point)
2.371 + {
2.372 + read += (parse_point - reparse_point);
2.373 + parse_point = reparse_point;
2.374 + reparse_point = NULL;
2.375 + }
2.376 +
2.377 + for (i=0; i<read; i++)
2.378 + {
2.379 + c = parse_point[i];
2.380 + if (c == '\n')
2.381 + {
2.382 + /* If we got a newline, there's a lot of things that could have happened in the interim.
2.383 + * First, let's make sure the staged strings are rotated.
2.384 + */
2.385 + if (strings[0].ptr)
2.386 + {
2.387 + strings[0].end = &parse_point[i];
2.388 + if (rotate(strings) != NULL)
2.389 + {
2.390 + err = SMCError_InvalidTokens;
2.391 + goto failed;
2.392 + }
2.393 + }
2.394 +
2.395 + /* Next, let's clear some line-based values that may no longer have meaning */
2.396 + eol_comment = false;
2.397 + in_quote = false;
2.398 + if (ignoring && !ml_comment)
2.399 + {
2.400 + ignoring = false;
2.401 + }
2.402 +
2.403 + /* Pass the raw line onto the listener. We terminate the line so the receiver
2.404 + * doesn't get tons of useless info. We restore the newline after.
2.405 + */
2.406 + parse_point[i] = '\0';
2.407 + if ((res=smc->ReadSMC_RawLine(&states, line_begin)) != SMCResult_Continue)
2.408 + {
2.409 + err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
2.410 + goto failed;
2.411 + }
2.412 + parse_point[i] = '\n';
2.413 +
2.414 + /* Now we check the sanity of our staged strings! */
2.415 + if (strings[2].ptr)
2.416 + {
2.417 + if (!curlevel)
2.418 + {
2.419 + err = SMCError_InvalidProperty1;
2.420 + goto failed;
2.421 + }
2.422 + /* Assume the next string is a property and pass the info on. */
2.423 + if ((res=smc->ReadSMC_KeyValue(
2.424 + &states,
2.425 + FixupString(strings[2]),
2.426 + FixupString(strings[1]))) != SMCResult_Continue)
2.427 + {
2.428 + err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
2.429 + goto failed;
2.430 + }
2.431 + scrap(strings);
2.432 + }
2.433 +
2.434 + /* Change the states for the next line */
2.435 + states.col = 0;
2.436 + states.line++;
2.437 + line_begin = &parse_point[i+1]; //Note: safe because this gets relocated later
2.438 + }
2.439 + else if (ignoring)
2.440 + {
2.441 + if (in_quote)
2.442 + {
2.443 + /* If i was 0, we could have reparsed, so make sure there's no buffer underrun */
2.444 + if ((&parse_point[i] != in_buf) && c == '"' && parse_point[i-1] != '\\')
2.445 + {
2.446 + /* If we reached a quote in an ignore phase,
2.447 + * we're staging a string and we must rotate it out.
2.448 + */
2.449 + in_quote = false;
2.450 + ignoring = false;
2.451 + /* Set our info */
2.452 + strings[0].end = &parse_point[i];
2.453 + strings[0].quoted = true;
2.454 + if (rotate(strings) != NULL)
2.455 + {
2.456 + /* If we rotated too many strings, there was too much crap on one line */
2.457 + err = SMCError_InvalidTokens;
2.458 + goto failed;
2.459 + }
2.460 + }
2.461 + else if (c == '\\')
2.462 + {
2.463 + strings[0].special = true;
2.464 + if (i == (read - 1))
2.465 + {
2.466 + reparse_point = &parse_point[i];
2.467 + break;
2.468 + }
2.469 + }
2.470 + }
2.471 + else if (ml_comment)
2.472 + {
2.473 + if (c == '*')
2.474 + {
2.475 + /* Check if we need to get more input first */
2.476 + if (i == read - 1)
2.477 + {
2.478 + reparse_point = &parse_point[i];
2.479 + break;
2.480 + }
2.481 + if (parse_point[i+1] == '/')
2.482 + {
2.483 + ml_comment = false;
2.484 + ignoring = false;
2.485 + /* We should not be staging anything right now. */
2.486 + assert(strings[0].ptr == NULL);
2.487 + /* Advance the input stream so we don't choke on this token */
2.488 + i++;
2.489 + states.col++;
2.490 + }
2.491 + }
2.492 + }
2.493 + }
2.494 + else
2.495 + {
2.496 + /* Check if we're whitespace or not */
2.497 + if (!g_ws_chartable[(unsigned)c])
2.498 + {
2.499 + bool restage = false;
2.500 + /* Check various special tokens:
2.501 + * ;
2.502 + * //
2.503 + * / *
2.504 + * {
2.505 + * }
2.506 + */
2.507 + if (c == ';' || c == '/')
2.508 + {
2.509 + /* If it's a line-based comment (that is, ; or //)
2.510 + * we will need to scrap everything until the end of the line.
2.511 + */
2.512 + if (c == '/')
2.513 + {
2.514 + if (i == read - 1)
2.515 + {
2.516 + /* If we reached the end of the look-ahead, we need to re-check our input.
2.517 + * Breaking out will force this to be the new reparse point!
2.518 + */
2.519 + reparse_point = &parse_point[i];
2.520 + break;
2.521 + }
2.522 + if (parse_point[i + 1] == '/')
2.523 + {
2.524 + /* standard comment */
2.525 + ignoring = true;
2.526 + eol_comment = true;
2.527 + restage = true;
2.528 + }
2.529 + else if (parse_point[i+1] == '*')
2.530 + {
2.531 + /* inline comment - start ignoring */
2.532 + ignoring = true;
2.533 + ml_comment = true;
2.534 + /* yes, we restage, meaning that:
2.535 + * STR/ *stuff* /ING (space because ml comments don't nest in C++)
2.536 + * will not generate 'STRING', but rather 'STR' and 'ING'.
2.537 + * This should be a rare occurrence and is done here for convenience.
2.538 + */
2.539 + restage = true;
2.540 + }
2.541 + }
2.542 + else
2.543 + {
2.544 + ignoring = true;
2.545 + eol_comment = true;
2.546 + restage = true;
2.547 + }
2.548 + }
2.549 + else if (c == '{')
2.550 + {
2.551 + /* If we are staging a string, we must rotate here */
2.552 + if (strings[0].ptr)
2.553 + {
2.554 + /* We have unacceptable tokens on this line */
2.555 + if (rotate(strings) != NULL)
2.556 + {
2.557 + err = SMCError_InvalidSection1;
2.558 + goto failed;
2.559 + }
2.560 + }
2.561 + /* Sections must always be alone */
2.562 + if (strings[2].ptr != NULL)
2.563 + {
2.564 + err = SMCError_InvalidSection1;
2.565 + goto failed;
2.566 + }
2.567 + else if (strings[1].ptr == NULL)
2.568 + {
2.569 + err = SMCError_InvalidSection2;
2.570 + goto failed;
2.571 + }
2.572 + if ((res=smc->ReadSMC_NewSection(&states, FixupString(strings[1])))
2.573 + != SMCResult_Continue)
2.574 + {
2.575 + err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
2.576 + goto failed;
2.577 + }
2.578 + strings[1] = emptystring;
2.579 + curlevel++;
2.580 + }
2.581 + else if (c == '}')
2.582 + {
2.583 + /* Unlike our matching friend, this can be on the same line as something prior */
2.584 + if (rotate(strings) != NULL)
2.585 + {
2.586 + err = SMCError_InvalidSection3;
2.587 + goto failed;
2.588 + }
2.589 + if (strings[2].ptr)
2.590 + {
2.591 + if (!curlevel)
2.592 + {
2.593 + err = SMCError_InvalidProperty1;
2.594 + goto failed;
2.595 + }
2.596 + if ((res=smc->ReadSMC_KeyValue(
2.597 + &states,
2.598 + FixupString(strings[2]),
2.599 + FixupString(strings[1])))
2.600 + != SMCResult_Continue)
2.601 + {
2.602 + err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
2.603 + goto failed;
2.604 + }
2.605 + }
2.606 + else if (strings[1].ptr)
2.607 + {
2.608 + err = SMCError_InvalidSection3;
2.609 + goto failed;
2.610 + }
2.611 + else if (!curlevel)
2.612 + {
2.613 + err = SMCError_InvalidSection4;
2.614 + goto failed;
2.615 + }
2.616 + /* Now it's safe to leave the section */
2.617 + scrap(strings);
2.618 + if ((res=smc->ReadSMC_LeavingSection(&states)) != SMCResult_Continue)
2.619 + {
2.620 + err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
2.621 + goto failed;
2.622 + }
2.623 + curlevel--;
2.624 + }
2.625 + else if (c == '"')
2.626 + {
2.627 + /* If we get a quote mark, we always restage, but we need to do it beforehand */
2.628 + if (strings[0].ptr)
2.629 + {
2.630 + strings[0].end = &parse_point[i];
2.631 + if (rotate(strings) != NULL)
2.632 + {
2.633 + err = SMCError_InvalidTokens;
2.634 + goto failed;
2.635 + }
2.636 + }
2.637 + strings[0].ptr = &parse_point[i];
2.638 + in_quote = true;
2.639 + ignoring = true;
2.640 + }
2.641 + else if (!strings[0].ptr)
2.642 + {
2.643 + /* If we have no string, we must start one */
2.644 + strings[0].ptr = &parse_point[i];
2.645 + }
2.646 + if (restage && strings[0].ptr)
2.647 + {
2.648 + strings[0].end = &parse_point[i];
2.649 + if (rotate(strings) != NULL)
2.650 + {
2.651 + err = SMCError_InvalidTokens;
2.652 + goto failed;
2.653 + }
2.654 + }
2.655 + }
2.656 + else
2.657 + {
2.658 + /* If we're eating a string and get whitespace, we need to restage.
2.659 + * (Note that if we are quoted, this is being ignored)
2.660 + */
2.661 + if (strings[0].ptr)
2.662 + {
2.663 + /*
2.664 + * The specification says the second string in a pair does not need to be quoted.
2.665 + * Thus, we check if there's already a string on the stack.
2.666 + * If there's a newline, we always rotate so the newline has an empty starter.
2.667 + */
2.668 + if (!strings[1].ptr)
2.669 + {
2.670 + /* There's no string, so we must move this one down and eat up another */
2.671 + strings[0].end = &parse_point[i];
2.672 + rotate(strings);
2.673 + }
2.674 + else if (!strings[1].quoted)
2.675 + {
2.676 + err = SMCError_InvalidTokens;
2.677 + goto failed;
2.678 + }
2.679 + }
2.680 + }
2.681 + }
2.682 +
2.683 + /* Advance which token we're on */
2.684 + states.col++;
2.685 + }
2.686 +
2.687 + if (line_begin != in_buf)
2.688 + {
2.689 + /* The line buffer has advanced, so it's safe to copy N bytes back to the beginning.
2.690 + * What's N? N is the lowest point we're currently relying on.
2.691 + */
2.692 + char *stage = lowstring(strings);
2.693 + if (!stage || stage > line_begin)
2.694 + {
2.695 + stage = line_begin;
2.696 + }
2.697 + unsigned int bytes = read - (stage - parse_point);
2.698 +
2.699 + /* It is now safe to delete everything before the staged point */
2.700 + memmove(in_buf, stage, bytes);
2.701 +
2.702 + /* Calculate the number of bytes in the new buffer */
2.703 + bytes = stage - in_buf;
2.704 + /* Relocate all the cached pointers to our new base */
2.705 + line_begin -= bytes;
2.706 + reloc(strings[0], bytes);
2.707 + reloc(strings[1], bytes);
2.708 + reloc(strings[2], bytes);
2.709 + if (reparse_point)
2.710 + {
2.711 + reparse_point -= bytes;
2.712 + }
2.713 + if (parse_point)
2.714 + {
2.715 + parse_point = &parse_point[read];
2.716 + parse_point -= bytes;
2.717 + }
2.718 + }
2.719 + else if (read == sizeof(in_buf) - 1)
2.720 + {
2.721 + err = SMCError_TokenOverflow;
2.722 + goto failed;
2.723 + }
2.724 + }
2.725 +
2.726 + /* If we're done parsing and there are tokens left over... */
2.727 + if (curlevel)
2.728 + {
2.729 + err = SMCError_InvalidSection5;
2.730 + goto failed;
2.731 + }
2.732 + else if (strings[0].ptr || strings[1].ptr)
2.733 + {
2.734 + err = SMCError_InvalidTokens;
2.735 + goto failed;
2.736 + }
2.737 +
2.738 + smc->ReadSMC_ParseEnd(false, false);
2.739 +
2.740 + if (pStates != NULL)
2.741 + {
2.742 + *pStates = states;
2.743 + }
2.744 +
2.745 + return SMCError_Okay;
2.746 +
2.747 +failed:
2.748 + if (pStates != NULL)
2.749 + {
2.750 + *pStates = states;
2.751 + }
2.752 +
2.753 + smc->ReadSMC_ParseEnd(true, (err == SMCError_Custom));
2.754 +
2.755 + return err;
2.756 +}
2.757 +
2.758 +
2.759 +/**
2.760 + * INI parser
2.761 + */
2.762 +
2.763 +bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
2.764 +{
2.765 + FILE *fp = fopen(file, "rt");
2.766 + unsigned int curline = 0;
2.767 + unsigned int curtok;
2.768 + size_t len;
2.769 +
2.770 + if (!fp)
2.771 + {
2.772 + if (line)
2.773 + {
2.774 + *line = 0;
2.775 + }
2.776 +
2.777 + return false;
2.778 + }
2.779 +
2.780 + char buffer[2048];
2.781 + char *ptr, *save_ptr;
2.782 + bool in_quote;
2.783 +
2.784 + while (!feof(fp))
2.785 + {
2.786 + curline++;
2.787 + curtok = 0;
2.788 + buffer[0] = '\0';
2.789 + if (fgets(buffer, sizeof(buffer), fp) == NULL)
2.790 + {
2.791 + break;
2.792 + }
2.793 +
2.794 + //:TODO: this will only run once, so find a nice way to move it out of the while loop
2.795 + /* If this is the first line, check the first three bytes for BOM */
2.796 + if (curline == 1 &&
2.797 + buffer[0] == (char)0xEF &&
2.798 + buffer[1] == (char)0xBB &&
2.799 + buffer[2] == (char)0xBF)
2.800 + {
2.801 + /* We have a UTF-8 marked file... skip these bytes */
2.802 + ptr = &buffer[3];
2.803 + } else {
2.804 + ptr = buffer;
2.805 + }
2.806 +
2.807 + /***************************************************
2.808 + * We preprocess the string before parsing tokens! *
2.809 + ***************************************************/
2.810 +
2.811 + /* First strip beginning whitespace */
2.812 + while (*ptr != '\0' && g_ws_chartable[(unsigned)*ptr] != 0)
2.813 + {
2.814 + ptr++;
2.815 + }
2.816 +
2.817 + len = strlen(ptr);
2.818 +
2.819 + if (!len)
2.820 + {
2.821 + continue;
2.822 + }
2.823 +
2.824 + /* Now search for comment characters */
2.825 + in_quote = false;
2.826 + save_ptr = ptr;
2.827 + for (size_t i=0; i<len; i++,ptr++)
2.828 + {
2.829 + if (!in_quote)
2.830 + {
2.831 + switch (*ptr)
2.832 + {
2.833 + case '"':
2.834 + {
2.835 + in_quote = true;
2.836 + break;
2.837 + }
2.838 + case ';':
2.839 + {
2.840 + /* Stop the loop */
2.841 + len = i;
2.842 + /* Terminate the string here */
2.843 + *ptr = '\0';
2.844 + break;
2.845 + }
2.846 + }
2.847 + } else {
2.848 + if (*ptr == '"')
2.849 + {
2.850 + in_quote = false;
2.851 + }
2.852 + }
2.853 + }
2.854 +
2.855 + if (!len)
2.856 + {
2.857 + continue;
2.858 + }
2.859 +
2.860 + ptr = save_ptr;
2.861 +
2.862 + /* Lastly, strip ending whitespace off */
2.863 + for (size_t i=len-1; i>=0 && i<len; i--)
2.864 + {
2.865 + if (g_ws_chartable[(unsigned)ptr[i]])
2.866 + {
2.867 + ptr[i] = '\0';
2.868 + len--;
2.869 + } else {
2.870 + break;
2.871 + }
2.872 + }
2.873 +
2.874 + if (!len)
2.875 + {
2.876 + continue;
2.877 + }
2.878 +
2.879 + if (!ini_listener->ReadINI_RawLine(ptr, &curtok))
2.880 + {
2.881 + goto event_failed;
2.882 + }
2.883 +
2.884 + if (*ptr == '[')
2.885 + {
2.886 + bool invalid_tokens = false;
2.887 + bool got_bracket = false;
2.888 + bool extra_tokens = false;
2.889 + char c;
2.890 + bool alnum;
2.891 + wchar_t wc;
2.892 +
2.893 + for (size_t i=1; i<len; i++)
2.894 + {
2.895 + c = ptr[i];
2.896 + alnum = false;
2.897 +
2.898 + if (c & (1<<7))
2.899 + {
2.900 + if (mbtowc(&wc, &ptr[i], len-i) != -1)
2.901 + {
2.902 + alnum = (iswalnum(wc) != 0);
2.903 + i += _GetUTF8CharBytes(&ptr[i]) - 1;
2.904 + }
2.905 + } else {
2.906 + alnum = (isalnum(c) != 0) || (g_ini_chartable1[(unsigned)c] != 0);
2.907 + }
2.908 + if (!alnum)
2.909 + {
2.910 + /* First check - is this a bracket? */
2.911 + if (c == ']')
2.912 + {
2.913 + /* Yes! */
2.914 + got_bracket = true;
2.915 + /* If this isn't the last character... */
2.916 + if (i != len - 1)
2.917 + {
2.918 + extra_tokens = true;
2.919 + }
2.920 + /* terminate */
2.921 + ptr[i] = '\0';
2.922 + break;
2.923 + } else {
2.924 + /* n...No! Continue copying. */
2.925 + invalid_tokens = true;
2.926 + }
2.927 + }
2.928 + }
2.929 +
2.930 + /* Tell the handler */
2.931 + if (!ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok))
2.932 + {
2.933 + goto event_failed;
2.934 + }
2.935 + } else {
2.936 + char *key_ptr = ptr;
2.937 + char *val_ptr = NULL;
2.938 + char c;
2.939 + size_t first_space = 0;
2.940 + bool invalid_tokens = false;
2.941 + bool equal_token = false;
2.942 + bool quotes = false;
2.943 + bool alnum;
2.944 + wchar_t wc;
2.945 +
2.946 + for (size_t i=0; i<len; i++)
2.947 + {
2.948 + c = ptr[i];
2.949 + alnum = false;
2.950 + /* is this an invalid char? */
2.951 + if (c & (1<<7))
2.952 + {
2.953 + if (mbtowc(&wc, &ptr[i], len-i) != -1)
2.954 + {
2.955 + alnum = (iswalnum(wc) != 0);
2.956 + i += _GetUTF8CharBytes(&ptr[i]) - 1;
2.957 + }
2.958 + } else {
2.959 + alnum = (isalnum(c) != 0) || (g_ini_chartable1[(unsigned)c] != 0);
2.960 + }
2.961 +
2.962 + if (!alnum)
2.963 + {
2.964 + if (g_ws_chartable[(unsigned)c])
2.965 + {
2.966 + /* if it's a space, keep track of the first occurring space */
2.967 + if (!first_space)
2.968 + {
2.969 + first_space = i;
2.970 + }
2.971 + } else {
2.972 + if (c == '=')
2.973 + {
2.974 + /* if it's an equal sign, we're done with the key */
2.975 + if (first_space)
2.976 + {
2.977 + /* remove excess whitespace */
2.978 + key_ptr[first_space] = '\0';
2.979 + } else {
2.980 + /* remove the equal sign */
2.981 + key_ptr[i] = '\0';
2.982 + }
2.983 + if (ptr[++i] != '\0')
2.984 + {
2.985 + /* If this isn't the end, set next pointer */
2.986 + val_ptr = &ptr[i];
2.987 + }
2.988 + equal_token = true;
2.989 + break;
2.990 + } else {
2.991 + /* Mark that we got something invalid! */
2.992 + invalid_tokens = true;
2.993 + first_space = 0;
2.994 + }
2.995 + }
2.996 + }
2.997 + }
2.998 +
2.999 + /* Now we need to parse the value, if any */
2.1000 + if (val_ptr)
2.1001 + {
2.1002 + /* eat up spaces! there shouldn't be any h*/
2.1003 + while ((*val_ptr != '\0') && g_ws_chartable[(unsigned)*val_ptr] != 0)
2.1004 + {
2.1005 + val_ptr++;
2.1006 + }
2.1007 + if (*val_ptr == '\0')
2.1008 + {
2.1009 + val_ptr = NULL;
2.1010 + goto skip_value;
2.1011 + }
2.1012 + /* Do we have an initial quote? If so, the parsing rules change! */
2.1013 + if (*val_ptr == '"' && *val_ptr != '\0')
2.1014 + {
2.1015 + len = strlen(val_ptr);
2.1016 + if (val_ptr[len-1] == '"')
2.1017 + {
2.1018 + /* Strip quotes! */
2.1019 + val_ptr[--len] = '\0';
2.1020 + val_ptr++;
2.1021 + quotes = true;
2.1022 + }
2.1023 + }
2.1024 + }
2.1025 +skip_value:
2.1026 + /* We're done! */
2.1027 + curtok = val_ptr - buffer;
2.1028 + if (!ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok))
2.1029 + {
2.1030 + curtok = 0;
2.1031 + goto event_failed;
2.1032 + }
2.1033 + }
2.1034 + }
2.1035 +
2.1036 + if (line)
2.1037 + {
2.1038 + *line = curline;
2.1039 + }
2.1040 +
2.1041 + fclose(fp);
2.1042 +
2.1043 + return true;
2.1044 +
2.1045 +event_failed:
2.1046 + if (line)
2.1047 + {
2.1048 + *line = curline;
2.1049 + }
2.1050 +
2.1051 + if (col)
2.1052 + {
2.1053 + *col = curtok;
2.1054 + }
2.1055 +
2.1056 + fclose(fp);
2.1057 +
2.1058 + return false;
2.1059 +}
2.1060 +
2.1061 +const char *TextParsers::GetSMCErrorString(SMCError err)
2.1062 +{
2.1063 + static const char *s_errors[] =
2.1064 + {
2.1065 + NULL,
2.1066 + "Stream failed to open",
2.1067 + "Stream returned read error",
2.1068 + NULL,
2.1069 + "Un-quoted section has invalid tokens",
2.1070 + "Section declared without header",
2.1071 + "Section declared with unknown tokens",
2.1072 + "Section ending without a matching section beginning",
2.1073 + "Section beginning without a matching ending",
2.1074 + "Line contained too many invalid tokens",
2.1075 + "Token buffer overflowed",
2.1076 + "A property was declared outside of a section",
2.1077 + };
2.1078 +
2.1079 + if (err < SMCError_Okay || err > SMCError_InvalidProperty1)
2.1080 + {
2.1081 + return NULL;
2.1082 + }
2.1083 +
2.1084 + return s_errors[err];
2.1085 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/tools/gamedata md5/TextParsers.h Sun Jun 29 22:23:14 2008 +0000
3.3 @@ -0,0 +1,87 @@
3.4 +/**
3.5 + * vim: set ts=4 :
3.6 + * =============================================================================
3.7 + * SourceMod
3.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
3.9 + * =============================================================================
3.10 + *
3.11 + * This program is free software; you can redistribute it and/or modify it under
3.12 + * the terms of the GNU General Public License, version 3.0, as published by the
3.13 + * Free Software Foundation.
3.14 + *
3.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
3.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
3.18 + * details.
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License along with
3.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
3.22 + *
3.23 + * As a special exception, AlliedModders LLC gives you permission to link the
3.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
3.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
3.26 + * by the Valve Corporation. You must obey the GNU General Public License in
3.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
3.28 + * this exception to all derivative works. AlliedModders LLC defines further
3.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
3.30 + * or <http://www.sourcemod.net/license.php>.
3.31 + *
3.32 + * Version: $Id$
3.33 + */
3.34 +
3.35 +#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
3.36 +#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
3.37 +
3.38 +#include "ITextParsers.h"
3.39 +#include "main.h"
3.40 +
3.41 +using namespace SourceMod;
3.42 +
3.43 +/**
3.44 + * @param void * IN: Stream pointer
3.45 + * @param char * IN/OUT: Stream buffer
3.46 + * @param size_t IN: Maximum size of buffer
3.47 + * @param unsigned int * OUT: Number of bytes read (0 = end of stream)
3.48 + * @return True on success, false on failure
3.49 + */
3.50 +typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *);
3.51 +
3.52 +class TextParsers : public ITextParsers
3.53 +{
3.54 +public:
3.55 + TextParsers();
3.56 +public:
3.57 + bool ParseFile_INI(const char *file,
3.58 + ITextListener_INI *ini_listener,
3.59 + unsigned int *line,
3.60 + unsigned int *col);
3.61 +
3.62 + SMCError ParseFile_SMC(const char *file,
3.63 + ITextListener_SMC *smc_listener,
3.64 + SMCStates *states);
3.65 +
3.66 + SMCError ParseSMCFile(const char *file,
3.67 + ITextListener_SMC *smc_listener,
3.68 + SMCStates *states,
3.69 + char *buffer,
3.70 + size_t maxsize);
3.71 +
3.72 + unsigned int GetUTF8CharBytes(const char *stream);
3.73 +
3.74 + const char *GetSMCErrorString(SMCError err);
3.75 + bool IsWhitespace(const char *stream);
3.76 +private:
3.77 + SMCError ParseString_SMC(const char *stream,
3.78 + ITextListener_SMC *smc,
3.79 + SMCStates *states);
3.80 + SMCError ParseStream_SMC(void *stream,
3.81 + STREAMREADER srdr,
3.82 + ITextListener_SMC *smc,
3.83 + SMCStates *states);
3.84 +
3.85 +};
3.86 +
3.87 +extern TextParsers g_TextParser;
3.88 +
3.89 +#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_
3.90 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tools/gamedata md5/main.cpp Sun Jun 29 22:23:14 2008 +0000
4.3 @@ -0,0 +1,45 @@
4.4 +#include "main.h"
4.5 +#include <stdarg.h>
4.6 +
4.7 +BuildMD5ableBuffer g_MD5Builder;
4.8 +
4.9 +int main(int argc, char **argv)
4.10 +{
4.11 + SMCStates states;
4.12 + SMCError error;
4.13 +
4.14 + if (argc < 2)
4.15 + {
4.16 + fprintf(stderr, "Usage: <file>\n");
4.17 + return -1;
4.18 + }
4.19 +
4.20 + error = g_TextParser.ParseFile_SMC(argv[1], &g_MD5Builder, &states);
4.21 +
4.22 + if (error == SMCError_Okay)
4.23 + {
4.24 + printf("MD5: %s\n", g_MD5Builder.GetMD5String());
4.25 + return 0;
4.26 + }
4.27 +
4.28 + fprintf(stderr, "Failed to parse file, Error %i at line %i and col %i\n", error, states.line, states.col);
4.29 + return -1;
4.30 +}
4.31 +
4.32 +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
4.33 +{
4.34 + va_list ap;
4.35 + va_start(ap, fmt);
4.36 + size_t len = vsnprintf(buffer, maxlength, fmt, ap);
4.37 + va_end(ap);
4.38 +
4.39 + if (len >= maxlength)
4.40 + {
4.41 + buffer[maxlength - 1] = '\0';
4.42 + return (maxlength - 1);
4.43 + }
4.44 + else
4.45 + {
4.46 + return len;
4.47 + }
4.48 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/tools/gamedata md5/main.h Sun Jun 29 22:23:14 2008 +0000
5.3 @@ -0,0 +1,88 @@
5.4 +#ifndef _INCLUDE_GAMEDATAMD5_MAIN_H_
5.5 +#define _INCLUDE_GAMEDATAMD5_MAIN_H_
5.6 +
5.7 +#include "TextParsers.h"
5.8 +#include "sm_memtable.h"
5.9 +#include "md5.h"
5.10 +
5.11 +using namespace SourceMod;
5.12 +
5.13 +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
5.14 +
5.15 +class BuildMD5ableBuffer : public ITextListener_SMC
5.16 +{
5.17 +public:
5.18 +
5.19 + BuildMD5ableBuffer()
5.20 + {
5.21 + stringTable = new BaseStringTable(2048);
5.22 + md5[0] = 0;
5.23 + md5String[0] = 0;
5.24 + }
5.25 +
5.26 + ~BuildMD5ableBuffer()
5.27 + {
5.28 + delete stringTable;
5.29 + }
5.30 +
5.31 + void ReadSMC_ParseStart()
5.32 + {
5.33 + checksum = MD5();
5.34 + }
5.35 +
5.36 + SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
5.37 + {
5.38 + stringTable->AddString(key);
5.39 + stringTable->AddString(value);
5.40 +
5.41 + return SMCResult_Continue;
5.42 + }
5.43 +
5.44 + SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
5.45 + {
5.46 + stringTable->AddString(name);
5.47 +
5.48 + return SMCResult_Continue;
5.49 + }
5.50 +
5.51 + void ReadSMC_ParseEnd(bool halted, bool failed)
5.52 + {
5.53 + if (halted || failed)
5.54 + {
5.55 + return;
5.56 + }
5.57 +
5.58 + void *data = stringTable->GetMemTable()->GetAddress(0);
5.59 +
5.60 + if (data != NULL)
5.61 + {
5.62 + checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
5.63 + }
5.64 +
5.65 + checksum.finalize();
5.66 +
5.67 + checksum.hex_digest(md5String);
5.68 + checksum.raw_digest(md5);
5.69 +
5.70 + stringTable->Reset();
5.71 + }
5.72 +
5.73 + unsigned char * GetMD5()
5.74 + {
5.75 + return md5;
5.76 + }
5.77 +
5.78 + unsigned char * GetMD5String()
5.79 + {
5.80 + return (unsigned char *)&md5String[0];
5.81 + }
5.82 +
5.83 +private:
5.84 + MD5 checksum;
5.85 + unsigned char md5[16];
5.86 + char md5String[33];
5.87 + BaseStringTable *stringTable;
5.88 +};
5.89 +
5.90 +
5.91 +#endif // _INCLUDE_GAMEDATAMD5_MAIN_H_
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tools/gamedata md5/md5.cpp Sun Jun 29 22:23:14 2008 +0000
6.3 @@ -0,0 +1,485 @@
6.4 +// MD5.CC - source code for the C++/object oriented translation and
6.5 +// modification of MD5.
6.6 +
6.7 +// Translation and modification (c) 1995 by Mordechai T. Abzug
6.8 +
6.9 +// This translation/ modification is provided "as is," without express or
6.10 +// implied warranty of any kind.
6.11 +
6.12 +// The translator/ modifier does not claim (1) that MD5 will do what you think
6.13 +// it does; (2) that this translation/ modification is accurate; or (3) that
6.14 +// this software is "merchantible." (Language for this disclaimer partially
6.15 +// copied from the disclaimer below).
6.16 +
6.17 +/* based on:
6.18 +
6.19 + MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
6.20 + MDDRIVER.C - test driver for MD2, MD4 and MD5
6.21 +
6.22 +
6.23 + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
6.24 +rights reserved.
6.25 +
6.26 +License to copy and use this software is granted provided that it
6.27 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
6.28 +Algorithm" in all material mentioning or referencing this software
6.29 +or this function.
6.30 +
6.31 +License is also granted to make and use derivative works provided
6.32 +that such works are identified as "derived from the RSA Data
6.33 +Security, Inc. MD5 Message-Digest Algorithm" in all material
6.34 +mentioning or referencing the derived work.
6.35 +
6.36 +RSA Data Security, Inc. makes no representations concerning either
6.37 +the merchantability of this software or the suitability of this
6.38 +software for any particular purpose. It is provided "as is"
6.39 +without express or implied warranty of any kind.
6.40 +
6.41 +These notices must be retained in any copies of any part of this
6.42 +documentation and/or software.
6.43 +
6.44 + */
6.45 +
6.46 +#include "md5.h"
6.47 +
6.48 +#include <assert.h>
6.49 +#include <string.h>
6.50 +
6.51 +// MD5 simple initialization method
6.52 +
6.53 +MD5::MD5(){
6.54 +
6.55 + init();
6.56 +
6.57 +}
6.58 +
6.59 +
6.60 +// MD5 block update operation. Continues an MD5 message-digest
6.61 +// operation, processing another message block, and updating the
6.62 +// context.
6.63 +
6.64 +void MD5::update (uint1 *input, uint4 input_length) {
6.65 +
6.66 + uint4 input_index, buffer_index;
6.67 + uint4 buffer_space; // how much space is left in buffer
6.68 +
6.69 + if (finalized){ // so we can't update!
6.70 + /*cerr << "MD5::update: Can't update a finalized digest!" << endl;*/
6.71 + return;
6.72 + }
6.73 +
6.74 + // Compute number of bytes mod 64
6.75 + buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
6.76 +
6.77 + // Update number of bits
6.78 + if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
6.79 + count[1]++;
6.80 +
6.81 + count[1] += ((uint4)input_length >> 29);
6.82 +
6.83 +
6.84 + buffer_space = 64 - buffer_index; // how much space is left in buffer
6.85 +
6.86 + // Transform as many times as possible.
6.87 + if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
6.88 + // fill the rest of the buffer and transform
6.89 + memcpy (buffer + buffer_index, input, buffer_space);
6.90 + transform (buffer);
6.91 +
6.92 + // now, transform each 64-byte piece of the input, bypassing the buffer
6.93 + for (input_index = buffer_space; input_index + 63 < input_length;
6.94 + input_index += 64)
6.95 + transform (input+input_index);
6.96 +
6.97 + buffer_index = 0; // so we can buffer remaining
6.98 + }
6.99 + else
6.100 + input_index=0; // so we can buffer the whole input
6.101 +
6.102 +
6.103 + // and here we do the buffering:
6.104 + memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
6.105 +}
6.106 +
6.107 +
6.108 +
6.109 +// MD5 update for files.
6.110 +// Like above, except that it works on files (and uses above as a primitive.)
6.111 +
6.112 +void MD5::update(FILE *file){
6.113 +
6.114 + unsigned char buffer[1024];
6.115 + int len;
6.116 +
6.117 + while ((len=fread(buffer, 1, 1024, file)))
6.118 + update(buffer, len);
6.119 +
6.120 + fclose (file);
6.121 +
6.122 +}
6.123 +
6.124 +
6.125 +// MD5 finalization. Ends an MD5 message-digest operation, writing the
6.126 +// the message digest and zeroizing the context.
6.127 +
6.128 +
6.129 +void MD5::finalize (){
6.130 +
6.131 + unsigned char bits[8];
6.132 + unsigned int index, padLen;
6.133 + static uint1 PADDING[64]={
6.134 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6.135 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6.136 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
6.137 + };
6.138 +
6.139 + if (finalized){
6.140 + /* cerr << "MD5::finalize: Already finalized this digest!" << endl;*/
6.141 + return;
6.142 + }
6.143 +
6.144 + // Save number of bits
6.145 + encode (bits, count, 8);
6.146 +
6.147 + // Pad out to 56 mod 64.
6.148 + index = (uint4) ((count[0] >> 3) & 0x3f);
6.149 + padLen = (index < 56) ? (56 - index) : (120 - index);
6.150 + update (PADDING, padLen);
6.151 +
6.152 + // Append length (before padding)
6.153 + update (bits, 8);
6.154 +
6.155 + // Store state in digest
6.156 + encode (digest, state, 16);
6.157 +
6.158 + // Zeroize sensitive information
6.159 + memset (buffer, 0, sizeof(*buffer));
6.160 +
6.161 + finalized=1;
6.162 +
6.163 +}
6.164 +
6.165 +
6.166 +
6.167 +
6.168 +MD5::MD5(FILE *file){
6.169 +
6.170 + init(); // must be called be all constructors
6.171 + update(file);
6.172 + finalize ();
6.173 +}
6.174 +
6.175 +unsigned char *MD5::raw_digest(){
6.176 +
6.177 + uint1 *s = new uint1[16];
6.178 +
6.179 + if (!finalized){
6.180 +/* cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
6.181 + "finalized the digest!" <<endl;*/
6.182 + return ( (unsigned char*) "");
6.183 + }
6.184 +
6.185 + memcpy(s, digest, 16);
6.186 + return s;
6.187 +}
6.188 +
6.189 +unsigned char *MD5::raw_digest(unsigned char buffer[16])
6.190 +{
6.191 + if (!finalized)
6.192 + {
6.193 + return ( (unsigned char*) "");
6.194 + }
6.195 +
6.196 + memcpy(buffer, digest, 16);
6.197 + return buffer;
6.198 +}
6.199 +
6.200 +
6.201 +
6.202 +char *MD5::hex_digest(){
6.203 +
6.204 + int i;
6.205 + char *s= new char[33];
6.206 +
6.207 + if (!finalized){
6.208 +/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
6.209 + "finalized the digest!" <<endl;*/
6.210 + return "";
6.211 + }
6.212 +
6.213 + for (i=0; i<16; i++)
6.214 + sprintf(s+i*2, "%02x", digest[i]);
6.215 +
6.216 + s[32]='\0';
6.217 +
6.218 + return s;
6.219 +}
6.220 +
6.221 +
6.222 +char *MD5::hex_digest(char buffer[33]){
6.223 +
6.224 + int i;
6.225 +
6.226 + if (!finalized)
6.227 + {
6.228 + /* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
6.229 + "finalized the digest!" <<endl;*/
6.230 + return "";
6.231 + }
6.232 +
6.233 + for (i=0; i<16; i++)
6.234 + sprintf(buffer+i*2, "%02x", digest[i]);
6.235 +
6.236 + buffer[32]='\0';
6.237 +
6.238 + return buffer;
6.239 +}
6.240 +
6.241 +
6.242 +// PRIVATE METHODS:
6.243 +
6.244 +
6.245 +
6.246 +void MD5::init(){
6.247 + finalized=0; // we just started!
6.248 +
6.249 + // Nothing counted, so count=0
6.250 + count[0] = 0;
6.251 + count[1] = 0;
6.252 +
6.253 + // Load magic initialization constants.
6.254 + state[0] = 0x67452301;
6.255 + state[1] = 0xefcdab89;
6.256 + state[2] = 0x98badcfe;
6.257 + state[3] = 0x10325476;
6.258 +}
6.259 +
6.260 +
6.261 +
6.262 +// Constants for MD5Transform routine.
6.263 +// Although we could use C++ style constants, defines are actually better,
6.264 +// since they let us easily evade scope clashes.
6.265 +
6.266 +#define S11 7
6.267 +#define S12 12
6.268 +#define S13 17
6.269 +#define S14 22
6.270 +#define S21 5
6.271 +#define S22 9
6.272 +#define S23 14
6.273 +#define S24 20
6.274 +#define S31 4
6.275 +#define S32 11
6.276 +#define S33 16
6.277 +#define S34 23
6.278 +#define S41 6
6.279 +#define S42 10
6.280 +#define S43 15
6.281 +#define S44 21
6.282 +
6.283 +
6.284 +
6.285 +
6.286 +// MD5 basic transformation. Transforms state based on block.
6.287 +void MD5::transform (uint1 block[64]){
6.288 +
6.289 + uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
6.290 +
6.291 + decode (x, block, 64);
6.292 +
6.293 + assert(!finalized); // not just a user error, since the method is private
6.294 +
6.295 + /* Round 1 */
6.296 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
6.297 + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
6.298 + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
6.299 + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
6.300 + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
6.301 + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
6.302 + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
6.303 + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
6.304 + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
6.305 + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
6.306 + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
6.307 + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
6.308 + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
6.309 + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
6.310 + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
6.311 + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
6.312 +
6.313 + /* Round 2 */
6.314 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
6.315 + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
6.316 + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
6.317 + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
6.318 + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
6.319 + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
6.320 + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
6.321 + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
6.322 + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
6.323 + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
6.324 + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
6.325 + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
6.326 + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
6.327 + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
6.328 + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
6.329 + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
6.330 +
6.331 + /* Round 3 */
6.332 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
6.333 + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
6.334 + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
6.335 + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
6.336 + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
6.337 + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
6.338 + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
6.339 + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
6.340 + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
6.341 + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
6.342 + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
6.343 + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
6.344 + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
6.345 + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
6.346 + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
6.347 + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
6.348 +
6.349 + /* Round 4 */
6.350 + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
6.351 + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
6.352 + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
6.353 + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
6.354 + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
6.355 + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
6.356 + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
6.357 + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
6.358 + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
6.359 + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
6.360 + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
6.361 + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
6.362 + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
6.363 + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
6.364 + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
6.365 + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
6.366 +
6.367 + state[0] += a;
6.368 + state[1] += b;
6.369 + state[2] += c;
6.370 + state[3] += d;
6.371 +
6.372 + // Zeroize sensitive information.
6.373 + memset ( (uint1 *) x, 0, sizeof(x));
6.374 +
6.375 +}
6.376 +
6.377 +
6.378 +
6.379 +// Encodes input (UINT4) into output (unsigned char). Assumes len is
6.380 +// a multiple of 4.
6.381 +void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
6.382 +
6.383 + unsigned int i, j;
6.384 +
6.385 + for (i = 0, j = 0; j < len; i++, j += 4) {
6.386 + output[j] = (uint1) (input[i] & 0xff);
6.387 + output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
6.388 + output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
6.389 + output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
6.390 + }
6.391 +}
6.392 +
6.393 +
6.394 +
6.395 +
6.396 +// Decodes input (unsigned char) into output (UINT4). Assumes len is
6.397 +// a multiple of 4.
6.398 +void MD5::decode (uint4 *output, uint1 *input, uint4 len){
6.399 +
6.400 + unsigned int i, j;
6.401 +
6.402 + for (i = 0, j = 0; j < len; i++, j += 4)
6.403 + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
6.404 + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
6.405 +}
6.406 +
6.407 +
6.408 +
6.409 +
6.410 +
6.411 +// Note: Replace "for loop" with standard memcpy if possible.
6.412 +void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
6.413 +
6.414 + unsigned int i;
6.415 +
6.416 + for (i = 0; i < len; i++)
6.417 + output[i] = input[i];
6.418 +}
6.419 +
6.420 +
6.421 +
6.422 +// Note: Replace "for loop" with standard memset if possible.
6.423 +void MD5::memset (uint1 *output, uint1 value, uint4 len){
6.424 +
6.425 + unsigned int i;
6.426 +
6.427 + for (i = 0; i < len; i++)
6.428 + output[i] = value;
6.429 +}
6.430 +
6.431 +
6.432 +
6.433 +// ROTATE_LEFT rotates x left n bits.
6.434 +
6.435 +inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
6.436 + return (x << n) | (x >> (32-n)) ;
6.437 +}
6.438 +
6.439 +
6.440 +
6.441 +
6.442 +// F, G, H and I are basic MD5 functions.
6.443 +
6.444 +inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
6.445 + return (x & y) | (~x & z);
6.446 +}
6.447 +
6.448 +inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
6.449 + return (x & z) | (y & ~z);
6.450 +}
6.451 +
6.452 +inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
6.453 + return x ^ y ^ z;
6.454 +}
6.455 +
6.456 +inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
6.457 + return y ^ (x | ~z);
6.458 +}
6.459 +
6.460 +
6.461 +
6.462 +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
6.463 +// Rotation is separate from addition to prevent recomputation.
6.464 +
6.465 +
6.466 +inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
6.467 + uint4 s, uint4 ac){
6.468 + a += F(b, c, d) + x + ac;
6.469 + a = rotate_left (a, s) +b;
6.470 +}
6.471 +
6.472 +inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
6.473 + uint4 s, uint4 ac){
6.474 + a += G(b, c, d) + x + ac;
6.475 + a = rotate_left (a, s) +b;
6.476 +}
6.477 +
6.478 +inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
6.479 + uint4 s, uint4 ac){
6.480 + a += H(b, c, d) + x + ac;
6.481 + a = rotate_left (a, s) +b;
6.482 +}
6.483 +
6.484 +inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
6.485 + uint4 s, uint4 ac){
6.486 + a += I(b, c, d) + x + ac;
6.487 + a = rotate_left (a, s) +b;
6.488 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tools/gamedata md5/md5.h Sun Jun 29 22:23:14 2008 +0000
7.3 @@ -0,0 +1,106 @@
7.4 +// MD5.CC - source code for the C++/object oriented translation and
7.5 +// modification of MD5.
7.6 +
7.7 +// Translation and modification (c) 1995 by Mordechai T. Abzug
7.8 +
7.9 +// This translation/ modification is provided "as is," without express or
7.10 +// implied warranty of any kind.
7.11 +
7.12 +// The translator/ modifier does not claim (1) that MD5 will do what you think
7.13 +// it does; (2) that this translation/ modification is accurate; or (3) that
7.14 +// this software is "merchantible." (Language for this disclaimer partially
7.15 +// copied from the disclaimer below).
7.16 +
7.17 +/* based on:
7.18 +
7.19 + MD5.H - header file for MD5C.C
7.20 + MDDRIVER.C - test driver for MD2, MD4 and MD5
7.21 +
7.22 + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
7.23 +rights reserved.
7.24 +
7.25 +License to copy and use this software is granted provided that it
7.26 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
7.27 +Algorithm" in all material mentioning or referencing this software
7.28 +or this function.
7.29 +
7.30 +License is also granted to make and use derivative works provided
7.31 +that such works are identified as "derived from the RSA Data
7.32 +Security, Inc. MD5 Message-Digest Algorithm" in all material
7.33 +mentioning or referencing the derived work.
7.34 +
7.35 +RSA Data Security, Inc. makes no representations concerning either
7.36 +the merchantability of this software or the suitability of this
7.37 +software for any particular purpose. It is provided "as is"
7.38 +without express or implied warranty of any kind.
7.39 +
7.40 +These notices must be retained in any copies of any part of this
7.41 +documentation and/or software.
7.42 +
7.43 +*/
7.44 +
7.45 +#include <stdio.h>
7.46 +//#include <fstream.h>
7.47 +//#include <iostream.h>
7.48 +
7.49 +class MD5 {
7.50 +
7.51 +public:
7.52 +// methods for controlled operation:
7.53 + MD5 (); // simple initializer
7.54 + void update (unsigned char *input, unsigned int input_length);
7.55 + void update (FILE *file);
7.56 + void finalize ();
7.57 +
7.58 +// constructors for special circumstances. All these constructors finalize
7.59 +// the MD5 context.
7.60 + MD5 (unsigned char *string); // digest string, finalize
7.61 + MD5 (FILE *file); // digest file, close, finalize
7.62 +
7.63 +// methods to acquire finalized result
7.64 + unsigned char *raw_digest (); // digest as a 16-byte binary array
7.65 + unsigned char *raw_digest(unsigned char buffer[16]);
7.66 + char * hex_digest (); // digest as a 33-byte ascii-hex string
7.67 + char * hex_digest (char buffer[33]); //same as above, passing buffer
7.68 +
7.69 +
7.70 +
7.71 +private:
7.72 +
7.73 +// first, some types:
7.74 + typedef unsigned int uint4; // assumes integer is 4 words long
7.75 + typedef unsigned short int uint2; // assumes short integer is 2 words long
7.76 + typedef unsigned char uint1; // assumes char is 1 word long
7.77 +
7.78 +// next, the private data:
7.79 + uint4 state[4];
7.80 + uint4 count[2]; // number of *bits*, mod 2^64
7.81 + uint1 buffer[64]; // input buffer
7.82 + uint1 digest[16];
7.83 + uint1 finalized;
7.84 +
7.85 +// last, the private methods, mostly static:
7.86 + void init (); // called by all constructors
7.87 + void transform (uint1 *buffer); // does the real update work. Note
7.88 + // that length is implied to be 64.
7.89 +
7.90 + static void encode (uint1 *dest, uint4 *src, uint4 length);
7.91 + static void decode (uint4 *dest, uint1 *src, uint4 length);
7.92 + static void memcpy (uint1 *dest, uint1 *src, uint4 length);
7.93 + static void memset (uint1 *start, uint1 val, uint4 length);
7.94 +
7.95 + static inline uint4 rotate_left (uint4 x, uint4 n);
7.96 + static inline uint4 F (uint4 x, uint4 y, uint4 z);
7.97 + static inline uint4 G (uint4 x, uint4 y, uint4 z);
7.98 + static inline uint4 H (uint4 x, uint4 y, uint4 z);
7.99 + static inline uint4 I (uint4 x, uint4 y, uint4 z);
7.100 + static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
7.101 + uint4 s, uint4 ac);
7.102 + static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
7.103 + uint4 s, uint4 ac);
7.104 + static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
7.105 + uint4 s, uint4 ac);
7.106 + static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
7.107 + uint4 s, uint4 ac);
7.108 +
7.109 +};
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/tools/gamedata md5/msvc9/gamedatamd5.sln Sun Jun 29 22:23:14 2008 +0000
8.3 @@ -0,0 +1,20 @@
8.4 +
8.5 +Microsoft Visual Studio Solution File, Format Version 10.00
8.6 +# Visual Studio 2008
8.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamedatamd5", "gamedatamd5.vcproj", "{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
8.8 +EndProject
8.9 +Global
8.10 + GlobalSection(SolutionConfigurationPlatforms) = preSolution
8.11 + Debug|Win32 = Debug|Win32
8.12 + Release|Win32 = Release|Win32
8.13 + EndGlobalSection
8.14 + GlobalSection(ProjectConfigurationPlatforms) = postSolution
8.15 + {E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.ActiveCfg = Debug|Win32
8.16 + {E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.Build.0 = Debug|Win32
8.17 + {E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.ActiveCfg = Release|Win32
8.18 + {E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.Build.0 = Release|Win32
8.19 + EndGlobalSection
8.20 + GlobalSection(SolutionProperties) = preSolution
8.21 + HideSolutionNode = FALSE
8.22 + EndGlobalSection
8.23 +EndGlobal
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/tools/gamedata md5/msvc9/gamedatamd5.vcproj Sun Jun 29 22:23:14 2008 +0000
9.3 @@ -0,0 +1,219 @@
9.4 +<?xml version="1.0" encoding="UTF-8"?>
9.5 +<VisualStudioProject
9.6 + ProjectType="Visual C++"
9.7 + Version="9.00"
9.8 + Name="gamedatamd5"
9.9 + ProjectGUID="{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
9.10 + Keyword="Win32Proj"
9.11 + TargetFrameworkVersion="0"
9.12 + >
9.13 + <Platforms>
9.14 + <Platform
9.15 + Name="Win32"
9.16 + />
9.17 + </Platforms>
9.18 + <ToolFiles>
9.19 + </ToolFiles>
9.20 + <Configurations>
9.21 + <Configuration
9.22 + Name="Debug|Win32"
9.23 + OutputDirectory="Debug"
9.24 + IntermediateDirectory="Debug"
9.25 + ConfigurationType="1"
9.26 + CharacterSet="2"
9.27 + >
9.28 + <Tool
9.29 + Name="VCPreBuildEventTool"
9.30 + />
9.31 + <Tool
9.32 + Name="VCCustomBuildTool"
9.33 + />
9.34 + <Tool
9.35 + Name="VCXMLDataGeneratorTool"
9.36 + />
9.37 + <Tool
9.38 + Name="VCWebServiceProxyGeneratorTool"
9.39 + />
9.40 + <Tool
9.41 + Name="VCMIDLTool"
9.42 + />
9.43 + <Tool
9.44 + Name="VCCLCompilerTool"
9.45 + Optimization="0"
9.46 + AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
9.47 + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
9.48 + MinimalRebuild="true"
9.49 + BasicRuntimeChecks="3"
9.50 + RuntimeLibrary="1"
9.51 + UsePrecompiledHeader="0"
9.52 + WarningLevel="3"
9.53 + Detect64BitPortabilityProblems="false"
9.54 + DebugInformationFormat="4"
9.55 + />
9.56 + <Tool
9.57 + Name="VCManagedResourceCompilerTool"
9.58 + />
9.59 + <Tool
9.60 + Name="VCResourceCompilerTool"
9.61 + />
9.62 + <Tool
9.63 + Name="VCPreLinkEventTool"
9.64 + />
9.65 + <Tool
9.66 + Name="VCLinkerTool"
9.67 + LinkIncremental="2"
9.68 + GenerateDebugInformation="true"
9.69 + SubSystem="1"
9.70 + TargetMachine="1"
9.71 + />
9.72 + <Tool
9.73 + Name="VCALinkTool"
9.74 + />
9.75 + <Tool
9.76 + Name="VCManifestTool"
9.77 + />
9.78 + <Tool
9.79 + Name="VCXDCMakeTool"
9.80 + />
9.81 + <Tool
9.82 + Name="VCBscMakeTool"
9.83 + />
9.84 + <Tool
9.85 + Name="VCFxCopTool"
9.86 + />
9.87 + <Tool
9.88 + Name="VCAppVerifierTool"
9.89 + />
9.90 + <Tool
9.91 + Name="VCPostBuildEventTool"
9.92 + />
9.93 + </Configuration>
9.94 + <Configuration
9.95 + Name="Release|Win32"
9.96 + OutputDirectory="Release"
9.97 + IntermediateDirectory="Release"
9.98 + ConfigurationType="1"
9.99 + >
9.100 + <Tool
9.101 + Name="VCPreBuildEventTool"
9.102 + />
9.103 + <Tool
9.104 + Name="VCCustomBuildTool"
9.105 + />
9.106 + <Tool
9.107 + Name="VCXMLDataGeneratorTool"
9.108 + />
9.109 + <Tool
9.110 + Name="VCWebServiceProxyGeneratorTool"
9.111 + />
9.112 + <Tool
9.113 + Name="VCMIDLTool"
9.114 + />
9.115 + <Tool
9.116 + Name="VCCLCompilerTool"
9.117 + AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
9.118 + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
9.119 + RuntimeLibrary="0"
9.120 + UsePrecompiledHeader="0"
9.121 + WarningLevel="3"
9.122 + Detect64BitPortabilityProblems="false"
9.123 + DebugInformationFormat="3"
9.124 + />
9.125 + <Tool
9.126 + Name="VCManagedResourceCompilerTool"
9.127 + />
9.128 + <Tool
9.129 + Name="VCResourceCompilerTool"
9.130 + />
9.131 + <Tool
9.132 + Name="VCPreLinkEventTool"
9.133 + />
9.134 + <Tool
9.135 + Name="VCLinkerTool"
9.136 + LinkIncremental="2"
9.137 + GenerateDebugInformation="true"
9.138 + SubSystem="1"
9.139 + OptimizeReferences="2"
9.140 + EnableCOMDATFolding="2"
9.141 + TargetMachine="1"
9.142 + />
9.143 + <Tool
9.144 + Name="VCALinkTool"
9.145 + />
9.146 + <Tool
9.147 + Name="VCManifestTool"
9.148 + />
9.149 + <Tool
9.150 + Name="VCXDCMakeTool"
9.151 + />
9.152 + <Tool
9.153 + Name="VCBscMakeTool"
9.154 + />
9.155 + <Tool
9.156 + Name="VCFxCopTool"
9.157 + />
9.158 + <Tool
9.159 + Name="VCAppVerifierTool"
9.160 + />
9.161 + <Tool
9.162 + Name="VCPostBuildEventTool"
9.163 + />
9.164 + </Configuration>
9.165 + </Configurations>
9.166 + <References>
9.167 + </References>
9.168 + <Files>
9.169 + <Filter
9.170 + Name="Header Files"
9.171 + Filter="h;hpp;hxx;hm;inl;inc;xsd"
9.172 + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
9.173 + >
9.174 + <File
9.175 + RelativePath="..\main.h"
9.176 + >
9.177 + </File>
9.178 + <File
9.179 + RelativePath="..\md5.h"
9.180 + >
9.181 + </File>
9.182 + <File
9.183 + RelativePath="..\sm_memtable.h"
9.184 + >
9.185 + </File>
9.186 + <File
9.187 + RelativePath="..\TextParsers.h"
9.188 + >
9.189 + </File>
9.190 + </Filter>
9.191 + <Filter
9.192 + Name="Resource Files"
9.193 + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
9.194 + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
9.195 + >
9.196 + </Filter>
9.197 + <Filter
9.198 + Name="Source Files"
9.199 + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
9.200 + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
9.201 + >
9.202 + <File
9.203 + RelativePath="..\main.cpp"
9.204 + >
9.205 + </File>
9.206 + <File
9.207 + RelativePath="..\md5.cpp"
9.208 + >
9.209 + </File>
9.210 + <File
9.211 + RelativePath="..\sm_memtable.cpp"
9.212 + >
9.213 + </File>
9.214 + <File
9.215 + RelativePath="..\TextParsers.cpp"
9.216 + >
9.217 + </File>
9.218 + </Filter>
9.219 + </Files>
9.220 + <Globals>
9.221 + </Globals>
9.222 +</VisualStudioProject>
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/tools/gamedata md5/sm_memtable.cpp Sun Jun 29 22:23:14 2008 +0000
10.3 @@ -0,0 +1,112 @@
10.4 +/**
10.5 + * vim: set ts=4 :
10.6 + * =============================================================================
10.7 + * SourceMod
10.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
10.9 + * =============================================================================
10.10 + *
10.11 + * This program is free software; you can redistribute it and/or modify it under
10.12 + * the terms of the GNU General Public License, version 3.0, as published by the
10.13 + * Free Software Foundation.
10.14 + *
10.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
10.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10.18 + * details.
10.19 + *
10.20 + * You should have received a copy of the GNU General Public License along with
10.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
10.22 + *
10.23 + * As a special exception, AlliedModders LLC gives you permission to link the
10.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
10.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
10.26 + * by the Valve Corporation. You must obey the GNU General Public License in
10.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
10.28 + * this exception to all derivative works. AlliedModders LLC defines further
10.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
10.30 + * or <http://www.sourcemod.net/license.php>.
10.31 + *
10.32 + * Version: $Id$
10.33 + */
10.34 +
10.35 +#include <string.h>
10.36 +#include <malloc.h>
10.37 +#include "sm_memtable.h"
10.38 +
10.39 +BaseMemTable::BaseMemTable(unsigned int init_size)
10.40 +{
10.41 + membase = (unsigned char *)malloc(init_size);
10.42 + size = init_size;
10.43 + tail = 0;
10.44 +}
10.45 +
10.46 +BaseMemTable::~BaseMemTable()
10.47 +{
10.48 + free(membase);
10.49 + membase = NULL;
10.50 +}
10.51 +
10.52 +int BaseMemTable::CreateMem(unsigned int addsize, void **addr)
10.53 +{
10.54 + int idx = (int)tail;
10.55 +
10.56 + while (tail + addsize >= size)
10.57 + {
10.58 + size *= 2;
10.59 + membase = (unsigned char *)realloc(membase, size);
10.60 + }
10.61 +
10.62 + tail += addsize;
10.63 +
10.64 + if (addr)
10.65 + {
10.66 + *addr = (void *)&membase[idx];
10.67 + }
10.68 +
10.69 + return idx;
10.70 +}
10.71 +
10.72 +void *BaseMemTable::GetAddress(int index)
10.73 +{
10.74 + if (index < 0 || (unsigned int)index >= tail)
10.75 + {
10.76 + return NULL;
10.77 + }
10.78 +
10.79 + return &membase[index];
10.80 +}
10.81 +
10.82 +void BaseMemTable::Reset()
10.83 +{
10.84 + tail = 0;
10.85 +}
10.86 +
10.87 +BaseStringTable::BaseStringTable(unsigned int init_size) : m_table(init_size)
10.88 +{
10.89 +}
10.90 +
10.91 +BaseStringTable::~BaseStringTable()
10.92 +{
10.93 +}
10.94 +
10.95 +int BaseStringTable::AddString(const char *string)
10.96 +{
10.97 + size_t len = strlen(string) + 1;
10.98 + int idx;
10.99 + char *addr;
10.100 +
10.101 + idx = m_table.CreateMem(len, (void **)&addr);
10.102 + strcpy(addr, string);
10.103 +
10.104 + return idx;
10.105 +}
10.106 +
10.107 +/*const char *BaseStringTable::GetString(int str)
10.108 +{
10.109 + return (const char *)m_table.GetAddress(str);
10.110 +}*/
10.111 +
10.112 +void BaseStringTable::Reset()
10.113 +{
10.114 + m_table.Reset();
10.115 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/tools/gamedata md5/sm_memtable.h Sun Jun 29 22:23:14 2008 +0000
11.3 @@ -0,0 +1,114 @@
11.4 +/**
11.5 + * vim: set ts=4 :
11.6 + * =============================================================================
11.7 + * SourceMod
11.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
11.9 + * =============================================================================
11.10 + *
11.11 + * This program is free software; you can redistribute it and/or modify it under
11.12 + * the terms of the GNU General Public License, version 3.0, as published by the
11.13 + * Free Software Foundation.
11.14 + *
11.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
11.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11.18 + * details.
11.19 + *
11.20 + * You should have received a copy of the GNU General Public License along with
11.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
11.22 + *
11.23 + * As a special exception, AlliedModders LLC gives you permission to link the
11.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
11.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
11.26 + * by the Valve Corporation. You must obey the GNU General Public License in
11.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
11.28 + * this exception to all derivative works. AlliedModders LLC defines further
11.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
11.30 + * or <http://www.sourcemod.net/license.php>.
11.31 + *
11.32 + * Version: $Id$
11.33 + */
11.34 +
11.35 +#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
11.36 +#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
11.37 +
11.38 +class BaseMemTable
11.39 +{
11.40 +public:
11.41 + BaseMemTable(unsigned int init_size);
11.42 + ~BaseMemTable();
11.43 +public:
11.44 + /**
11.45 + * Allocates 'size' bytes of memory.
11.46 + * Optionally outputs the address through 'addr'.
11.47 + * Returns an index >= 0 on success, < 0 on failure.
11.48 + */
11.49 + int CreateMem(unsigned int size, void **addr);
11.50 +
11.51 + /**
11.52 + * Given an index into the memory table, returns its address.
11.53 + * Returns NULL if invalid.
11.54 + */
11.55 + void *GetAddress(int index);
11.56 +
11.57 + /**
11.58 + * Scraps the memory table. For caching purposes, the memory
11.59 + * is not freed, however subsequent calls to CreateMem() will
11.60 + * begin at the first index again.
11.61 + */
11.62 + void Reset();
11.63 +
11.64 + inline unsigned int GetMemUsage()
11.65 + {
11.66 + return size;
11.67 + }
11.68 +
11.69 + inline unsigned int GetActualMemUsed()
11.70 + {
11.71 + return tail;
11.72 + }
11.73 +
11.74 +private:
11.75 + unsigned char *membase;
11.76 + unsigned int size;
11.77 + unsigned int tail;
11.78 +};
11.79 +
11.80 +class BaseStringTable
11.81 +{
11.82 +public:
11.83 + BaseStringTable(unsigned int init_size);
11.84 + ~BaseStringTable();
11.85 +public:
11.86 + /**
11.87 + * Adds a string to the string table and returns its index.
11.88 + */
11.89 + int AddString(const char *string);
11.90 +
11.91 + /**
11.92 + * Given an index into the string table, returns the associated string.
11.93 + */
11.94 + inline const char *GetString(int str)
11.95 + {
11.96 + return (const char *)m_table.GetAddress(str);
11.97 + }
11.98 +
11.99 + /**
11.100 + * Scraps the string table. For caching purposes, the memory
11.101 + * is not freed, however subsequent calls to AddString() will
11.102 + * begin at the first index again.
11.103 + */
11.104 + void Reset();
11.105 +
11.106 + /**
11.107 + * Returns the parent BaseMemTable that this string table uses.
11.108 + */
11.109 + inline BaseMemTable *GetMemTable()
11.110 + {
11.111 + return &m_table;
11.112 + }
11.113 +private:
11.114 + BaseMemTable m_table;
11.115 +};
11.116 +
11.117 +#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_