PageRenderTime 60ms CodeModel.GetById 11ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llui/lltextvalidate.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 347 lines | 274 code | 30 blank | 43 comment | 66 complexity | 4c621c335994e1d7b95e8d2cb6c2a3d5 MD5 | raw file
  1/** 
  2 * @file lltextvalidate.cpp
  3 * @brief Text validation helper functions
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27// Text editor widget to let users enter a single line.
 28
 29#include "linden_common.h"
 30 
 31#include "lltextvalidate.h"
 32#include "llresmgr.h" // for LLLocale
 33
 34namespace LLTextValidate
 35{
 36	void ValidateTextNamedFuncs::declareValues()
 37	{
 38		declare("ascii", validateASCII);
 39		declare("float", validateFloat);
 40		declare("int", validateInt);
 41		declare("positive_s32", validatePositiveS32);
 42		declare("non_negative_s32", validateNonNegativeS32);
 43		declare("alpha_num", validateAlphaNum);
 44		declare("alpha_num_space", validateAlphaNumSpace);
 45		declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe);
 46		declare("ascii_printable_no_space", validateASCIIPrintableNoSpace);
 47		declare("ascii_with_newline", validateASCIIWithNewLine);
 48	}
 49
 50	// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position.
 51	// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
 52	// the simple reasons that intermediate states may be invalid even if the final result is valid.
 53	// 
 54	bool validateFloat(const LLWString &str)
 55	{
 56		LLLocale locale(LLLocale::USER_LOCALE);
 57
 58		bool success = TRUE;
 59		LLWString trimmed = str;
 60		LLWStringUtil::trim(trimmed);
 61		S32 len = trimmed.length();
 62		if( 0 < len )
 63		{
 64			// May be a comma or period, depending on the locale
 65			llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
 66
 67			S32 i = 0;
 68
 69			// First character can be a negative sign
 70			if( '-' == trimmed[0] )
 71			{
 72				i++;
 73			}
 74
 75			for( ; i < len; i++ )
 76			{
 77				if( (decimal_point != trimmed[i] ) && !LLStringOps::isDigit( trimmed[i] ) )
 78				{
 79					success = FALSE;
 80					break;
 81				}
 82			}
 83		}		
 84
 85		return success;
 86	}
 87
 88	// Limits what characters can be used to [1234567890-] with [-] only valid in the first position.
 89	// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
 90	// the simple reasons that intermediate states may be invalid even if the final result is valid.
 91	//
 92	bool validateInt(const LLWString &str)
 93	{
 94		LLLocale locale(LLLocale::USER_LOCALE);
 95
 96		bool success = TRUE;
 97		LLWString trimmed = str;
 98		LLWStringUtil::trim(trimmed);
 99		S32 len = trimmed.length();
100		if( 0 < len )
101		{
102			S32 i = 0;
103
104			// First character can be a negative sign
105			if( '-' == trimmed[0] )
106			{
107				i++;
108			}
109
110			for( ; i < len; i++ )
111			{
112				if( !LLStringOps::isDigit( trimmed[i] ) )
113				{
114					success = FALSE;
115					break;
116				}
117			}
118		}		
119
120		return success;
121	}
122
123	bool validatePositiveS32(const LLWString &str)
124	{
125		LLLocale locale(LLLocale::USER_LOCALE);
126
127		LLWString trimmed = str;
128		LLWStringUtil::trim(trimmed);
129		S32 len = trimmed.length();
130		bool success = TRUE;
131		if(0 < len)
132		{
133			if(('-' == trimmed[0]) || ('0' == trimmed[0]))
134			{
135				success = FALSE;
136			}
137			S32 i = 0;
138			while(success && (i < len))
139			{
140				if(!LLStringOps::isDigit(trimmed[i++]))
141				{
142					success = FALSE;
143				}
144			}
145		}
146		if (success)
147		{
148			S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
149			if (val <= 0)
150			{
151				success = FALSE;
152			}
153		}
154		return success;
155	}
156
157	bool validateNonNegativeS32(const LLWString &str)
158	{
159		LLLocale locale(LLLocale::USER_LOCALE);
160
161		LLWString trimmed = str;
162		LLWStringUtil::trim(trimmed);
163		S32 len = trimmed.length();
164		bool success = TRUE;
165		if(0 < len)
166		{
167			if('-' == trimmed[0])
168			{
169				success = FALSE;
170			}
171			S32 i = 0;
172			while(success && (i < len))
173			{
174				if(!LLStringOps::isDigit(trimmed[i++]))
175				{
176					success = FALSE;
177				}
178			}
179		}
180		if (success)
181		{
182			S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
183			if (val < 0)
184			{
185				success = FALSE;
186			}
187		}
188		return success;
189	}
190
191	bool validateNonNegativeS32NoSpace(const LLWString &str)
192	{
193		LLLocale locale(LLLocale::USER_LOCALE);
194
195		LLWString test_str = str;
196		S32 len = test_str.length();
197		bool success = TRUE;
198		if(0 < len)
199		{
200			if('-' == test_str[0])
201			{
202				success = FALSE;
203			}
204			S32 i = 0;
205			while(success && (i < len))
206			{
207				if(!LLStringOps::isDigit(test_str[i]) || LLStringOps::isSpace(test_str[i++]))
208				{
209					success = FALSE;
210				}
211			}
212		}
213		if (success)
214		{
215			S32 val = strtol(wstring_to_utf8str(test_str).c_str(), NULL, 10);
216			if (val < 0)
217			{
218				success = FALSE;
219			}
220		}
221		return success;
222	}
223
224	bool validateAlphaNum(const LLWString &str)
225	{
226		LLLocale locale(LLLocale::USER_LOCALE);
227
228		bool rv = TRUE;
229		S32 len = str.length();
230		if(len == 0) return rv;
231		while(len--)
232		{
233			if( !LLStringOps::isAlnum((char)str[len]) )
234			{
235				rv = FALSE;
236				break;
237			}
238		}
239		return rv;
240	}
241
242	bool validateAlphaNumSpace(const LLWString &str)
243	{
244		LLLocale locale(LLLocale::USER_LOCALE);
245
246		bool rv = TRUE;
247		S32 len = str.length();
248		if(len == 0) return rv;
249		while(len--)
250		{
251			if(!(LLStringOps::isAlnum((char)str[len]) || (' ' == str[len])))
252			{
253				rv = FALSE;
254				break;
255			}
256		}
257		return rv;
258	}
259
260	// Used for most names of things stored on the server, due to old file-formats
261	// that used the pipe (|) for multiline text storage.  Examples include
262	// inventory item names, parcel names, object names, etc.
263	bool validateASCIIPrintableNoPipe(const LLWString &str)
264	{
265		bool rv = TRUE;
266		S32 len = str.length();
267		if(len == 0) return rv;
268		while(len--)
269		{
270			llwchar wc = str[len];
271			if (wc < 0x20
272				|| wc > 0x7f
273				|| wc == '|')
274			{
275				rv = FALSE;
276				break;
277			}
278			if(!(wc == ' '
279				 || LLStringOps::isAlnum((char)wc)
280				 || LLStringOps::isPunct((char)wc) ) )
281			{
282				rv = FALSE;
283				break;
284			}
285		}
286		return rv;
287	}
288
289
290	// Used for avatar names
291	bool validateASCIIPrintableNoSpace(const LLWString &str)
292	{
293		bool rv = TRUE;
294		S32 len = str.length();
295		if(len == 0) return rv;
296		while(len--)
297		{
298			llwchar wc = str[len];
299			if (wc < 0x20
300				|| wc > 0x7f
301				|| LLStringOps::isSpace(wc))
302			{
303				rv = FALSE;
304				break;
305			}
306			if( !(LLStringOps::isAlnum((char)str[len]) ||
307				  LLStringOps::isPunct((char)str[len]) ) )
308			{
309				rv = FALSE;
310				break;
311			}
312		}
313		return rv;
314	}
315
316	bool validateASCII(const LLWString &str)
317	{
318		bool rv = TRUE;
319		S32 len = str.length();
320		while(len--)
321		{
322			if (str[len] < 0x20 || str[len] > 0x7f)
323			{
324				rv = FALSE;
325				break;
326			}
327		}
328		return rv;
329	}
330
331	// Used for multiline text stored on the server.
332	// Example is landmark description in Places SP.
333	bool validateASCIIWithNewLine(const LLWString &str)
334	{
335		bool rv = TRUE;
336		S32 len = str.length();
337		while(len--)
338		{
339			if (str[len] < 0x20 && str[len] != 0xA || str[len] > 0x7f)
340			{
341				rv = FALSE;
342				break;
343			}
344		}
345		return rv;
346	}
347}