Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:30:09

0001 /*
0002 Open Asset Import Library (assimp)
0003 ----------------------------------------------------------------------
0004 
0005 Copyright (c) 2006-2024, assimp team
0006 
0007 All rights reserved.
0008 
0009 Redistribution and use of this software in source and binary forms,
0010 with or without modification, are permitted provided that the
0011 following conditions are met:
0012 
0013 * Redistributions of source code must retain the above
0014   copyright notice, this list of conditions and the
0015   following disclaimer.
0016 
0017 * Redistributions in binary form must reproduce the above
0018   copyright notice, this list of conditions and the
0019   following disclaimer in the documentation and/or other
0020   materials provided with the distribution.
0021 
0022 * Neither the name of the assimp team, nor the names of its
0023   contributors may be used to endorse or promote products
0024   derived from this software without specific prior
0025   written permission of the assimp team.
0026 
0027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0028 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0029 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0030 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0031 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0032 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0033 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0034 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0035 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0037 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0038 
0039 ----------------------------------------------------------------------
0040 */
0041 
0042 /** @file ParsingUtils.h
0043  *  @brief Defines helper functions for text parsing
0044  */
0045 #pragma once
0046 #ifndef AI_PARSING_UTILS_H_INC
0047 #define AI_PARSING_UTILS_H_INC
0048 
0049 #ifdef __GNUC__
0050 #pragma GCC system_header
0051 #endif
0052 
0053 #include <assimp/StringComparison.h>
0054 #include <assimp/StringUtils.h>
0055 #include <assimp/defs.h>
0056 
0057 #include <vector>
0058 #include <algorithm>
0059 
0060 namespace Assimp {
0061 
0062 // NOTE: the functions below are mostly intended as replacement for
0063 // std::upper, std::lower, std::isupper, std::islower, std::isspace.
0064 // we don't bother of locales. We don't want them. We want reliable
0065 // (i.e. identical) results across all locales.
0066 
0067 // The functions below accept any character type, but know only
0068 // about ASCII. However, UTF-32 is the only safe ASCII superset to
0069 // use since it doesn't have multi-byte sequences.
0070 
0071 static const unsigned int BufferSize = 4096;
0072 
0073 // ---------------------------------------------------------------------------------
0074 template <class char_t>
0075 AI_FORCE_INLINE bool IsUpper(char_t in) {
0076     return (in >= (char_t)'A' && in <= (char_t)'Z');
0077 }
0078 
0079 // ---------------------------------------------------------------------------------
0080 template <class char_t>
0081 AI_FORCE_INLINE bool IsLower(char_t in) {
0082     return (in >= (char_t)'a' && in <= (char_t)'z');
0083 }
0084 
0085 // ---------------------------------------------------------------------------------
0086 template <class char_t>
0087 AI_FORCE_INLINE bool IsSpace(char_t in) {
0088     return (in == (char_t)' ' || in == (char_t)'\t');
0089 }
0090 
0091 // ---------------------------------------------------------------------------------
0092 template <class char_t>
0093 AI_FORCE_INLINE bool IsLineEnd(char_t in) {
0094     return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0' || in == (char_t)'\f');
0095 }
0096 
0097 // ---------------------------------------------------------------------------------
0098 template <class char_t>
0099 AI_FORCE_INLINE bool IsSpaceOrNewLine(char_t in) {
0100     return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
0101 }
0102 
0103 // ---------------------------------------------------------------------------------
0104 template <class char_t>
0105 AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out, const char_t *end) {
0106     while ((*in == (char_t)' ' || *in == (char_t)'\t') && in != end) {
0107         ++in;
0108     }
0109     *out = in;
0110     return !IsLineEnd<char_t>(*in);
0111 }
0112 
0113 // ---------------------------------------------------------------------------------
0114 template <class char_t>
0115 AI_FORCE_INLINE bool SkipSpaces(const char_t **inout, const char_t *end) {
0116     return SkipSpaces<char_t>(*inout, inout, end);
0117 }
0118 
0119 // ---------------------------------------------------------------------------------
0120 template <class char_t>
0121 AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out, const char_t *end) {
0122     while ((*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') && in != end) {
0123         ++in;
0124     }
0125 
0126     // files are opened in binary mode. Ergo there are both NL and CR
0127     while ((*in == (char_t)'\r' || *in == (char_t)'\n') && in != end) {
0128         ++in;
0129     }
0130     *out = in;
0131     return *in != (char_t)'\0';
0132 }
0133 
0134 // ---------------------------------------------------------------------------------
0135 template <class char_t>
0136 AI_FORCE_INLINE bool SkipLine(const char_t **inout, const char_t *end) {
0137     return SkipLine<char_t>(*inout, inout, end);
0138 }
0139 
0140 // ---------------------------------------------------------------------------------
0141 template <class char_t>
0142 AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out, const char_t  *end) {
0143     while ((*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') && in != end) {
0144         ++in;
0145     }
0146     *out = in;
0147     return *in != '\0';
0148 }
0149 
0150 // ---------------------------------------------------------------------------------
0151 template <class char_t>
0152 AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout, const char_t *end) {
0153     return SkipSpacesAndLineEnd<char_t>(*inout, inout, end);
0154 }
0155 
0156 // ---------------------------------------------------------------------------------
0157 template <class char_t>
0158 AI_FORCE_INLINE bool GetNextLine(const char_t *&buffer, char_t out[BufferSize]) {
0159     if ((char_t)'\0' == *buffer) {
0160         return false;
0161     }
0162 
0163     char *_out = out;
0164     char *const end = _out + BufferSize;
0165     while (!IsLineEnd(*buffer) && _out < end) {
0166         *_out++ = *buffer++;
0167     }
0168     *_out = (char_t)'\0';
0169 
0170     while (IsLineEnd(*buffer) && '\0' != *buffer) {
0171         ++buffer;
0172     }
0173 
0174     return true;
0175 }
0176 
0177 // ---------------------------------------------------------------------------------
0178 template <class char_t>
0179 AI_FORCE_INLINE bool IsNumeric(char_t in) {
0180     return (in >= '0' && in <= '9') || '-' == in || '+' == in;
0181 }
0182 
0183 // ---------------------------------------------------------------------------------
0184 template <class char_t>
0185 AI_FORCE_INLINE bool TokenMatch(char_t *&in, const char *token, unsigned int len) {
0186     if (!::strncmp(token, in, len) && IsSpaceOrNewLine(in[len])) {
0187         if (in[len] != '\0') {
0188             in += len + 1;
0189         } else {
0190             // If EOF after the token make sure we don't go past end of buffer
0191             in += len;
0192         }
0193         return true;
0194     }
0195 
0196     return false;
0197 }
0198 // ---------------------------------------------------------------------------------
0199 /** @brief Case-ignoring version of TokenMatch
0200  *  @param in Input
0201  *  @param token Token to check for
0202  *  @param len Number of characters to check
0203  */
0204 AI_FORCE_INLINE bool TokenMatchI(const char *&in, const char *token, unsigned int len) {
0205     if (!ASSIMP_strincmp(token, in, len) && IsSpaceOrNewLine(in[len])) {
0206         in += len + 1;
0207         return true;
0208     }
0209     return false;
0210 }
0211 
0212 // ---------------------------------------------------------------------------------
0213 AI_FORCE_INLINE void SkipToken(const char *&in, const char *end) {
0214     SkipSpaces(&in, end);
0215     while (!IsSpaceOrNewLine(*in)) {
0216         ++in;
0217     }
0218 }
0219 
0220 // ---------------------------------------------------------------------------------
0221 AI_FORCE_INLINE std::string GetNextToken(const char *&in, const char *end) {
0222     SkipSpacesAndLineEnd(&in, end);
0223     const char *cur = in;
0224     while (!IsSpaceOrNewLine(*in)) {
0225         ++in;
0226     }
0227     return std::string(cur, (size_t)(in - cur));
0228 }
0229 
0230 // ---------------------------------------------------------------------------------
0231 /** @brief  Will perform a simple tokenize.
0232  *  @param  str         String to tokenize.
0233  *  @param  tokens      Array with tokens, will be empty if no token was found.
0234  *  @param  delimiters  Delimiter for tokenize.
0235  *  @return Number of found token.
0236  */
0237 template <class string_type>
0238 AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector<string_type> &tokens,
0239         const string_type &delimiters) {
0240     // Skip delimiters at beginning.
0241     typename string_type::size_type lastPos = str.find_first_not_of(delimiters, 0);
0242 
0243     // Find first "non-delimiter".
0244     typename string_type::size_type pos = str.find_first_of(delimiters, lastPos);
0245     while (string_type::npos != pos || string_type::npos != lastPos) {
0246         // Found a token, add it to the vector.
0247         string_type tmp = str.substr(lastPos, pos - lastPos);
0248         if (!tmp.empty() && ' ' != tmp[0])
0249             tokens.push_back(tmp);
0250 
0251         // Skip delimiters.  Note the "not_of"
0252         lastPos = str.find_first_not_of(delimiters, pos);
0253 
0254         // Find next "non-delimiter"
0255         pos = str.find_first_of(delimiters, lastPos);
0256     }
0257 
0258     return static_cast<unsigned int>(tokens.size());
0259 }
0260 
0261 inline std::string ai_stdStrToLower(const std::string &str) {
0262     std::string out(str);
0263     for (size_t i = 0; i < str.size(); ++i) {
0264         out[i] = (char) tolower((unsigned char)out[i]);
0265     }
0266     return out;
0267 }
0268 
0269 } // namespace Assimp
0270 
0271 #endif // ! AI_PARSING_UTILS_H_INC