1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* ---- includes ----------------------------------------------------------- */
18
19#include "b_BasicEm/String.h"
20/*
21#include <stdlib.h>
22*/
23
24/* ---- related objects  --------------------------------------------------- */
25
26/* ---- typedefs ----------------------------------------------------------- */
27
28/* ---- constants ---------------------------------------------------------- */
29
30/* ------------------------------------------------------------------------- */
31
32/* ========================================================================= */
33/*                                                                           */
34/* ---- \ghd{ external functions } ----------------------------------------- */
35/*                                                                           */
36/* ========================================================================= */
37
38/* ------------------------------------------------------------------------- */
39
40char* bbs_strcpy( char* dstA, const char* srcA )
41{
42	const char* srcL = srcA;
43	char* dstL = dstA;
44	while( ( *dstL++ = *srcL++ ) != 0 );
45	return dstA;
46}
47
48/* ------------------------------------------------------------------------- */
49
50char* bbs_strncpy( char* dstA, const char* srcA, uint32 sizeA )
51{
52	uint32 iL;
53	for( iL = 0; iL < sizeA; iL++ )
54	{
55		if( ( dstA[ iL ] = srcA[ iL ] ) == 0 ) break;
56	}
57	if( iL == sizeA && sizeA > 0 ) dstA[ iL - 1 ] = 0;
58	return dstA;
59}
60
61/* ------------------------------------------------------------------------- */
62
63char* bbs_strcat( char* dstA, const char* srcA )
64{
65	const char* srcL = srcA;
66	char* dstL = dstA;
67	while( *dstL != 0 ) dstL++;
68	while( ( *dstL++ = *srcL++ ) != 0 );
69	return dstA;
70}
71
72/* ------------------------------------------------------------------------- */
73
74char* bbs_strncat( char* dstA, const char* srcA, uint32 sizeA )
75{
76	uint32 iL;
77	for( iL = 0; iL < sizeA; iL++ )
78	{
79		if( dstA[ iL ] == 0 ) break;
80	}
81
82	for( ; iL < sizeA; iL++ )
83	{
84		if( ( dstA[ iL ] = srcA[ iL ] ) == 0 ) break;
85	}
86
87	if( iL == sizeA && sizeA > 0 ) dstA[ iL - 1 ] = 0;
88
89	return dstA;
90}
91
92/* ------------------------------------------------------------------------- */
93
94uint32 bbs_strlen( const char* strA )
95{
96	uint32 iL = 0;
97	while( strA[ iL++ ] != 0 );
98	return iL - 1;
99}
100
101/* ------------------------------------------------------------------------- */
102
103flag bbs_strequal( const char* str1A, const char* str2A )
104{
105	const char* str1L = str1A;
106	const char* str2L = str2A;
107
108	if( str1L == NULL && str2L == NULL ) return TRUE;
109	if( str1L == NULL || str2L == NULL ) return FALSE;
110
111	while( ( *str1L != 0 ) && ( *str2L != 0 ) )
112	{
113		if( *str1L != *str2L ) break;
114		str1L++;
115		str2L++;
116	}
117
118	return *str1L == *str2L;
119}
120
121/* ------------------------------------------------------------------------- */
122
123flag bbs_strmatch( const char* str1A, const char* str2A )
124{
125	const char* str1L = str1A;
126	const char* str2L = str2A;
127
128	if( str1L == NULL || str2L == NULL ) return TRUE;
129
130	while( ( *str1L != 0 ) && ( *str2L != 0 ) )
131	{
132		if( *str1L != *str2L ) break;
133		str1L++;
134		str2L++;
135	}
136
137	if( *str1L == 0 || *str2L == 0 ) return TRUE;
138
139	return *str1L == *str2L;
140}
141
142/* ------------------------------------------------------------------------- */
143
144uint32 bbs_snprintf( char* bufA, uint32 bufSizeA, const char* formatA, ... )
145{
146	uint32 sizeL;
147	va_list argsL;
148	va_start( argsL, formatA );
149	sizeL = bbs_vsnprintf( bufA, bufSizeA, formatA, argsL );
150	va_end( argsL );
151	return sizeL;
152}
153
154/* ------------------------------------------------------------------------- */
155
156/* converts number to string without 0 termination - returns number of characters written */
157uint32 bbs_cString( int32 valA, char* dstA, uint32 bufSizeA )
158{
159	uint32 valL = ( valA < 0 ) ? -valA : valA;
160	uint32 iL = 0;
161	uint32 digitsL = 0;
162	if( valA < 0 )
163	{
164		if( iL < bufSizeA ) dstA[ iL++ ] = '-';
165	}
166
167	/* count #digits */
168	if( valL == 0 )
169	{
170		iL++;
171	}
172	else
173	{
174		while( valL > 0 )
175		{
176			iL++;
177			valL /= 10;
178		}
179	}
180
181	digitsL = ( iL > bufSizeA ) ? bufSizeA : iL;
182
183	valL = ( valA < 0 ) ? -valA : valA;
184
185	if( valL == 0 )
186	{
187		if( iL < bufSizeA ) dstA[ --iL ] = '0';
188	}
189	else
190	{
191		while( valL > 0 )
192		{
193			if( iL < bufSizeA ) dstA[ --iL ] = '0' + ( valL % 10 );
194			valL /= 10;
195		}
196	}
197
198	return digitsL;
199}
200
201/* ------------------------------------------------------------------------- */
202
203uint32 bbs_vsnprintf( char* bufA, uint32 bufSizeA, const char* formatA, va_list argsA )
204{
205	const char* fpL = formatA;
206	uint32 iL = 0;
207
208	while( *fpL != 0 )
209	{
210		if( *fpL == '%' )
211		{
212			if( *( fpL + 1 ) == 'i' || *( fpL + 1 ) == 'd' )
213			{
214				int valL = va_arg( argsA, int );
215				if( iL < bufSizeA )
216				{
217					iL += bbs_cString( valL, bufA + iL, bufSizeA - iL );
218				}
219				fpL += 2;
220			}
221			else if( *( fpL + 1 ) == 's' )
222			{
223				const char* stringL = va_arg( argsA, char* );
224				if( iL < bufSizeA )
225				{
226					bufA[ iL ] = 0;
227					bbs_strncat( bufA + iL, stringL, bufSizeA - iL );
228					iL += bbs_strlen( stringL );
229				}
230				fpL += 2;
231			}
232			else if( *( fpL + 1 ) == '%' )
233			{
234				if( iL < bufSizeA ) bufA[ iL++ ] = '%';
235				fpL++;
236			}
237			else
238			{
239				if( iL < bufSizeA ) bufA[ iL++ ] = *fpL;
240				fpL++;
241			}
242		}
243		else
244		{
245			if( iL < bufSizeA ) bufA[ iL++ ] = *fpL;
246			fpL++;
247		}
248	}
249
250	if( iL < bufSizeA )
251	{
252		bufA[ iL ] = 0;
253	}
254	else if( bufSizeA > 0 )
255	{
256		bufA[ bufSizeA - 1 ] = 0;
257	}
258
259	return iL;
260}
261
262/* ------------------------------------------------------------------------- */
263
264int32 bbs_atoi( const char* strA )
265{
266	int32 valL = 0;
267	int16 signL = 1;
268	uint16 iL = 0, lenL = bbs_strlen( strA );
269
270	while( iL < lenL && strA[ iL ] == ' ' ) iL++;
271	if( strA[ iL ] == '-' )
272	{
273		signL = -1;
274		iL++;
275	}
276	while( iL < lenL && strA[ iL ] == ' ' ) iL++;
277	while( iL < lenL && strA[ iL ] >= '0' && strA[ iL ] <= '9' )
278	{
279		valL = valL * 10 + ( strA[ iL ] - '0' );
280		iL++;
281	}
282	return valL * signL;
283}
284
285/* ------------------------------------------------------------------------- */
286
287