📄 xbaseparser.cpp
字号:
#include "XBaseParser.h"#include <vector>#include <string>#include <memory.h>#include <stdio.h>#include <stdlib.h>#if defined(_MSC_VER) || defined(__MINGW32__) #include <io.h>#else #include <unistd.h>#endif #include <fcntl.h>#include <osg/Notify>namespace ESRIShape{void XBaseHeader::print(){ osg::notify(osg::INFO) << "VersionNumber = " << (int) _versionNumber << std::endl << "LastUpdate = " << 1900 + (int) _lastUpdate[0] << "/" << (int) _lastUpdate[1] << "/" << (int) _lastUpdate[2] << std::endl << "NumRecord = " << _numRecord << std::endl << "HeaderLength = " << _headerLength << std::endl << "RecordLength = " << _recordLength << std::endl; }bool XBaseHeader::read(int fd){ int nbytes = 0; if ((nbytes = ::read( fd, &_versionNumber, sizeof(_versionNumber))) <= 0) return false; if ((nbytes = ::read( fd, &_lastUpdate, sizeof(_lastUpdate))) <= 0) return false; if ((nbytes = ::read( fd, &_numRecord, sizeof(_numRecord))) <= 0) return false; if ((nbytes = ::read( fd, &_headerLength, sizeof(_headerLength))) <= 0) return false; if ((nbytes = ::read( fd, &_recordLength, sizeof(_recordLength))) <= 0) return false; if ((nbytes = ::read( fd, &_reserved, sizeof(_reserved))) <= 0) return false; if ((nbytes = ::read( fd, &_incompleteTransaction, sizeof(_incompleteTransaction))) <= 0) return false; if ((nbytes = ::read( fd, &_encryptionFlag, sizeof(_encryptionFlag))) <= 0) return false; if ((nbytes = ::read( fd, &_freeRecordThread, sizeof(_freeRecordThread))) <= 0) return false; if ((nbytes = ::read( fd, &_reservedMultiUser, sizeof(_reservedMultiUser))) <= 0) return false; if ((nbytes = ::read( fd, &_mdxflag, sizeof(_mdxflag))) <= 0) return false; if ((nbytes = ::read( fd, &_languageDriver, sizeof(_languageDriver))) <= 0) return false; if ((nbytes = ::read( fd, &_reserved2, sizeof(_reserved2))) <= 0) return false; return true;} void XBaseFieldDescriptor::print(){ osg::notify(osg::INFO) << "name = " << _name << std::endl << "type = " << _fieldType << std::endl << "length = " << (int) _fieldLength << std::endl << "decimalCount = " << (int) _decimalCount << std::endl << "workAreaID = " << (int) _workAreaID << std::endl << "setFieldFlag = " << (int) _setFieldFlag << std::endl << "indexFieldFlag = " << (int) _indexFieldFlag << std::endl;}bool XBaseFieldDescriptor::read(int fd){ int nbytes = 0; if ((nbytes = ::read( fd, &_name, sizeof(_name))) <= 0) return false; if ((nbytes = ::read( fd, &_fieldType, sizeof(_fieldType))) <= 0) return false; if ((nbytes = ::read( fd, &_fieldDataAddress, sizeof(_fieldDataAddress))) <= 0) return false; if ((nbytes = ::read( fd, &_fieldLength, sizeof(_fieldLength))) <= 0) return false; if ((nbytes = ::read( fd, &_decimalCount, sizeof(_decimalCount))) <= 0) return false; if ((nbytes = ::read( fd, &_reservedMultiUser, sizeof(_reservedMultiUser))) <= 0) return false; if ((nbytes = ::read( fd, &_workAreaID, sizeof(_workAreaID))) <= 0) return false; if ((nbytes = ::read( fd, &_reservedMultiUser2, sizeof(_reservedMultiUser2))) <= 0) return false; if ((nbytes = ::read( fd, &_setFieldFlag, sizeof(_setFieldFlag))) <= 0) return false; if ((nbytes = ::read( fd, &_reserved, sizeof(_reserved))) <= 0) return false; if ((nbytes = ::read( fd, &_indexFieldFlag, sizeof(_indexFieldFlag))) <= 0) return false; return true;}XBaseParser::XBaseParser(const std::string fileName): _valid(false){ int fd = 0; if (fileName.empty() == false) {#ifdef WIN32 if( (fd = open( fileName.c_str(), O_RDONLY | O_BINARY )) <= 0 )#else if( (fd = ::open( fileName.c_str(), O_RDONLY )) <= 0 )#endif { perror( fileName.c_str() ); return ; } } _valid = parse(fd);} bool XBaseParser::parse(int fd){ int nbytes; XBaseHeader _xBaseHeader; std::vector<XBaseFieldDescriptor> _xBaseFieldDescriptorList; XBaseFieldDescriptor _xBaseFieldDescriptorTmp; // ** read the header if (_xBaseHeader.read(fd) == false) return false;// _xBaseHeader.print(); // ** read field descriptor bool fieldDescriptorDone = false; Byte nullTerminator; while (fieldDescriptorDone == false) { // ** store the field descriptor if (_xBaseFieldDescriptorTmp.read(fd) == false) return false; _xBaseFieldDescriptorList.push_back(_xBaseFieldDescriptorTmp);// _xBaseFieldDescriptorTmp.print(); // ** check the terminator if ((nbytes = ::read( fd, &nullTerminator, sizeof(nullTerminator))) <= 0) return false; if (nullTerminator == 0x0D) fieldDescriptorDone = true; else ::lseek( fd, -1, SEEK_CUR); } // ** move to the end of the Header ::lseek( fd, _xBaseHeader._headerLength + 1, SEEK_SET); // ** reserve AttributeListList _shapeAttributeListList.reserve(_xBaseHeader._numRecord); // ** read each record and store them in the ShapeAttributeListList char* record = new char[_xBaseHeader._recordLength]; std::vector<XBaseFieldDescriptor>::iterator it, end = _xBaseFieldDescriptorList.end(); for (Integer i = 0; i < _xBaseHeader._numRecord; ++i) { if ((nbytes = ::read( fd, record, _xBaseHeader._recordLength)) <= 0) return false; char * recordPtr = record; osgSim::ShapeAttributeList * shapeAttributeList = new osgSim::ShapeAttributeList; shapeAttributeList->reserve(_xBaseFieldDescriptorList.size()); for (it = _xBaseFieldDescriptorList.begin(); it != end; ++it) { switch (it->_fieldType) { case 'C': { char* str = new char[it->_fieldLength + 1]; memcpy(str, recordPtr, it->_fieldLength); str[it->_fieldLength] = 0; shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (char*) str)); delete [] str; break; } case 'N': { char* number = new char[it->_fieldLength + 1]; memcpy(number, recordPtr, it->_fieldLength); number[it->_fieldLength] = 0; shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (int) atoi(number))); delete [] number; break; } case 'I': { int number; memcpy(&number, record, it->_fieldLength); shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (int) number)); break; } case 'O': { double number; memcpy(&number, record, it->_fieldLength); shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (double) number)); break; } default: { osg::notify(osg::WARN) << "ESRIShape::XBaseParser : record type " << it->_fieldType << "not supported, skipped" << std::endl; shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (double) 0)); break; } } recordPtr += it->_fieldLength; } _shapeAttributeListList.push_back(shapeAttributeList); } delete [] record; close (fd); return true;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -