rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41
|
nuclear@0
|
42 /** @file ParsingUtils.h
|
nuclear@0
|
43 * @brief Defines helper functions for text parsing
|
nuclear@0
|
44 */
|
nuclear@0
|
45 #ifndef AI_PARSING_UTILS_H_INC
|
nuclear@0
|
46 #define AI_PARSING_UTILS_H_INC
|
nuclear@0
|
47
|
nuclear@0
|
48 #include "StringComparison.h"
|
nuclear@0
|
49 namespace Assimp {
|
nuclear@0
|
50
|
nuclear@0
|
51 // NOTE: the functions below are mostly intended as replacement for
|
nuclear@0
|
52 // std::upper, std::lower, std::isupper, std::islower, std::isspace.
|
nuclear@0
|
53 // we don't bother of locales. We don't want them. We want reliable
|
nuclear@0
|
54 // (i.e. identical) results across all locales.
|
nuclear@0
|
55
|
nuclear@0
|
56 // The functions below accept any character type, but know only
|
nuclear@0
|
57 // about ASCII. However, UTF-32 is the only safe ASCII superset to
|
nuclear@0
|
58 // use since it doesn't have multibyte sequences.
|
nuclear@0
|
59
|
nuclear@0
|
60 // ---------------------------------------------------------------------------------
|
nuclear@0
|
61 template <class char_t>
|
nuclear@0
|
62 AI_FORCE_INLINE char_t ToLower( char_t in)
|
nuclear@0
|
63 {
|
nuclear@0
|
64 return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in;
|
nuclear@0
|
65 }
|
nuclear@0
|
66 // ---------------------------------------------------------------------------------
|
nuclear@0
|
67 template <class char_t>
|
nuclear@0
|
68 AI_FORCE_INLINE char_t ToUpper( char_t in)
|
nuclear@0
|
69 {
|
nuclear@0
|
70 return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
|
nuclear@0
|
71 }
|
nuclear@0
|
72 // ---------------------------------------------------------------------------------
|
nuclear@0
|
73 template <class char_t>
|
nuclear@0
|
74 AI_FORCE_INLINE bool IsUpper( char_t in)
|
nuclear@0
|
75 {
|
nuclear@0
|
76 return (in >= (char_t)'A' && in <= (char_t)'Z');
|
nuclear@0
|
77 }
|
nuclear@0
|
78 // ---------------------------------------------------------------------------------
|
nuclear@0
|
79 template <class char_t>
|
nuclear@0
|
80 AI_FORCE_INLINE bool IsLower( char_t in)
|
nuclear@0
|
81 {
|
nuclear@0
|
82 return (in >= (char_t)'a' && in <= (char_t)'z');
|
nuclear@0
|
83 }
|
nuclear@0
|
84 // ---------------------------------------------------------------------------------
|
nuclear@0
|
85 template <class char_t>
|
nuclear@0
|
86 AI_FORCE_INLINE bool IsSpace( char_t in)
|
nuclear@0
|
87 {
|
nuclear@0
|
88 return (in == (char_t)' ' || in == (char_t)'\t');
|
nuclear@0
|
89 }
|
nuclear@0
|
90 // ---------------------------------------------------------------------------------
|
nuclear@0
|
91 template <class char_t>
|
nuclear@0
|
92 AI_FORCE_INLINE bool IsLineEnd( char_t in)
|
nuclear@0
|
93 {
|
nuclear@0
|
94 return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
|
nuclear@0
|
95 }
|
nuclear@0
|
96 // ---------------------------------------------------------------------------------
|
nuclear@0
|
97 template <class char_t>
|
nuclear@0
|
98 AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
|
nuclear@0
|
99 {
|
nuclear@0
|
100 return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
|
nuclear@0
|
101 }
|
nuclear@0
|
102 // ---------------------------------------------------------------------------------
|
nuclear@0
|
103 template <class char_t>
|
nuclear@0
|
104 AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
|
nuclear@0
|
105 {
|
nuclear@0
|
106 while (*in == (char_t)' ' || *in == (char_t)'\t')in++;
|
nuclear@0
|
107 *out = in;
|
nuclear@0
|
108 return !IsLineEnd<char_t>(*in);
|
nuclear@0
|
109 }
|
nuclear@0
|
110 // ---------------------------------------------------------------------------------
|
nuclear@0
|
111 template <class char_t>
|
nuclear@0
|
112 AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
|
nuclear@0
|
113 {
|
nuclear@0
|
114 return SkipSpaces<char_t>(*inout,inout);
|
nuclear@0
|
115 }
|
nuclear@0
|
116 // ---------------------------------------------------------------------------------
|
nuclear@0
|
117 template <class char_t>
|
nuclear@0
|
118 inline bool SkipLine( const char_t* in, const char_t** out)
|
nuclear@0
|
119 {
|
nuclear@0
|
120 while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++;
|
nuclear@0
|
121
|
nuclear@0
|
122 // files are opened in binary mode. Ergo there are both NL and CR
|
nuclear@0
|
123 while (*in == (char_t)'\r' || *in == (char_t)'\n')in++;
|
nuclear@0
|
124 *out = in;
|
nuclear@0
|
125 return *in != (char_t)'\0';
|
nuclear@0
|
126 }
|
nuclear@0
|
127 // ---------------------------------------------------------------------------------
|
nuclear@0
|
128 template <class char_t>
|
nuclear@0
|
129 inline bool SkipLine( const char_t** inout)
|
nuclear@0
|
130 {
|
nuclear@0
|
131 return SkipLine<char_t>(*inout,inout);
|
nuclear@0
|
132 }
|
nuclear@0
|
133 // ---------------------------------------------------------------------------------
|
nuclear@0
|
134 template <class char_t>
|
nuclear@0
|
135 inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
|
nuclear@0
|
136 {
|
nuclear@0
|
137 while (*in == (char_t)' ' || *in == (char_t)'\t' ||
|
nuclear@0
|
138 *in == (char_t)'\r' || *in == (char_t)'\n')in++;
|
nuclear@0
|
139 *out = in;
|
nuclear@0
|
140 return *in != '\0';
|
nuclear@0
|
141 }
|
nuclear@0
|
142 // ---------------------------------------------------------------------------------
|
nuclear@0
|
143 template <class char_t>
|
nuclear@0
|
144 inline bool SkipSpacesAndLineEnd( const char_t** inout)
|
nuclear@0
|
145 {
|
nuclear@0
|
146 return SkipSpacesAndLineEnd<char_t>(*inout,inout);
|
nuclear@0
|
147 }
|
nuclear@0
|
148 // ---------------------------------------------------------------------------------
|
nuclear@0
|
149 template <class char_t>
|
nuclear@0
|
150 inline bool GetNextLine(const char_t*& buffer, char_t out[4096])
|
nuclear@0
|
151 {
|
nuclear@0
|
152 if ((char_t)'\0' == *buffer)return false;
|
nuclear@0
|
153
|
nuclear@0
|
154 char* _out = out;
|
nuclear@0
|
155 char* const end = _out+4096;
|
nuclear@0
|
156 while (!IsLineEnd( *buffer ) && _out < end)
|
nuclear@0
|
157 *_out++ = *buffer++;
|
nuclear@0
|
158 *_out = (char_t)'\0';
|
nuclear@0
|
159
|
nuclear@0
|
160 while (IsLineEnd( *buffer ) && '\0' != *buffer)++buffer;
|
nuclear@0
|
161 return true;
|
nuclear@0
|
162 }
|
nuclear@0
|
163 // ---------------------------------------------------------------------------------
|
nuclear@0
|
164 template <class char_t>
|
nuclear@0
|
165 AI_FORCE_INLINE bool IsNumeric( char_t in)
|
nuclear@0
|
166 {
|
nuclear@0
|
167 return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
|
nuclear@0
|
168 }
|
nuclear@0
|
169 // ---------------------------------------------------------------------------------
|
nuclear@0
|
170 template <class char_t>
|
nuclear@0
|
171 AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
|
nuclear@0
|
172 {
|
nuclear@0
|
173 if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len]))
|
nuclear@0
|
174 {
|
nuclear@0
|
175 in += len+1;
|
nuclear@0
|
176 return true;
|
nuclear@0
|
177 }
|
nuclear@0
|
178 return false;
|
nuclear@0
|
179 }
|
nuclear@0
|
180 // ---------------------------------------------------------------------------------
|
nuclear@0
|
181 /** @brief Case-ignoring version of TokenMatch
|
nuclear@0
|
182 * @param in Input
|
nuclear@0
|
183 * @param token Token to check for
|
nuclear@0
|
184 * @param len Number of characters to check
|
nuclear@0
|
185 */
|
nuclear@0
|
186 AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len)
|
nuclear@0
|
187 {
|
nuclear@0
|
188 if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len]))
|
nuclear@0
|
189 {
|
nuclear@0
|
190 in += len+1;
|
nuclear@0
|
191 return true;
|
nuclear@0
|
192 }
|
nuclear@0
|
193 return false;
|
nuclear@0
|
194 }
|
nuclear@0
|
195 // ---------------------------------------------------------------------------------
|
nuclear@0
|
196 AI_FORCE_INLINE void SkipToken(const char*& in)
|
nuclear@0
|
197 {
|
nuclear@0
|
198 SkipSpaces(&in);
|
nuclear@0
|
199 while (!IsSpaceOrNewLine(*in))++in;
|
nuclear@0
|
200 }
|
nuclear@0
|
201 // ---------------------------------------------------------------------------------
|
nuclear@0
|
202 AI_FORCE_INLINE std::string GetNextToken(const char*& in)
|
nuclear@0
|
203 {
|
nuclear@0
|
204 SkipSpacesAndLineEnd(&in);
|
nuclear@0
|
205 const char* cur = in;
|
nuclear@0
|
206 while (!IsSpaceOrNewLine(*in))++in;
|
nuclear@0
|
207 return std::string(cur,(size_t)(in-cur));
|
nuclear@0
|
208 }
|
nuclear@0
|
209 } // ! namespace Assimp
|
nuclear@0
|
210 #endif // ! AI_PARSING_UTILS_H_INC
|