示例#1
0
文件: MorkParser.cpp 项目: KDE/kdepim
bool MorkParser::parseTable()
{
    bool Result = true;
    QString TextId;
    int Id = 0, Scope = 0;

    char cur = nextChar();

    // Get id
    while (cur != '{' && cur != '[' && cur != '}' && cur) {
        if (!isWhiteSpace(cur)) {
            TextId += cur;
        }

        cur = nextChar();
    }

    parseScopeId(TextId, Id, Scope);

    // Parse the table
    while (Result && cur != '}' && cur) {
        if (!isWhiteSpace(cur)) {
            switch (cur) {
            case '{':
                Result = parseMeta('}');
                break;
            case '[':
                Result = parseRow(Id, Scope);
                break;
            case '-':
            case '+':
                break;
            default: {
                QString JustId;
                while (!isWhiteSpace(cur) && cur) {
                    JustId += cur;
                    cur = nextChar();

                    if (cur == '}') {
                        return Result;
                    }
                }

                int JustIdNum = 0, JustScopeNum = 0;
                parseScopeId(JustId, JustIdNum, JustScopeNum);

                setCurrentRow(Scope, Id, JustScopeNum, JustIdNum);
            }
            break;
            }
        }

        cur = nextChar();
    }

    return Result;
}
示例#2
0
bool TestCase::load(const char* filePath)
{
    char* buf = 0;
    FILE* fp = fopen(filePath, "rb");
    if (!fp)
        return false;
    fseek(fp, 0, SEEK_END);
    int bufSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    buf = new char[bufSize];
    if (!buf)
    {
        fclose(fp);
        return false;
    }
    fread(buf, bufSize, 1, fp);
    fclose(fp);

    char* src = buf;
    char* srcEnd = buf + bufSize;
    char row[512];
    while (src < srcEnd)
    {
        // Parse one row
        row[0] = '\0';
        src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
        if (row[0] == 's')
        {
            // Sample name.
            copyName(m_sampleName, row+1);
        }
        else if (row[0] == 'f')
        {
            // File name.
            copyName(m_geomFileName, row+1);
        }
        else if (row[0] == 'p' && row[1] == 'f')
        {
            // Pathfind test.
            Test* test = new Test;
            memset(test, 0, sizeof(Test));
            test->type = TEST_PATHFIND;
            test->expand = false;
            test->next = m_tests;
            m_tests = test;
            sscanf(row+2, "%f %f %f %f %f %f %x %x",
                   &test->spos[0], &test->spos[1], &test->spos[2],
                   &test->epos[0], &test->epos[1], &test->epos[2],
                   &test->includeFlags, &test->excludeFlags);
        }
    }
    
    delete [] buf;

    return true;
}
示例#3
0
static void parseIndex(struct gbRelease* release, struct gbIgnore* ignore,
                       char *path)
/* read and parse ignore file */
{
char* row[IGIDX_NUM_COLS];
struct lineFile* lf = lineFileOpen(path, TRUE);
while (lineFileNextRowTab(lf, row, ArraySize(row)))
    parseRow(release, ignore, lf, row);

lineFileClose(&lf);
}
示例#4
0
void OOoReportBuilder::parseTable(QDomNode table)
{
    QDomNode child = table.firstChild();

    while (!child.isNull()) {
        if (child.nodeName() == "table:table-row") {
            child = parseRow(child);
        }

        child = child.nextSibling();
    }
}
示例#5
0
void TextScanWorkOrder::execute() {
  const CatalogRelationSchema &relation = output_destination_->getRelation();

  string current_row_string;
  if (is_file_) {
    FILE *file = std::fopen(filename_.c_str(), "r");
    if (file == nullptr) {
      throw TextScanReadError(filename_);
    }

    bool have_row = false;
    do {
      current_row_string.clear();
      have_row = readRowFromFile(file, &current_row_string);
      if (have_row) {
        Tuple tuple = parseRow(current_row_string, relation);
        output_destination_->insertTupleInBatch(tuple);
      }
    } while (have_row);

    std::fclose(file);
  } else {
    BlobReference blob = storage_manager_->getBlob(text_blob_);
    const char *blob_pos = static_cast<const char*>(blob->getMemory());
    const char *blob_end = blob_pos + text_size_;
    bool have_row = false;
    do {
      current_row_string.clear();
      have_row = readRowFromBlob(&blob_pos, blob_end, &current_row_string);
      if (have_row) {
        Tuple tuple = parseRow(current_row_string, relation);
        output_destination_->insertTupleInBatch(tuple);
      }
    } while (have_row);

    // Drop the consumed blob produced by TextSplitWorkOrder.
    blob.release();
    storage_manager_->deleteBlockOrBlobFile(text_blob_);
  }
}
示例#6
0
bool MorkParser::parse()
{
	bool Result = true;
	char cur = 0;

	// Run over mork chars and parse each term
	cur = nextChar();

	int i = 0;

	while ( Result && cur )
	{
		if ( !isWhiteSpace( cur ) )
		{
			i++;
			// Figure out what a term
			switch ( cur )
			{
			case '<':
				// Dict
				Result = parseDict();
				break;
			case '/':
				// Comment
				Result = parseComment();
				break;
			case '{':
				Result = parseTable();
				// Table
				break;
			case '[':
				Result = parseRow( 0, 0 );
				// Row
				break;
			case '@':
				Result = parseGroup();
				// Group
				break;
			default:
				error_ = DefectedFormat;
				Result = false;
				break;
			}
		}

		// Get next char
		cur = nextChar();
	}

	return Result;
}
示例#7
0
Mesh* MeshLoader::loadPlyFile(std::string filename)
{
	plyElements word = NONE;
	int lengthRow=0;
	char* curRow;
	
	
	std::ifstream is;
	is.open(filename.c_str(),std::ifstream::in);
	
	is.seekg(0,is.end);
	int length = is.tellg();
	is.seekg(0,is.beg);
	char* file = new char[length];
	is.read(file,length);
	is.close();
	
	curRow = file;
	lengthRow = strchr(curRow,'\n') - curRow;
	do
	{
		word = parseRow(curRow,lengthRow);
		
		switch(word)
		{
			case FORMAT:
			{
			
			}
		}
		if((curRow-file)+lengthRow+1 > length)
		{
			return NULL;
		}
		curRow = curRow + lengthRow + 1;
		lengthRow = strchr(curRow,'\n') - curRow;
	}while(word != END_HEADER);

	return NULL;
}
示例#8
0
void LayoutParser::parseExtended(const TagKeyPtr &key)
{
    bool found_row(false);
    TagExtendedPtr new_extended(new TagExtended);

    key->setExtended(new_extended);

    while (m_xml.readNextStartElement()) {
        const QStringRef name(m_xml.name());

        if (name == QLatin1String("row")) {
            parseRow(new_extended);
            found_row = true;
        } else {
            error(QString::fromLatin1("Expected '<row>', but got '<%1>'.").arg(name.toString()));
        }
    }

    if (not found_row) {
        error(QString::fromLatin1("Expected at least one '<row>', but got none."));
    }
}
示例#9
0
bool NavMesh::loadGeomFile()
{
    unsigned char* buf = 0;
    auto data = FileUtils::getInstance()->getDataFromFile(_geomFilePath);
    if (data.isNull()) return false;
    buf = data.getBytes();
    _geomData = new GeomData;
    _geomData->offMeshConCount = 0;

    unsigned char* src = buf;
    unsigned char* srcEnd = buf + data.getSize();
    char row[512];
    while (src < srcEnd)
    {
        // Parse one row
        row[0] = '\0';
        src = parseRow(src, srcEnd, row, sizeof(row) / sizeof(char));
        if (row[0] == 'c')
        {
            // Off-mesh connection
            if (_geomData->offMeshConCount < GeomData::MAX_OFFMESH_CONNECTIONS)
            {
                float* v = &_geomData->offMeshConVerts[_geomData->offMeshConCount * 3 * 2];
                int bidir, area = 0, flags = 0;
                float rad;
                sscanf(row + 1, "%f %f %f  %f %f %f %f %d %d %d",
                    &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &rad, &bidir, &area, &flags);
                _geomData->offMeshConRads[_geomData->offMeshConCount] = rad;
                _geomData->offMeshConDirs[_geomData->offMeshConCount] = (unsigned char)bidir;
                _geomData->offMeshConAreas[_geomData->offMeshConCount] = (unsigned char)area;
                _geomData->offMeshConFlags[_geomData->offMeshConCount] = (unsigned short)flags;
                _geomData->offMeshConCount++;
            }
        }
    }

    return true;
}
示例#10
0
void LayoutParser::parseSection(const TagLayoutPtr &layout)
{
    static const QStringList typeValues(QString::fromLatin1("sloppy,non-sloppy").split(','));

    const QXmlStreamAttributes attributes(m_xml.attributes());
    const QString id(attributes.value(QLatin1String("id")).toString());
    const bool movable(boolValue(attributes.value(QLatin1String("movable")), true));
    const TagSection::SectionType type(enumValue("type", typeValues, TagSection::Sloppy));
    const QString style(attributes.value(QLatin1String("style")).toString());

    if (id.isEmpty()) {
        error("Expected non-empty 'id' attribute in '<section>'.");
        return;
    }


    TagSectionPtr new_section(new TagSection(id, movable, type, style));
    layout->appendSection(new_section);

    bool found_row(false);

    while (m_xml.readNextStartElement()) {
        const QStringRef name(m_xml.name());

        if (name == QLatin1String("row")) {
            parseRow(new_section);
            found_row = true;
        } else {
            error(QString::fromLatin1("Expected '<row>', but got '<%1>'.").arg(name.toString()));
        }
    }

    if (not found_row) {
        error(QString::fromLatin1("Expected '<row>'."));
    }

}
示例#11
0
bool rcMeshLoaderObj::load(const char* filename)
{
	char* buf = 0;
	FILE* fp = fopen(filename, "rb");
	if (!fp)
		return false;
	fseek(fp, 0, SEEK_END);
	int bufSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	buf = new char[bufSize];
	if (!buf)
	{
		fclose(fp);
		return false;
	}
	fread(buf, bufSize, 1, fp);
	fclose(fp);

	char* src = buf;
	char* srcEnd = buf + bufSize;
	char row[512];
	int face[32];
	float x,y,z;
	int nv;
	int vcap = 0;
	int tcap = 0;
	
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		// Skip comments
		if (row[0] == '#') continue;
		if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
		{
			// Vertex pos
			sscanf(row+1, "%f %f %f", &x, &y, &z);
			addVertex(x, y, z, vcap);
		}
		if (row[0] == 'f')
		{
			// Faces
			nv = parseFace(row+1, face, 32, m_vertCount);
			for (int i = 2; i < nv; ++i)
			{
				const int a = face[0];
				const int b = face[i-1];
				const int c = face[i];
				if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
					continue;
				addTriangle(a, b, c, tcap);
			}
		}
	}

	delete [] buf;

	// Calculate normals.
	m_normals = new float[m_triCount*3];
	for (int i = 0; i < m_triCount*3; i += 3)
	{
		const float* v0 = &m_verts[m_tris[i]*3];
		const float* v1 = &m_verts[m_tris[i+1]*3];
		const float* v2 = &m_verts[m_tris[i+2]*3];
		float e0[3], e1[3];
		for (int j = 0; j < 3; ++j)
		{
			e0[j] = v1[j] - v0[j];
			e1[j] = v2[j] - v0[j];
		}
		float* n = &m_normals[i];
		n[0] = e0[1]*e1[2] - e0[2]*e1[1];
		n[1] = e0[2]*e1[0] - e0[0]*e1[2];
		n[2] = e0[0]*e1[1] - e0[1]*e1[0];
		float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
		if (d > 0)
		{
			d = 1.0f/d;
			n[0] *= d;
			n[1] *= d;
			n[2] *= d;
		}
	}
	
	strncpy(m_filename, filename, sizeof(m_filename));
	m_filename[sizeof(m_filename)-1] = '\0';
	
	return true;
}
示例#12
0
bool InputGeom::load(const char* filePath)
{
	char* buf = 0;
	FILE* fp = fopen(filePath, "rb");
	if (!fp)
		return false;
	fseek(fp, 0, SEEK_END);
	int bufSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	buf = new char[bufSize];
	if (!buf)
	{
		fclose(fp);
		return false;
	}
	fread(buf, bufSize, 1, fp);
	fclose(fp);
	
	m_offMeshConCount = 0;
	m_volumeCount = 0;
	delete m_mesh;
	m_mesh = 0;

	char* src = buf;
	char* srcEnd = buf + bufSize;
	char row[512];
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		if (row[0] == 'f')
		{
			// File name.
			const char* name = row+1;
			// Skip white spaces
			while (*name && isspace(*name))
				name++;
			if (*name)
			{
				if (!loadMesh(name))
				{
					delete [] buf;
					return false;
				}
			}
		}
		else if (row[0] == 'c')
		{
			// Off-mesh connection
			if (m_offMeshConCount < MAX_OFFMESH_CONNECTIONS)
			{
				float* v = &m_offMeshConVerts[m_offMeshConCount*3*2];
				int bidir, area = 0, flags = 0;
				float rad;
				sscanf(row+1, "%f %f %f  %f %f %f %f %d %d %d",
					   &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &rad, &bidir, &area, &flags);
				m_offMeshConRads[m_offMeshConCount] = rad;
				m_offMeshConDirs[m_offMeshConCount] = (unsigned char)bidir;
				m_offMeshConAreas[m_offMeshConCount] = (unsigned char)area;
				m_offMeshConFlags[m_offMeshConCount] = (unsigned short)flags;
				m_offMeshConCount++;
			}
		}
		else if (row[0] == 'v')
		{
			// Convex volumes
			if (m_volumeCount < MAX_VOLUMES)
			{
				ConvexVolume* vol = &m_volumes[m_volumeCount++];
				sscanf(row+1, "%d %d %f %f", &vol->nverts, &vol->area, &vol->hmin, &vol->hmax);
				for (int i = 0; i < vol->nverts; ++i)
				{
					row[0] = '\0';
					src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
					sscanf(row, "%f %f %f", &vol->verts[i*3+0], &vol->verts[i*3+1], &vol->verts[i*3+2]);
				}
			}
		}
	}
	
	delete [] buf;
	
	return true;
}
示例#13
0
void CSVDocument::load(const std::string& oFile, bool bWithHeader /* = true */, int *errorRow /* = NULL */, int *errorCol /* = NULL */)
{
	std::ifstream oStream(oFile.c_str(), std::ios::in) ;
	if (!oStream.is_open())
	{
		printf("打开文件失败: %s\n", oFile.c_str());
		return;
	}
	std::vector<std::string> stringList;
	char sBuff[1024];
	while (!oStream.eof())
	{
		memset(sBuff, 0, sizeof(sBuff));
		oStream.getline(sBuff, sizeof(sBuff));
		if (sBuff[0] != '\0')
		{
			int len = (int)strlen(sBuff);
			if (sBuff[len - 1] == '\r')
				sBuff[len - 1] = '\0';
			stringList.push_back(sBuff);
		}
	}
	//首先清空现有数据
	clearColumnObject();
	//文档为空,没有数据则退出
	if (stringList.size() <= 0)
		return;

	//从第1行分析列名称表,分隔符是","
	parseColumns(stringList[1], ',');

	//循环读取数据并添加到每个列对象
	const int rowCount = (int)stringList.size();
	m_dwRowNum = 0;
	int hadErrCol = 0;
	int nStartRow = bWithHeader ? 1 : 0;
	for (int i = nStartRow; i < rowCount; ++i)
	{
		if (parseRow(stringList[i], ',', &hadErrCol))
		{
			m_dwRowNum++;
		}
		if (hadErrCol != 0)
		{
			if (errorRow && errorCol)
			{
				*errorCol = hadErrCol;
				*errorRow = i;
				return;
			}
			else assert(false);
		}
	}
#ifdef _DEBUG
	for (size_t i = 0; i < m_dwColNum; ++i)
	{
		if ((int)m_dwRowNum != m_ColumnList[i]->size())
		{
			if (errorCol)
			{
				*errorCol = (int)i;
				return;
			}
			else
			{
				assert(false);
			}
		}
	}
#endif
}
示例#14
0
bool rcMeshLoaderObj::loadContents(const char* contents) // TODO: PATCH
{
	int bufSize = strlen(contents);

	char* buf = const_cast<char*>(contents);
	
	char* src = buf;
	//char* src = 0;

	char* srcEnd = buf + bufSize;
	char row[512];
	int face[32];
	float x,y,z;
	int nv;
	int vcap = 0;
	int tcap = 0;
	
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		// Skip comments
		if (row[0] == '#') continue;
		if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
		{
			// Vertex pos
			sscanf(row+1, "%f %f %f", &x, &y, &z);
			addVertex(x, y, z, vcap);
		}
		if (row[0] == 'f')
		{
			// Faces
			nv = parseFace(row+1, face, 32, m_vertCount);
			for (int i = 2; i < nv; ++i)
			{
				const int a = face[0];
				const int b = face[i-1];
				const int c = face[i];
				if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
					continue;
				addTriangle(a, b, c, tcap);
			}
		}
	}

	//delete [] buf;

	// Calculate normals.
	m_normals = new float[m_triCount*3];
	for (int i = 0; i < m_triCount*3; i += 3)
	{
		const float* v0 = &m_verts[m_tris[i]*3];
		const float* v1 = &m_verts[m_tris[i+1]*3];
		const float* v2 = &m_verts[m_tris[i+2]*3];
		float e0[3], e1[3];
		for (int j = 0; j < 3; ++j)
		{
			e0[j] = v1[j] - v0[j];
			e1[j] = v2[j] - v0[j];
		}
		float* n = &m_normals[i];
		n[0] = e0[1]*e1[2] - e0[2]*e1[1];
		n[1] = e0[2]*e1[0] - e0[0]*e1[2];
		n[2] = e0[0]*e1[1] - e0[1]*e1[0];
		float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
		if (d > 0)
		{
			d = 1.0f/d;
			n[0] *= d;
			n[1] *= d;
			n[2] *= d;
		}
	}
	
	return true;
}
示例#15
0
bool InputGeom::load(rcContext* ctx, string filePath)
{
	char* buf = 0;
	FILE* fp = fopen(filePath.c_str(), "rb");
	if (!fp)
		return false;
	fseek(fp, 0, SEEK_END);
	int bufSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	buf = new char[bufSize];
	if (!buf)
	{
		fclose(fp);
		return false;
	}
	size_t readLen = fread(buf, bufSize, 1, fp);
	fclose(fp);
	if (readLen != 1)
	{
		delete[] buf;
		return false;
	}
	
	m_offMeshConCount = 0;
	m_volumes.clear();
	delete m_mesh;
	m_mesh = nullptr;

	char* src = buf;
	char* srcEnd = buf + bufSize;
	char row[512];
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		if (row[0] == 'f')
		{
			// File name.
			const char* name = row+1;
			// Skip white spaces
			while (*name && isspace(*name))
				name++;
			if (*name)
			{
				if (!loadMesh(ctx, name))
				{
					delete [] buf;
					return false;
				}
			}
		}
		else if (row[0] == 'c')
		{
			// Off-mesh connection
			if (m_offMeshConCount < MAX_OFFMESH_CONNECTIONS)
			{
				float* v = &m_offMeshConVerts[m_offMeshConCount*3*2];
				int bidir, area = 0, flags = 0;
				float rad;
				sscanf(row+1, "%f %f %f  %f %f %f %f %d %d",
					   &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &rad, &bidir, &area, &flags);
				m_offMeshConRads[m_offMeshConCount] = rad;
				m_offMeshConDirs[m_offMeshConCount] = (unsigned char)bidir;
				m_offMeshConAreaMask[m_offMeshConCount] = (navAreaMask)area;
				m_offMeshConCount++;
			}
		}
		else if (row[0] == 'v')
		{
			// Convex volumes
			m_volumes.emplace_back();
			ConvexVolume& vol = m_volumes.back();
			sscanf(row + 1, "%d %d %f %f", &vol.nverts, &vol.areaMask, &vol.hmin, &vol.hmax);
			for (int i = 0; i < vol.nverts; ++i)
			{
				row[0] = '\0';
				src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
				sscanf(row, "%f %f %f", &vol.verts[i * 3 + 0], &vol.verts[i * 3 + 1], &vol.verts[i * 3 + 2]);
				
			}
		}
	}
	
	delete [] buf;
	
	return true;
}
示例#16
0
bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath)
{
	char* buf = 0;
	FILE* fp = fopen(filepath.c_str(), "rb");
	if (!fp)
		return false;
	fseek(fp, 0, SEEK_END);
	int bufSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	buf = new char[bufSize];
	if (!buf)
	{
		fclose(fp);
		return false;
	}
	size_t readLen = fread(buf, bufSize, 1, fp);
	fclose(fp);
	if (readLen != 1)
	{
		delete[] buf;
		return false;
	}
	
	m_offMeshConCount = 0;
	m_volumeCount = 0;
	delete m_mesh;
	m_mesh = 0;

	char* src = buf;
	char* srcEnd = buf + bufSize;
	char row[512];
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		if (row[0] == 'f')
		{
			// File name.
			const char* name = row+1;
			// Skip white spaces
			while (*name && isspace(*name))
				name++;
			if (*name)
			{
				if (!loadMesh(ctx, name))
				{
					delete [] buf;
					return false;
				}
			}
		}
		else if (row[0] == 'c')
		{
			// Off-mesh connection
			if (m_offMeshConCount < MAX_OFFMESH_CONNECTIONS)
			{
				float* v = &m_offMeshConVerts[m_offMeshConCount*3*2];
				int bidir, area = 0, flags = 0;
				float rad;
				sscanf(row+1, "%f %f %f  %f %f %f %f %d %d %d",
					   &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &rad, &bidir, &area, &flags);
				m_offMeshConRads[m_offMeshConCount] = rad;
				m_offMeshConDirs[m_offMeshConCount] = (unsigned char)bidir;
				m_offMeshConAreas[m_offMeshConCount] = (unsigned char)area;
				m_offMeshConFlags[m_offMeshConCount] = (unsigned short)flags;
				m_offMeshConCount++;
			}
		}
		else if (row[0] == 'v')
		{
			// Convex volumes
			if (m_volumeCount < MAX_VOLUMES)
			{
				ConvexVolume* vol = &m_volumes[m_volumeCount++];
				sscanf(row+1, "%d %d %f %f", &vol->nverts, &vol->area, &vol->hmin, &vol->hmax);
				for (int i = 0; i < vol->nverts; ++i)
				{
					row[0] = '\0';
					src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
					sscanf(row, "%f %f %f", &vol->verts[i*3+0], &vol->verts[i*3+1], &vol->verts[i*3+2]);
				}
			}
		}
		else if (row[0] == 's')
		{
			// Settings
			m_hasBuildSettings = true;
			sscanf(row + 1, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d %f %f %f %f %f %f %f",
							&m_buildSettings.cellSize,
							&m_buildSettings.cellHeight,
							&m_buildSettings.agentHeight,
							&m_buildSettings.agentRadius,
							&m_buildSettings.agentMaxClimb,
							&m_buildSettings.agentMaxSlope,
							&m_buildSettings.regionMinSize,
							&m_buildSettings.regionMergeSize,
							&m_buildSettings.edgeMaxLen,
							&m_buildSettings.edgeMaxError,
							&m_buildSettings.vertsPerPoly,
							&m_buildSettings.detailSampleDist,
							&m_buildSettings.detailSampleMaxError,
							&m_buildSettings.partitionType,
							&m_buildSettings.navMeshBMin[0],
							&m_buildSettings.navMeshBMin[1],
							&m_buildSettings.navMeshBMin[2],
							&m_buildSettings.navMeshBMax[0],
							&m_buildSettings.navMeshBMax[1],
							&m_buildSettings.navMeshBMax[2],
							&m_buildSettings.tileSize);
		}
	}
	
	delete [] buf;
	
	return true;
}