/* dxfReader for OpenSceneGraph Copyright (C) 2005 by GraphArchitecture ( grapharchitecture.com ) * Programmed by Paul de Repentigny * * OpenSceneGraph is (C) 2004 Robert Osfield * * This library is provided as-is, without support of any kind. * * Read DXF docs or OSG docs for any related questions. * * You may contact the author if you have suggestions/corrections/enhancements. */ #include "dxfReader.h" #include "dxfDataTypes.h" #include "codeValue.h" #include #include #include #include #include #include #include using namespace std; static std::string trim(const string& str) { if (!str.size()) return str; string::size_type first = str.find_first_not_of(" \t"); string::size_type last = str.find_last_not_of(" \t\r\n"); return str.substr(first, last-first+1); } /* ************** readerBase */ bool readerBase::readGroup(std::ifstream& f, codeValue& cv) { cv.reset(); if (readGroupCode(f, cv._groupCode)) { cv._type = dxfDataType::typeForCode(cv._groupCode); switch (cv._type) { case dxfDataType::BOOL: return readValue(f, cv._bool); break; case dxfDataType::SHORT: return readValue(f, cv._short); break; case dxfDataType::INT: return readValue(f, cv._int); break; case dxfDataType::LONG: return readValue(f, cv._long); break; case dxfDataType::DOUBLE: return readValue(f, cv._double); break; case dxfDataType::UNKNOWN: case dxfDataType::STRING: case dxfDataType::HEX: default: // to do: default case an error return readValue(f, cv._string); break; } } else { cv._type = dxfDataType::UNKNOWN; cv._groupCode = -1; } return false; } /* ************** readerText */ bool readerText::success(bool inSuccess, string type) { if (!inSuccess) cout << "Error converting line " << _lineCount << " to type " << type << endl; return inSuccess; } bool readerText::getTrimmedLine(std::ifstream& f) { static string line = ""; if (getline(f, line, _delim)) { ++_lineCount; _str.clear(); _str.str(trim(line)); return true; } return false; } bool readerText::readGroupCode(std::ifstream& f, int &groupcode) { if (getTrimmedLine(f)) { _str >> groupcode; return success(!_str.fail(), "int"); } else { return false; } } bool readerText::readValue(std::ifstream& f, string &s) { if (getTrimmedLine(f)) { getline(_str, s); // empty string is valid return success((!_str.fail() || s == ""), "string"); } else { return false; } } bool readerText::readValue(std::ifstream& f, bool &b) { if (getTrimmedLine(f)) { _str >> b; return success(!_str.fail(), "bool"); } else { return false; } } bool readerText::readValue(std::ifstream& f, short &s) { if (getTrimmedLine(f)) { _str >> s; return success(!_str.fail(), "short"); } else { return false; } } bool readerText::readValue(std::ifstream& f, int &i) { if (getTrimmedLine(f)) { _str >> i; return success(!_str.fail(), "int"); } else { return false; } } bool readerText::readValue(std::ifstream& f, long &l) { if (getTrimmedLine(f)) { _str >> l; return success(!_str.fail(), "long"); } else { return false; } } bool readerText::readValue(std::ifstream& f, double &d) { if (getTrimmedLine(f)) { _str >> d; return success(!_str.fail(), "double"); } else { return false; } } /* ************** dxfReader */ bool dxfReader::openFile(std::string fileName) { if (fileName.size() == 0) return false; _ifs.open(fileName.c_str(), ios::binary); // found mac autocad with \r delimiters if (!_ifs) { cout << " Can't open " << fileName << endl; return false; } // A binary file starts with "AutoCAD Binary DXF" char buf[255]; _ifs.get(buf, 255); string sentinel(buf); if (trim(sentinel) == "AutoCAD Binary DXF") { cout << " Binary DXF not supported. For now. Come back soon." << endl; return false; } //string::size_type lf = sentinel.find('\n'); //string::size_type cr = sentinel.find('\r'); // gossage. un mac peut mettre juste CR. ca fonctionne pas: // if (cr > 0 && (!lf || lf > cr + 1)) // _reader = new readerText('\r'); // else _reader = new readerText; _ifs.seekg(0, ios::beg); return true; } bool dxfReader::nextGroupCode(codeValue& cv) { return (_reader->readGroup(_ifs, cv)); }