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 /** @file ObjTools.h
|
nuclear@0
|
42 * @brief Some helpful templates for text parsing
|
nuclear@0
|
43 */
|
nuclear@0
|
44 #ifndef OBJ_TOOLS_H_INC
|
nuclear@0
|
45 #define OBJ_TOOLS_H_INC
|
nuclear@0
|
46
|
nuclear@0
|
47 #include "fast_atof.h"
|
nuclear@0
|
48
|
nuclear@0
|
49 namespace Assimp
|
nuclear@0
|
50 {
|
nuclear@0
|
51
|
nuclear@0
|
52 /** @brief Returns true, if the last entry of the buffer is reached.
|
nuclear@0
|
53 * @param it Iterator of current position.
|
nuclear@0
|
54 * @param end Iterator with end of buffer.
|
nuclear@0
|
55 * @return true, if the end of the buffer is reached.
|
nuclear@0
|
56 */
|
nuclear@0
|
57 template<class char_t>
|
nuclear@0
|
58 inline bool isEndOfBuffer( char_t it, char_t end )
|
nuclear@0
|
59 {
|
nuclear@0
|
60 if ( it == end )
|
nuclear@0
|
61 {
|
nuclear@0
|
62 return true;
|
nuclear@0
|
63 }
|
nuclear@0
|
64 else
|
nuclear@0
|
65 {
|
nuclear@0
|
66 end--;
|
nuclear@0
|
67 }
|
nuclear@0
|
68 return ( it == end );
|
nuclear@0
|
69 }
|
nuclear@0
|
70
|
nuclear@0
|
71 /** @brief Returns true, if token is a space on any supported platform
|
nuclear@0
|
72 * @param token Token to search in
|
nuclear@0
|
73 * @return true, if token is a space
|
nuclear@0
|
74 */
|
nuclear@0
|
75 inline bool isSeparator( char token )
|
nuclear@0
|
76 {
|
nuclear@0
|
77 return ( token == ' ' ||
|
nuclear@0
|
78 token == '\n' ||
|
nuclear@0
|
79 token == '\f' ||
|
nuclear@0
|
80 token == '\r' ||
|
nuclear@0
|
81 token == '\t' );
|
nuclear@0
|
82 }
|
nuclear@0
|
83
|
nuclear@0
|
84 /** @brief Returns true, fi token id a new line marking token.
|
nuclear@0
|
85 * @param token Token to search in
|
nuclear@0
|
86 * @return true, if token is a newline token.
|
nuclear@0
|
87 */
|
nuclear@0
|
88 inline bool isNewLine( char token )
|
nuclear@0
|
89 {
|
nuclear@0
|
90 return ( token == '\n' || token == '\f' || token == '\r' );
|
nuclear@0
|
91 }
|
nuclear@0
|
92
|
nuclear@0
|
93 /** @brief Returns next word separated by a space
|
nuclear@0
|
94 * @param pBuffer Pointer to data buffer
|
nuclear@0
|
95 * @param pEnd Pointer to end of buffer
|
nuclear@0
|
96 * @return Pointer to next space
|
nuclear@0
|
97 */
|
nuclear@0
|
98 template<class Char_T>
|
nuclear@0
|
99 inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
|
nuclear@0
|
100 {
|
nuclear@0
|
101 while ( !isEndOfBuffer( pBuffer, pEnd ) )
|
nuclear@0
|
102 {
|
nuclear@0
|
103 if ( !isSeparator( *pBuffer ) || isNewLine( *pBuffer ) )
|
nuclear@0
|
104 break;
|
nuclear@0
|
105 pBuffer++;
|
nuclear@0
|
106 }
|
nuclear@0
|
107 return pBuffer;
|
nuclear@0
|
108 }
|
nuclear@0
|
109
|
nuclear@0
|
110 /** @brief Returns ponter a next token
|
nuclear@0
|
111 * @param pBuffer Pointer to data buffer
|
nuclear@0
|
112 * @param pEnd Pointer to end of buffer
|
nuclear@0
|
113 * @return Pointer to next token
|
nuclear@0
|
114 */
|
nuclear@0
|
115 template<class Char_T>
|
nuclear@0
|
116 inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
|
nuclear@0
|
117 {
|
nuclear@0
|
118 while ( !isEndOfBuffer( pBuffer, pEnd ) )
|
nuclear@0
|
119 {
|
nuclear@0
|
120 if ( isSeparator( *pBuffer ) )
|
nuclear@0
|
121 break;
|
nuclear@0
|
122 pBuffer++;
|
nuclear@0
|
123 }
|
nuclear@0
|
124 return getNextWord( pBuffer, pEnd );
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 /** @brief Skips a line
|
nuclear@0
|
128 * @param it Iterator set to current position
|
nuclear@0
|
129 * @param end Iterator set to end of scratch buffer for readout
|
nuclear@0
|
130 * @param uiLine Current linenumber in format
|
nuclear@0
|
131 * @return Current-iterator with new position
|
nuclear@0
|
132 */
|
nuclear@0
|
133 template<class char_t>
|
nuclear@0
|
134 inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine )
|
nuclear@0
|
135 {
|
nuclear@0
|
136 while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) )
|
nuclear@0
|
137 ++it;
|
nuclear@0
|
138 if ( it != end )
|
nuclear@0
|
139 {
|
nuclear@0
|
140 ++it;
|
nuclear@0
|
141 ++uiLine;
|
nuclear@0
|
142 }
|
nuclear@0
|
143 // fix .. from time to time there are spaces at the beginning of a material line
|
nuclear@0
|
144 while ( it != end && (*it == '\t' || *it == ' ') )
|
nuclear@0
|
145 ++it;
|
nuclear@0
|
146 return it;
|
nuclear@0
|
147 }
|
nuclear@0
|
148
|
nuclear@0
|
149 /** @brief Get a name from the current line. Preserve space in the middle,
|
nuclear@0
|
150 * but trim it at the end.
|
nuclear@0
|
151 * @param it set to current position
|
nuclear@0
|
152 * @param end set to end of scratch buffer for readout
|
nuclear@0
|
153 * @param name Separated name
|
nuclear@0
|
154 * @return Current-iterator with new position
|
nuclear@0
|
155 */
|
nuclear@0
|
156 template<class char_t>
|
nuclear@0
|
157 inline char_t getName( char_t it, char_t end, std::string &name )
|
nuclear@0
|
158 {
|
nuclear@0
|
159 name = "";
|
nuclear@0
|
160 it = getNextToken<char_t>( it, end );
|
nuclear@0
|
161 if ( isEndOfBuffer( it, end ) )
|
nuclear@0
|
162 return end;
|
nuclear@0
|
163
|
nuclear@0
|
164 char *pStart = &( *it );
|
nuclear@0
|
165 while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) ) {
|
nuclear@0
|
166 ++it;
|
nuclear@0
|
167 }
|
nuclear@0
|
168
|
nuclear@0
|
169 while(isEndOfBuffer( it, end ) || isNewLine( *it ) || isSeparator(*it)) {
|
nuclear@0
|
170 --it;
|
nuclear@0
|
171 }
|
nuclear@0
|
172 ++it;
|
nuclear@0
|
173
|
nuclear@0
|
174 // Get name
|
nuclear@0
|
175 // if there is no name, and the previous char is a separator, come back to start
|
nuclear@0
|
176 while (&(*it) < pStart) {
|
nuclear@0
|
177 ++it;
|
nuclear@0
|
178 }
|
nuclear@0
|
179 std::string strName( pStart, &(*it) );
|
nuclear@0
|
180 if ( strName.empty() )
|
nuclear@0
|
181 return it;
|
nuclear@0
|
182 else
|
nuclear@0
|
183 name = strName;
|
nuclear@0
|
184
|
nuclear@0
|
185 return it;
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@0
|
188 /** @brief Get next word from given line
|
nuclear@0
|
189 * @param it set to current position
|
nuclear@0
|
190 * @param end set to end of scratch buffer for readout
|
nuclear@0
|
191 * @param pBuffer Buffer for next word
|
nuclear@0
|
192 * @param length Buffer length
|
nuclear@0
|
193 * @return Current-iterator with new position
|
nuclear@0
|
194 */
|
nuclear@0
|
195 template<class char_t>
|
nuclear@0
|
196 inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length )
|
nuclear@0
|
197 {
|
nuclear@0
|
198 size_t index = 0;
|
nuclear@0
|
199 it = getNextWord<char_t>( it, end );
|
nuclear@0
|
200 while ( !isSeparator( *it ) && !isEndOfBuffer( it, end ) )
|
nuclear@0
|
201 {
|
nuclear@0
|
202 pBuffer[index] = *it ;
|
nuclear@0
|
203 index++;
|
nuclear@0
|
204 if (index == length-1)
|
nuclear@0
|
205 break;
|
nuclear@0
|
206 ++it;
|
nuclear@0
|
207 }
|
nuclear@0
|
208 pBuffer[ index ] = '\0';
|
nuclear@0
|
209 return it;
|
nuclear@0
|
210 }
|
nuclear@0
|
211
|
nuclear@0
|
212 /** @brief Get next float from given line
|
nuclear@0
|
213 * @param it set to current position
|
nuclear@0
|
214 * @param end set to end of scratch buffer for readout
|
nuclear@0
|
215 * @param value Separated float value.
|
nuclear@0
|
216 * @return Current-iterator with new position
|
nuclear@0
|
217 */
|
nuclear@0
|
218 template<class char_t>
|
nuclear@0
|
219 inline char_t getFloat( char_t it, char_t end, float &value )
|
nuclear@0
|
220 {
|
nuclear@0
|
221 static const size_t BUFFERSIZE = 1024;
|
nuclear@0
|
222 char buffer[ BUFFERSIZE ];
|
nuclear@0
|
223 it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE );
|
nuclear@0
|
224 value = (float) fast_atof( buffer );
|
nuclear@0
|
225
|
nuclear@0
|
226 return it;
|
nuclear@0
|
227 }
|
nuclear@0
|
228
|
nuclear@0
|
229 /** @brief Will perform a simple tokenize.
|
nuclear@0
|
230 * @param str String to tokenize.
|
nuclear@0
|
231 * @param tokens Array with tokens, will be empty if no token was found.
|
nuclear@0
|
232 * @param delimiters Delimiter for tokenize.
|
nuclear@0
|
233 * @return Number of found token.
|
nuclear@0
|
234 */
|
nuclear@0
|
235 template<class string_type>
|
nuclear@0
|
236 unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
|
nuclear@0
|
237 const string_type& delimiters )
|
nuclear@0
|
238 {
|
nuclear@0
|
239 // Skip delimiters at beginning.
|
nuclear@0
|
240 typename string_type::size_type lastPos = str.find_first_not_of( delimiters, 0 );
|
nuclear@0
|
241
|
nuclear@0
|
242 // Find first "non-delimiter".
|
nuclear@0
|
243 typename string_type::size_type pos = str.find_first_of( delimiters, lastPos );
|
nuclear@0
|
244 while ( string_type::npos != pos || string_type::npos != lastPos )
|
nuclear@0
|
245 {
|
nuclear@0
|
246 // Found a token, add it to the vector.
|
nuclear@0
|
247 string_type tmp = str.substr(lastPos, pos - lastPos);
|
nuclear@0
|
248 if ( !tmp.empty() && ' ' != tmp[ 0 ] )
|
nuclear@0
|
249 tokens.push_back( tmp );
|
nuclear@0
|
250
|
nuclear@0
|
251 // Skip delimiters. Note the "not_of"
|
nuclear@0
|
252 lastPos = str.find_first_not_of( delimiters, pos );
|
nuclear@0
|
253
|
nuclear@0
|
254 // Find next "non-delimiter"
|
nuclear@0
|
255 pos = str.find_first_of( delimiters, lastPos );
|
nuclear@0
|
256 }
|
nuclear@0
|
257
|
nuclear@0
|
258 return static_cast<unsigned int>( tokens.size() );
|
nuclear@0
|
259 }
|
nuclear@0
|
260
|
nuclear@0
|
261 } // Namespace Assimp
|
nuclear@0
|
262
|
nuclear@0
|
263 #endif
|