1/*-------------------------------------------------------------------------
2 * drawElements Base Portability Library
3 * -------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Basic string operations.
22 *//*--------------------------------------------------------------------*/
23
24#include "deString.h"
25
26#include <string.h>
27#include <stdlib.h>
28
29#include <stdio.h>
30#include <stdarg.h>
31
32#if (DE_COMPILER == DE_COMPILER_MSC)
33#	include <varargs.h>
34#endif
35
36DE_BEGIN_EXTERN_C
37
38/*--------------------------------------------------------------------*//*!
39 * \brief Compute hash from string.
40 * \param str	String to compute hash value for.
41 * \return Computed hash value.
42 *//*--------------------------------------------------------------------*/
43deUint32 deStringHash (const char* str)
44{
45	/* \note [pyry] This hash is used in DT_GNU_HASH and is proven
46	to be robust for symbol hashing. */
47	/* \see http://sources.redhat.com/ml/binutils/2006-06/msg00418.html */
48	deUint32 hash = 5381;
49	unsigned int c;
50
51	DE_ASSERT(str);
52	while ((c = (unsigned int)*str++) != 0)
53		hash = (hash << 5) + hash + c;
54
55	return hash;
56}
57
58deUint32 deStringHashLeading (const char* str, int numLeadingChars)
59{
60	deUint32 hash = 5381;
61	unsigned int c;
62
63	DE_ASSERT(str);
64	while (numLeadingChars-- && (c = (unsigned int)*str++) != 0)
65		hash = (hash << 5) + hash + c;
66
67	return hash;
68}
69
70deUint32 deMemoryHash (const void* ptr, size_t numBytes)
71{
72	/* \todo [2010-05-10 pyry] Better generic hash function? */
73	const deUint8*	input	= (const deUint8*)ptr;
74	deUint32		hash	= 5381;
75
76	DE_ASSERT(ptr);
77	while (numBytes--)
78		hash = (hash << 5) + hash + *input++;
79
80	return hash;
81}
82
83deBool deMemoryEqual (const void* ptr, const void* cmp, size_t numBytes)
84{
85	return memcmp(ptr, cmp, numBytes) == 0;
86}
87
88/*--------------------------------------------------------------------*//*!
89 * \brief Compare two strings for equality.
90 * \param a		First string.
91 * \param b		Second string.
92 * \return True if strings equal, false otherwise.
93 *//*--------------------------------------------------------------------*/
94deBool deStringEqual (const char* a, const char* b)
95{
96	DE_ASSERT(a && b);
97	return (strcmp(a, b) == 0);
98}
99
100deBool deStringBeginsWith (const char* str, const char* lead)
101{
102	const char* a = str;
103	const char* b = lead;
104
105	while (*b)
106	{
107		if (*a++ != *b++)
108			return DE_FALSE;
109	}
110
111	return DE_TRUE;
112}
113
114int deVsprintf (char* string, size_t size, const char* format, va_list list)
115{
116	int			res;
117
118	DE_ASSERT(string && format);
119
120#if (DE_COMPILER == DE_COMPILER_MSC)
121#	if (DE_OS == DE_OS_WINCE)
122	res = _vsnprintf(string, size, format, list);
123#	else
124	res = vsnprintf_s(string, size, _TRUNCATE, format, list);
125#	endif
126#else
127	res = vsnprintf(string, size, format, list);
128#endif
129
130	return res;
131}
132
133/*--------------------------------------------------------------------*//*!
134 * \brief 	Safe string print
135 * \note	This has the new safe signature, i.e., string length is a
136 *			required parameter.
137 *//*--------------------------------------------------------------------*/
138int deSprintf (char* string, size_t size, const char* format, ...)
139{
140	va_list		list;
141	int			res;
142
143	DE_ASSERT(string && format);
144
145	va_start(list, format);
146
147	res = deVsprintf(string, size, format, list);
148
149	va_end(list);
150
151	return res;
152}
153
154/*--------------------------------------------------------------------*//*!
155 * \note	This has the new safe signature, i.e., string length is a
156 *			required parameter.
157 *//*--------------------------------------------------------------------*/
158char* deStrcpy (char* dst, size_t size, const char* src)
159{
160#if (DE_COMPILER == DE_COMPILER_MSC) && (DE_OS != DE_OS_WINCE)
161	(void)strcpy_s(dst, size, src);
162	return dst;
163#else
164	return strncpy(dst, src, size);
165#endif
166}
167
168/*--------------------------------------------------------------------*//*!
169 * \note	This has the new safe signature, i.e., string length is a
170 *			required parameter.
171 *//*--------------------------------------------------------------------*/
172char* deStrcat (char* s1, size_t size, const char* s2)
173{
174#if (DE_COMPILER == DE_COMPILER_MSC) && (DE_OS != DE_OS_WINCE)
175	(void)strcat_s(s1, size, s2);
176	return s1;
177#else
178	return strncat(s1, s2, size);
179#endif
180}
181
182size_t deStrnlen (const char* string, size_t maxSize)
183{
184#if ((DE_COMPILER == DE_COMPILER_MSC) && (DE_OS != DE_OS_WINCE)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201100L))
185	return strnlen_s(string, maxSize);
186#else
187	size_t len = 0;
188	while (len < maxSize || string[len] != 0)
189		++len;
190	return len;
191#endif
192}
193
194DE_END_EXTERN_C
195