// ------------------------------------------------------------------- // Getter for a group name. void ObjFileParser::getGroupName() { std::string strGroupName; m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName); if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) { return; } // Change active group, if necessary if ( m_pModel->m_strActiveGroup != strGroupName ) { // Search for already existing entry ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName); // We are mapping groups into the object structure createObject( strGroupName ); // New group name, creating a new entry if (it == m_pModel->m_Groups.end()) { std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>; m_pModel->m_Groups[ strGroupName ] = pFaceIDArray; m_pModel->m_pGroupFaceIDs = (pFaceIDArray); } else { m_pModel->m_pGroupFaceIDs = (*it).second; } m_pModel->m_strActiveGroup = strGroupName; } m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); }
/* ///////////////////////////////////////////////////////////////////////////// * Texture Option * ///////////////////////////////////////////////////////////////////////////// * According to http://en.wikipedia.org/wiki/Wavefront_.obj_file#Texture_options * Texture map statement can contains various texture option, for example: * * map_Ka -o 1 1 1 some.png * map_Kd -clamp on some.png * * So we need to parse and skip these options, and leave the last part which is * the url of image, otherwise we will get a wrong url like "-clamp on some.png". * * Because aiMaterial supports clamp option, so we also want to return it * ///////////////////////////////////////////////////////////////////////////// */ void ObjFileMtlImporter::getTextureOption(bool &clamp) { m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); //If there is any more texture option while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-') { const char *pPtr( &(*m_DataIt) ); //skip option key and value int skipToken = 1; if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), ClampOption.size())) { DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); char value[3]; CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value)); if (!ASSIMP_strincmp(value, "on", 2)) { clamp = true; } skipToken = 2; } else if ( !ASSIMP_strincmp(pPtr, BlendUOption.c_str(), BlendUOption.size()) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), BlendVOption.size()) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), BoostOption.size()) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), ResolutionOption.size()) || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), BumpOption.size()) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), ChannelOption.size()) || !ASSIMP_strincmp(pPtr, TypeOption.c_str(), TypeOption.size()) ) { skipToken = 2; } else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), ModifyMapOption.size())) { skipToken = 3; } else if ( !ASSIMP_strincmp(pPtr, OffsetOption.c_str(), OffsetOption.size()) || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), ScaleOption.size()) || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), TurbulenceOption.size()) ) { skipToken = 4; } for (int i = 0; i < skipToken; ++i) { m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); } } }
// ------------------------------------------------------------------- // Getter for a group name. void ObjFileParser::getGroupName() { // Get next word from data buffer m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) return; // Store groupname in group library char *pStart = &(*m_DataIt); while ( !isSeparator(*m_DataIt) ) m_DataIt++; std::string strGroupName(pStart, &(*m_DataIt)); // Change active group, if necessary if (m_pModel->m_strActiveGroup != strGroupName) { // Search for already existing entry ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(&strGroupName); // We are mapping groups into the object structure /// TODO: Is this the right way to do it???? createObject( strGroupName ); // New group name, creating a new entry if (it == m_pModel->m_Groups.end()) { std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>; m_pModel->m_Groups[ &strGroupName ] = pFaceIDArray; m_pModel->m_pGroupFaceIDs = (pFaceIDArray); } else { m_pModel->m_pGroupFaceIDs = (*it).second; } m_pModel->m_strActiveGroup = strGroupName; } m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); }
inline void NetMessageReader::nextChar() { if (!isEndOfBuffer()) { ++pos_; } }
void NetMessageReader::parse() { while (!isEndOfBuffer()) { if (std::isprint(currentChar())) { TRACE("parse: '%c' (%d) %s", currentChar(), static_cast<int>(state()), state_str()); } else { TRACE("parse: 0x%02X (%d) %s", currentChar(), static_cast<int>(state()), state_str()); } switch (state()) { case MESSAGE_BEGIN: // Syntetic state. Go straight to TYPE. case MESSAGE_TYPE: switch (currentChar()) { case '+': case '-': case ':': currentContext_->type = static_cast<NetMessage::Type>(currentChar()); setState(MESSAGE_LINE_BEGIN); nextChar(); break; case '$': currentContext_->type = NetMessage::String; setState(BULK_BEGIN); break; case '*': currentContext_->type = NetMessage::Array; setState(MESSAGE_NUM_ARGS); nextChar(); break; default: currentContext_->type = NetMessage::Nil; setState(SYNTAX_ERROR); return; } break; case MESSAGE_LINE_BEGIN: if (currentChar() == '\r') { setState(SYNTAX_ERROR); return; } setState(MESSAGE_LINE_OR_CR); begin_ = pos_; nextChar(); break; case MESSAGE_LINE_OR_CR: if (currentChar() == '\n') { setState(SYNTAX_ERROR); return; } if (currentChar() == '\r') setState(MESSAGE_LINE_LF); nextChar(); break; case MESSAGE_LINE_LF: { if (currentChar() != '\n') { setState(SYNTAX_ERROR); return; } BufferRef value = buffer_->ref(begin_, pos_ - begin_ - 1); switch (currentContext_->type) { case NetMessage::Status: currentContext_->message = NetMessage::createStatus(value); break; case NetMessage::Error: currentContext_->message = NetMessage::createError(value); break; case NetMessage::String: currentContext_->message = NetMessage::createString(value); break; case NetMessage::Number: currentContext_->message = NetMessage::createNumber(value.toInt()); break; default: currentContext_->message = NetMessage::createNil(); break; } setState(MESSAGE_END); nextChar(); popContext(); break; } case MESSAGE_NUM_ARGS: { switch (currentChar()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': currentContext_->number *= 10; currentContext_->number += currentChar() - '0'; setState(MESSAGE_NUM_ARGS_OR_CR); nextChar(); break; default: setState(SYNTAX_ERROR); return; } break; } case MESSAGE_NUM_ARGS_OR_CR: switch (currentChar()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': currentContext_->number *= 10; currentContext_->number += currentChar() - '0'; nextChar(); break; case '\r': setState(MESSAGE_LF); currentContext_->message = NetMessage::createArray(currentContext_->number); nextChar(); break; default: setState(SYNTAX_ERROR); return; } break; case MESSAGE_LF: if (currentChar() != '\n') { setState(SYNTAX_ERROR); return; } nextChar(); if (currentContext_->type == NetMessage::Array) { setState(BULK_BEGIN); pushContext(); } else { setState(MESSAGE_END); popContext(); } break; case BULK_BEGIN: if (currentChar() != '$') { setState(SYNTAX_ERROR); return; } setState(BULK_SIZE); nextChar(); break; case BULK_SIZE: switch (currentChar()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': argSize_ *= 10; argSize_ += currentChar() - '0'; setState(BULK_SIZE_OR_CR); nextChar(); break; default: setState(SYNTAX_ERROR); return; } break; case BULK_SIZE_OR_CR: switch (currentChar()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': argSize_ *= 10; argSize_ += currentChar() - '0'; nextChar(); break; case '\r': setState(BULK_SIZE_LF); nextChar(); break; default: setState(SYNTAX_ERROR); return; } break; case BULK_SIZE_LF: if (currentChar() != '\n') { setState(SYNTAX_ERROR); return; } nextChar(); setState(BULK_BODY_OR_CR); begin_ = pos_; break; case BULK_BODY_OR_CR: if (argSize_ > 0) { argSize_ -= nextChar(argSize_); } else if (currentChar() == '\r') { BufferRef value = buffer_->ref(begin_, pos_ - begin_); currentContext_->message = NetMessage::createString(value); nextChar(); setState(BULK_BODY_LF); } else { setState(SYNTAX_ERROR); return; } break; case BULK_BODY_LF: if (currentChar() != '\n') { setState(SYNTAX_ERROR); return; } nextChar(); setState(MESSAGE_END); popContext(); break; case MESSAGE_END: // if we reach here, then only because // there's garbage at the end of our message. break; case SYNTAX_ERROR: fprintf(stderr, "NetMessageSocket message syntax error at offset %zi\n", pos_); break; default: break; } } }