Files
OpenSceneGraph/src/osgPlugins/dxf/dxfReader.cpp
2012-03-21 17:36:20 +00:00

205 lines
4.9 KiB
C++

/* dxfReader for OpenSceneGraph Copyright (C) 2005 by GraphArchitecture ( grapharchitecture.com )
* Programmed by Paul de Repentigny <pdr@grapharchitecture.com>
*
* 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 <map>
#include <vector>
#include <iostream>
#include <utility>
#include <sstream>
#include <math.h>
#include <iomanip>
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<CR><LF><SUB><NULL>"
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));
}