root/OpenSceneGraph/trunk/src/osgPlugins/shp/XBaseParser.cpp @ 13041

Revision 13041, 7.7 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1#include "XBaseParser.h"
2
3#include <vector>
4#include <string>
5
6#include <memory.h>
7#include <stdio.h>
8#include <stdlib.h>
9#if defined(_MSC_VER) || defined(__MINGW32__)
10    #include <io.h>
11#else
12    #include <unistd.h>
13#endif
14
15#include <fcntl.h>
16#include <osg/Notify>
17
18namespace ESRIShape
19{
20
21
22void XBaseHeader::print()
23{
24    OSG_INFO << "VersionNumber = " << (int) _versionNumber << std::endl
25                           << "LastUpdate    = " << 1900 + (int) _lastUpdate[0] << "/" << (int) _lastUpdate[1] << "/" << (int) _lastUpdate[2] << std::endl
26                           << "NumRecord     = " << _numRecord << std::endl
27                           << "HeaderLength  = " << _headerLength << std::endl
28                           << "RecordLength  = " << _recordLength << std::endl;
29}
30
31bool XBaseHeader::read(int fd)
32{
33    int nbytes = 0;
34
35    if ((nbytes = ::read( fd, &_versionNumber, sizeof(_versionNumber))) <= 0) return false;
36    if ((nbytes = ::read( fd, &_lastUpdate, sizeof(_lastUpdate))) <= 0) return false;
37    if ((nbytes = ::read( fd, &_numRecord, sizeof(_numRecord))) <= 0) return false;
38    if ((nbytes = ::read( fd, &_headerLength, sizeof(_headerLength))) <= 0) return false;
39    if ((nbytes = ::read( fd, &_recordLength, sizeof(_recordLength))) <= 0) return false;
40    if ((nbytes = ::read( fd, &_reserved, sizeof(_reserved))) <= 0) return false;
41    if ((nbytes = ::read( fd, &_incompleteTransaction, sizeof(_incompleteTransaction))) <= 0) return false;
42    if ((nbytes = ::read( fd, &_encryptionFlag, sizeof(_encryptionFlag))) <= 0) return false;
43    if ((nbytes = ::read( fd, &_freeRecordThread, sizeof(_freeRecordThread))) <= 0) return false;
44    if ((nbytes = ::read( fd, &_reservedMultiUser, sizeof(_reservedMultiUser))) <= 0) return false;
45    if ((nbytes = ::read( fd, &_mdxflag, sizeof(_mdxflag))) <= 0) return false;
46    if ((nbytes = ::read( fd, &_languageDriver, sizeof(_languageDriver))) <= 0) return false;
47    if ((nbytes = ::read( fd, &_reserved2, sizeof(_reserved2))) <= 0) return false;
48
49    return true;
50}
51
52void XBaseFieldDescriptor::print()
53{
54    OSG_INFO << "name           = " << _name << std::endl
55                           << "type           = " << _fieldType << std::endl
56                           << "length         = " << (int) _fieldLength << std::endl
57                           << "decimalCount   = " << (int) _decimalCount << std::endl
58                           << "workAreaID     = " << (int) _workAreaID << std::endl
59                           << "setFieldFlag   = " << (int) _setFieldFlag << std::endl
60                           << "indexFieldFlag = " << (int) _indexFieldFlag << std::endl;
61}
62
63bool XBaseFieldDescriptor::read(int fd)
64{
65    int nbytes = 0;
66
67    if ((nbytes = ::read( fd, &_name, sizeof(_name))) <= 0) return false;
68    if ((nbytes = ::read( fd, &_fieldType, sizeof(_fieldType))) <= 0) return false;
69    if ((nbytes = ::read( fd, &_fieldDataAddress, sizeof(_fieldDataAddress))) <= 0) return false;
70    if ((nbytes = ::read( fd, &_fieldLength, sizeof(_fieldLength))) <= 0) return false;
71    if ((nbytes = ::read( fd, &_decimalCount, sizeof(_decimalCount))) <= 0) return false;
72    if ((nbytes = ::read( fd, &_reservedMultiUser, sizeof(_reservedMultiUser))) <= 0) return false;
73    if ((nbytes = ::read( fd, &_workAreaID, sizeof(_workAreaID))) <= 0) return false;
74    if ((nbytes = ::read( fd, &_reservedMultiUser2, sizeof(_reservedMultiUser2))) <= 0) return false;
75    if ((nbytes = ::read( fd, &_setFieldFlag, sizeof(_setFieldFlag))) <= 0) return false;
76    if ((nbytes = ::read( fd, &_reserved, sizeof(_reserved))) <= 0) return false;
77    if ((nbytes = ::read( fd, &_indexFieldFlag, sizeof(_indexFieldFlag))) <= 0) return false;
78
79    return true;
80}
81
82
83XBaseParser::XBaseParser(const std::string fileName):
84    _valid(false)
85{
86    int fd = 0;
87    if (fileName.empty() == false)
88    {
89#ifdef WIN32
90        if( (fd = open( fileName.c_str(), O_RDONLY | O_BINARY )) <= 0 )
91#else
92        if( (fd = ::open( fileName.c_str(), O_RDONLY )) <= 0 )
93#endif
94        {
95            perror( fileName.c_str() );
96            if (fd) close( fd );
97            return;
98        }
99    }
100
101    _valid = parse(fd);
102}
103
104bool XBaseParser::parse(int fd)
105{
106    int nbytes;
107    XBaseHeader _xBaseHeader;
108    std::vector<XBaseFieldDescriptor> _xBaseFieldDescriptorList;
109    XBaseFieldDescriptor _xBaseFieldDescriptorTmp;
110
111
112    // ** read the header
113    if (_xBaseHeader.read(fd) == false) return false;
114//    _xBaseHeader.print();
115
116
117    // ** read field descriptor
118    bool fieldDescriptorDone = false;
119    Byte nullTerminator;
120
121    while (fieldDescriptorDone == false)
122    {
123        // ** store the field descriptor
124        if (_xBaseFieldDescriptorTmp.read(fd) == false) return false;
125        _xBaseFieldDescriptorList.push_back(_xBaseFieldDescriptorTmp);
126//        _xBaseFieldDescriptorTmp.print();
127
128        // ** check the terminator
129        if ((nbytes = ::read( fd, &nullTerminator, sizeof(nullTerminator))) <= 0) return false;
130        if (nullTerminator == 0x0D)
131            fieldDescriptorDone = true;
132        else
133            ::lseek( fd, -1, SEEK_CUR);
134    }
135
136
137    // ** move to the end of the Header
138    ::lseek( fd, _xBaseHeader._headerLength + 1, SEEK_SET);
139
140
141    // ** reserve AttributeListList
142    _shapeAttributeListList.reserve(_xBaseHeader._numRecord);
143
144
145    // ** read each record and store them in the ShapeAttributeListList
146    char* record = new char[_xBaseHeader._recordLength];
147
148    std::vector<XBaseFieldDescriptor>::iterator it, end = _xBaseFieldDescriptorList.end();
149    for (Integer i = 0; i < _xBaseHeader._numRecord; ++i)
150    {
151        if ((nbytes = ::read( fd, record, _xBaseHeader._recordLength)) <= 0) return false;
152
153        char * recordPtr = record;
154        osgSim::ShapeAttributeList * shapeAttributeList = new osgSim::ShapeAttributeList;
155        shapeAttributeList->reserve(_xBaseFieldDescriptorList.size());
156
157        for (it = _xBaseFieldDescriptorList.begin(); it != end; ++it)
158        {
159            switch (it->_fieldType)
160            {
161            case 'C':
162            {
163                char* str = new char[it->_fieldLength + 1];
164                memcpy(str, recordPtr, it->_fieldLength);
165                str[it->_fieldLength] = 0;
166                shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (char*) str));
167                delete [] str;
168                break;
169            }
170            case 'N':
171            {
172                char* number = new char[it->_fieldLength + 1];
173                memcpy(number, recordPtr, it->_fieldLength);
174                number[it->_fieldLength] = 0;
175                shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (int) atoi(number)));
176                delete [] number;
177                break;
178            }
179            case 'I':
180            {
181                int number;
182                memcpy(&number, record, it->_fieldLength);
183                shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (int) number));
184                break;
185            }
186            case 'O':
187            {
188                double number;
189                memcpy(&number, record, it->_fieldLength);
190                shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (double) number));
191                break;
192            }
193            default:
194            {
195                OSG_WARN << "ESRIShape::XBaseParser : record type "
196                                       << it->_fieldType << "not supported, skipped" << std::endl;
197                shapeAttributeList->push_back(osgSim::ShapeAttribute((const char *) it->_name, (double) 0));
198                break;
199            }
200
201
202            }
203
204            recordPtr += it->_fieldLength;
205        }
206
207        _shapeAttributeListList.push_back(shapeAttributeList);
208    }
209
210    delete [] record;
211
212    close (fd);
213
214    return true;
215}
216
217
218}
219
Note: See TracBrowser for help on using the browser.