src/string.cpp
author truebrain
Mon, 16 Jun 2008 14:43:19 +0000
branchnoai
changeset 10978 13fd0364b2c6
parent 10455 22c441f5adf9
permissions -rw-r--r--
(svn r13532) [NoAI] -Fix: in MultiPlayer SignID wasn't set correctly, causing weird effects. Code is now more unified, which should avoid simular effects in the future (tnx to glx for initial patch)
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     1
/* $Id$ */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     2
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents: 9724
diff changeset
     3
/** @file string.cpp Handling of C-type strings (char*). */
9574
698395509d12 (svn r9575) [NoAI] -Sync with trunk r9504:9574
glx
parents: 6600
diff changeset
     4
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     5
#include "stdafx.h"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     6
#include "openttd.h"
9686
d3c195c226f9 (svn r10636) [NoAI] -Sync with trunk r10532:10635.
rubidium
parents: 9574
diff changeset
     7
#include "debug.h"
9723
eee46cb39750 (svn r11796) [NoAI] -Sync: with trunk r11502:11795.
rubidium
parents: 9722
diff changeset
     8
#include "core/alloc_func.hpp"
eee46cb39750 (svn r11796) [NoAI] -Sync: with trunk r11502:11795.
rubidium
parents: 9722
diff changeset
     9
#include "string_func.h"
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    10
9724
b39bc69bb2f2 (svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents: 9723
diff changeset
    11
#include "table/control_codes.h"
b39bc69bb2f2 (svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents: 9723
diff changeset
    12
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    13
#include <stdarg.h>
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    14
#include <ctype.h> // required for tolower()
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    15
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    16
void ttd_strlcat(char *dst, const char *src, size_t size)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    17
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    18
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    19
	for (; size > 0 && *dst != '\0'; --size, ++dst) {}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    20
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    21
	while (--size > 0 && *src != '\0') *dst++ = *src++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    22
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    23
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    24
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    25
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    26
void ttd_strlcpy(char *dst, const char *src, size_t size)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    27
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    28
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    29
	while (--size > 0 && *src != '\0') *dst++ = *src++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    30
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    31
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    32
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    33
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    34
char* strecat(char* dst, const char* src, const char* last)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    35
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    36
	assert(dst <= last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    37
	for (; *dst != '\0'; ++dst)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    38
		if (dst == last) return dst;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    39
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    40
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    41
	return strecpy(dst, src, last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    42
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    43
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    44
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    45
char* strecpy(char* dst, const char* src, const char* last)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    46
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    47
	assert(dst <= last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    48
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    49
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    50
	if (dst == last && *src != '\0') {
9686
d3c195c226f9 (svn r10636) [NoAI] -Sync with trunk r10532:10635.
rubidium
parents: 9574
diff changeset
    51
#ifdef STRGEN
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    52
		error("String too long for destination buffer");
9686
d3c195c226f9 (svn r10636) [NoAI] -Sync with trunk r10532:10635.
rubidium
parents: 9574
diff changeset
    53
#else /* STRGEN */
d3c195c226f9 (svn r10636) [NoAI] -Sync with trunk r10532:10635.
rubidium
parents: 9574
diff changeset
    54
		DEBUG(misc, 0, "String too long for destination buffer");
d3c195c226f9 (svn r10636) [NoAI] -Sync with trunk r10532:10635.
rubidium
parents: 9574
diff changeset
    55
		*dst = '\0';
d3c195c226f9 (svn r10636) [NoAI] -Sync with trunk r10532:10635.
rubidium
parents: 9574
diff changeset
    56
#endif /* STRGEN */
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    57
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    58
	return dst;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    59
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    60
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    61
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    62
char* CDECL str_fmt(const char* str, ...)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    63
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    64
	char buf[4096];
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    65
	va_list va;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    66
	int len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    67
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    68
	va_start(va, str);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    69
	len = vsnprintf(buf, lengthof(buf), str, va);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    70
	va_end(va);
5860
7fdc9b423ba1 (svn r8066) - Codechange: MallocT(), CallocT(), ReallocT() now return the pointer to allocated memory instead of modifying the pointer given as parameter
KUDr
parents: 5838
diff changeset
    71
	char* p = MallocT<char>(len + 1);
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    72
	if (p != NULL) memcpy(p, buf, len + 1);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    73
	return p;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    74
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    75
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    76
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    77
void str_validate(char *str)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    78
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    79
	char *dst = str;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    80
	WChar c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    81
	size_t len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    82
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    83
	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    84
		if (IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END ||
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    85
			IsValidChar(c - SCC_SPRITE_START, CS_ALPHANUMERAL))) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    86
			/* Copy the character back. Even if dst is current the same as str
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    87
			 * (i.e. no characters have been changed) this is quicker than
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    88
			 * moving the pointers ahead by len */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    89
			do {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    90
				*dst++ = *str++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    91
			} while (--len != 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    92
		} else {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    93
			/* Replace the undesirable character with a question mark */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    94
			str += len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    95
			*dst++ = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    96
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    97
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    98
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    99
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   100
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   101
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   102
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   103
void str_strip_colours(char *str)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   104
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   105
	char *dst = str;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   106
	WChar c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   107
	size_t len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   108
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   109
	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   110
		if (c < SCC_BLUE || c > SCC_BLACK) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   111
			/* Copy the character back. Even if dst is current the same as str
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   112
			 * (i.e. no characters have been changed) this is quicker than
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   113
			 * moving the pointers ahead by len */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   114
			do {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   115
				*dst++ = *str++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   116
			} while (--len != 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   117
		} else {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   118
			/* Just skip (strip) the colour codes */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   119
			str += len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   120
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   121
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   122
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   123
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   124
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   125
/** Convert a given ASCII string to lowercase.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   126
 * NOTE: only support ASCII characters, no UTF8 fancy. As currently
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   127
 * the function is only used to lowercase data-filenames if they are
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   128
 * not found, this is sufficient. If more, or general functionality is
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   129
 * needed, look to r7271 where it was removed because it was broken when
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   130
 * using certain locales: eg in Turkish the uppercase 'I' was converted to
9574
698395509d12 (svn r9575) [NoAI] -Sync with trunk r9504:9574
glx
parents: 6600
diff changeset
   131
 * '?', so just revert to the old functionality
698395509d12 (svn r9575) [NoAI] -Sync with trunk r9504:9574
glx
parents: 6600
diff changeset
   132
 * @param str string to convert */
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   133
void strtolower(char *str)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   134
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   135
	for (; *str != '\0'; str++) *str = tolower(*str);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   136
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   137
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   138
/**
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   139
 * Only allow certain keys. You can define the filter to be used. This makes
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   140
 *  sure no invalid keys can get into an editbox, like BELL.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   141
 * @param key character to be checked
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   142
 * @param afilter the filter to use
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   143
 * @return true or false depending if the character is printable/valid or not
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   144
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   145
bool IsValidChar(WChar key, CharSetFilter afilter)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   146
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   147
	switch (afilter) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   148
		case CS_ALPHANUMERAL: return IsPrintable(key);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   149
		case CS_NUMERAL:      return (key >= '0' && key <= '9');
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   150
		case CS_ALPHA:        return IsPrintable(key) && !(key >= '0' && key <= '9');
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   151
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   152
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   153
	return false;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   154
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   155
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   156
#ifdef WIN32
9723
eee46cb39750 (svn r11796) [NoAI] -Sync: with trunk r11502:11795.
rubidium
parents: 9722
diff changeset
   157
/* Since version 3.14, MinGW Runtime has snprintf() and vsnprintf() conform to C99 but it's not the case for older versions */
eee46cb39750 (svn r11796) [NoAI] -Sync: with trunk r11502:11795.
rubidium
parents: 9722
diff changeset
   158
#if (__MINGW32_MAJOR_VERSION < 3) || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION < 14))
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   159
int CDECL snprintf(char *str, size_t size, const char *format, ...)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   160
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   161
	va_list ap;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   162
	int ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   163
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   164
	va_start(ap, format);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   165
	ret = vsnprintf(str, size, format, ap);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   166
	va_end(ap);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   167
	return ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   168
}
9723
eee46cb39750 (svn r11796) [NoAI] -Sync: with trunk r11502:11795.
rubidium
parents: 9722
diff changeset
   169
#endif /* MinGW Runtime < 3.14 */
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   170
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   171
#ifdef _MSC_VER
5881
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   172
/* *nprintf broken, not POSIX compliant, MSDN description
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   173
 * - If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   174
 * - If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   175
 * - If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   176
 */
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   177
int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   178
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   179
	int ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   180
	ret = _vsnprintf(str, size, format, ap);
5882
5ba219322829 (svn r8090) -[win32] Fix (r8089): for *nprintf 'ret = count' NOT 'ret = 0'...
Darkvater
parents: 5881
diff changeset
   181
	if (ret < 0 || ret == size) str[size - 1] = '\0';
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   182
	return ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   183
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   184
#endif /* _MSC_VER */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   185
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   186
#endif /* WIN32 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   187
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   188
5885
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   189
/** Convert the md5sum to a hexadecimal string representation
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   190
 * @param buf buffer to put the md5sum into
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   191
 * @param last last character of buffer (usually lastof(buf))
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   192
 * @param md5sum the md5sum itself
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   193
 * @return a pointer to the next character after the md5sum */
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   194
char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   195
{
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   196
	char *p = buf;
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   197
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   198
	for (uint i = 0; i < 16; i++) {
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   199
		p += snprintf(p, last + 1 - p, "%02X", md5sum[i]);
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   200
		if (p >= last) break;
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   201
	}
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   202
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   203
	return p;
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   204
}
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   205
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   206
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   207
/* UTF-8 handling routines */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   208
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   209
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   210
/* Decode and consume the next UTF-8 encoded character
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   211
 * @param c Buffer to place decoded character.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   212
 * @param s Character stream to retrieve character from.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   213
 * @return Number of characters in the sequence.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   214
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   215
size_t Utf8Decode(WChar *c, const char *s)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   216
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   217
	assert(c != NULL);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   218
9722
ebf0ece7d8f6 (svn r11503) [NoAI] -Sync: with trunk r11308:11502.
rubidium
parents: 9686
diff changeset
   219
	if (!HasBit(s[0], 7)) {
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   220
		/* Single byte character: 0xxxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   221
		*c = s[0];
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   222
		return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   223
	} else if (GB(s[0], 5, 3) == 6) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   224
		if (IsUtf8Part(s[1])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   225
			/* Double byte character: 110xxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   226
			*c = GB(s[0], 0, 5) << 6 | GB(s[1], 0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   227
			if (*c >= 0x80) return 2;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   228
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   229
	} else if (GB(s[0], 4, 4) == 14) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   230
		if (IsUtf8Part(s[1]) && IsUtf8Part(s[2])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   231
			/* Triple byte character: 1110xxxx 10xxxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   232
			*c = GB(s[0], 0, 4) << 12 | GB(s[1], 0, 6) << 6 | GB(s[2], 0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   233
			if (*c >= 0x800) return 3;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   234
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   235
	} else if (GB(s[0], 3, 5) == 30) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   236
		if (IsUtf8Part(s[1]) && IsUtf8Part(s[2]) && IsUtf8Part(s[3])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   237
			/* 4 byte character: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   238
			*c = GB(s[0], 0, 3) << 18 | GB(s[1], 0, 6) << 12 | GB(s[2], 0, 6) << 6 | GB(s[3], 0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   239
			if (*c >= 0x10000 && *c <= 0x10FFFF) return 4;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   240
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   241
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   242
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   243
	//DEBUG(misc, 1, "[utf8] invalid UTF-8 sequence");
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   244
	*c = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   245
	return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   246
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   247
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   248
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   249
/* Encode a unicode character and place it in the buffer
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   250
 * @param buf Buffer to place character.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   251
 * @param c   Unicode character to encode.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   252
 * @return Number of characters in the encoded sequence.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   253
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   254
size_t Utf8Encode(char *buf, WChar c)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   255
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   256
	if (c < 0x80) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   257
		*buf = c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   258
		return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   259
	} else if (c < 0x800) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   260
		*buf++ = 0xC0 + GB(c,  6, 5);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   261
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   262
		return 2;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   263
	} else if (c < 0x10000) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   264
		*buf++ = 0xE0 + GB(c, 12, 4);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   265
		*buf++ = 0x80 + GB(c,  6, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   266
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   267
		return 3;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   268
	} else if (c < 0x110000) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   269
		*buf++ = 0xF0 + GB(c, 18, 3);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   270
		*buf++ = 0x80 + GB(c, 12, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   271
		*buf++ = 0x80 + GB(c,  6, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   272
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   273
		return 4;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   274
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   275
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   276
	//DEBUG(misc, 1, "[utf8] can't UTF-8 encode value 0x%X", c);
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   277
	*buf = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   278
	return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   279
}
6541
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   280
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   281
/**
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   282
 * Properly terminate an UTF8 string to some maximum length
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   283
 * @param s string to check if it needs additional trimming
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   284
 * @param maxlen the maximum length the buffer can have.
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   285
 * @return the new length in bytes of the string (eg. strlen(new_string))
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   286
 * @NOTE maxlen is the string length _INCLUDING_ the terminating '\0'
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   287
 */
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   288
size_t Utf8TrimString(char *s, size_t maxlen)
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   289
{
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   290
	size_t length = 0;
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   291
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   292
	for (const char *ptr = strchr(s, '\0'); *s != '\0';) {
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   293
		size_t len = Utf8EncodedCharLen(*s);
6600
f7b2ffd75b35 (svn r9083) -Codechange: Be more lenient when trimming UTF-8 strings and don't terminate the string when an invalid encoding is encountered, but only focus on maximum length.
Darkvater
parents: 6544
diff changeset
   294
		/* Silently ignore invalid UTF8 sequences, our only concern trimming */
f7b2ffd75b35 (svn r9083) -Codechange: Be more lenient when trimming UTF-8 strings and don't terminate the string when an invalid encoding is encountered, but only focus on maximum length.
Darkvater
parents: 6544
diff changeset
   295
		if (len == 0) len = 1;
6541
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   296
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   297
		/* Take care when a hard cutoff was made for the string and
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   298
		 * the last UTF8 sequence is invalid */
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   299
		if (length + len >= maxlen || (s + len > ptr)) break;
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   300
		s += len;
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   301
		length += len;
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   302
	}
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   303
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   304
	*s = '\0';
ff575414f0d2 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5885
diff changeset
   305
	return length;
6544
a5f64ee6e4d6 (svn r9015) -Fix
tron
parents: 6541
diff changeset
   306
}