1
/******************************************************************************
2
* $Id: ogrdxf_diskio.cpp 20278 2010-08-14 15:11:01Z warmerdam $
4
* Project: DXF Translator
5
* Purpose: Implements low level DXF reading with caching and parsing of
6
* of the code/value pairs.
7
* Author: Frank Warmerdam, warmerdam@pobox.com
9
******************************************************************************
10
* Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
12
* Permission is hereby granted, free of charge, to any person obtaining a
13
* copy of this software and associated documentation files (the "Software"),
14
* to deal in the Software without restriction, including without limitation
15
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
16
* and/or sell copies of the Software, and to permit persons to whom the
17
* Software is furnished to do so, subject to the following conditions:
19
* The above copyright notice and this permission notice shall be included
20
* in all copies or substantial portions of the Software.
22
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28
* DEALINGS IN THE SOFTWARE.
29
****************************************************************************/
33
#include "cpl_string.h"
36
CPL_CVSID("$Id: ogrdxf_diskio.cpp 20278 2010-08-14 15:11:01Z warmerdam $");
38
/************************************************************************/
40
/************************************************************************/
42
OGRDXFReader::OGRDXFReader()
49
iSrcBufferFileOffset = 0;
54
/************************************************************************/
56
/************************************************************************/
58
OGRDXFReader::~OGRDXFReader()
63
/************************************************************************/
65
/************************************************************************/
67
void OGRDXFReader::Initialize( VSILFILE *fp )
73
/************************************************************************/
74
/* ResetReadPointer() */
75
/************************************************************************/
77
void OGRDXFReader::ResetReadPointer( int iNewOffset )
82
iSrcBufferFileOffset = iNewOffset;
85
VSIFSeekL( fp, iNewOffset, SEEK_SET );
88
/************************************************************************/
91
/* Load another block (512 bytes) of input from the source */
93
/************************************************************************/
95
void OGRDXFReader::LoadDiskChunk()
98
CPLAssert( iSrcBufferOffset >= 0 );
100
if( nSrcBufferBytes - iSrcBufferOffset > 511 )
103
if( iSrcBufferOffset > 0 )
105
CPLAssert( nSrcBufferBytes <= 1024 );
106
CPLAssert( iSrcBufferOffset <= nSrcBufferBytes );
108
memmove( achSrcBuffer, achSrcBuffer + iSrcBufferOffset,
109
nSrcBufferBytes - iSrcBufferOffset );
110
iSrcBufferFileOffset += iSrcBufferOffset;
111
nSrcBufferBytes -= iSrcBufferOffset;
112
iSrcBufferOffset = 0;
115
nSrcBufferBytes += VSIFReadL( achSrcBuffer + nSrcBufferBytes,
117
achSrcBuffer[nSrcBufferBytes] = '\0';
119
CPLAssert( nSrcBufferBytes <= 1024 );
120
CPLAssert( iSrcBufferOffset <= nSrcBufferBytes );
123
/************************************************************************/
126
/* Read one type code and value line pair from the DXF file. */
127
/************************************************************************/
129
int OGRDXFReader::ReadValue( char *pszValueBuf, int nValueBufSize )
132
/* -------------------------------------------------------------------- */
133
/* Make sure we have lots of data in our buffer for one value. */
134
/* -------------------------------------------------------------------- */
135
if( nSrcBufferBytes - iSrcBufferOffset < 512 )
138
if( nValueBufSize > 512 )
141
/* -------------------------------------------------------------------- */
142
/* Capture the value code, and skip past it. */
143
/* -------------------------------------------------------------------- */
144
int iStartSrcBufferOffset = iSrcBufferOffset;
145
int nValueCode = atoi(achSrcBuffer + iSrcBufferOffset);
147
// proceed to newline.
148
while( achSrcBuffer[iSrcBufferOffset] != '\n'
149
&& achSrcBuffer[iSrcBufferOffset] != '\r'
150
&& achSrcBuffer[iSrcBufferOffset] != '\0' )
153
if( achSrcBuffer[iSrcBufferOffset] == '\0' )
156
// skip past newline. CR, CRLF, or LFCR
157
if( (achSrcBuffer[iSrcBufferOffset] == '\r'
158
&& achSrcBuffer[iSrcBufferOffset+1] == '\n' )
159
|| (achSrcBuffer[iSrcBufferOffset] == '\n'
160
&& achSrcBuffer[iSrcBufferOffset+1] == '\r' ) )
161
iSrcBufferOffset += 2;
163
iSrcBufferOffset += 1;
165
if( achSrcBuffer[iSrcBufferOffset] == '\0' )
168
/* -------------------------------------------------------------------- */
169
/* Capture the value string. */
170
/* -------------------------------------------------------------------- */
171
int iEOL = iSrcBufferOffset;
173
// proceed to newline.
174
while( achSrcBuffer[iEOL] != '\n'
175
&& achSrcBuffer[iEOL] != '\r'
176
&& achSrcBuffer[iEOL] != '\0' )
179
if( achSrcBuffer[iEOL] == '\0' )
182
if( (iEOL - iSrcBufferOffset) > nValueBufSize-1 )
184
strncpy( pszValueBuf, achSrcBuffer + iSrcBufferOffset,
186
pszValueBuf[nValueBufSize-1] = '\0';
188
CPLDebug( "DXF", "Long line truncated to %d characters.\n%s...",
194
strncpy( pszValueBuf, achSrcBuffer + iSrcBufferOffset,
195
iEOL - iSrcBufferOffset );
196
pszValueBuf[iEOL - iSrcBufferOffset] = '\0';
199
iSrcBufferOffset = iEOL;
201
// skip past newline. CR, CRLF, or LFCR
202
if( (achSrcBuffer[iSrcBufferOffset] == '\r'
203
&& achSrcBuffer[iSrcBufferOffset+1] == '\n' )
204
|| (achSrcBuffer[iSrcBufferOffset] == '\n'
205
&& achSrcBuffer[iSrcBufferOffset+1] == '\r' ) )
206
iSrcBufferOffset += 2;
208
iSrcBufferOffset += 1;
210
/* -------------------------------------------------------------------- */
211
/* Record how big this value was, so it can be unread safely. */
212
/* -------------------------------------------------------------------- */
213
nLastValueSize = iSrcBufferOffset - iStartSrcBufferOffset;
215
/* -------------------------------------------------------------------- */
216
/* Is this a comment? If so, tail recurse to get another line. */
217
/* -------------------------------------------------------------------- */
218
if( nValueCode == 999 )
219
return ReadValue(pszValueBuf,nValueBufSize);
224
/************************************************************************/
227
/* Unread the last value read, accomplished by resetting the */
229
/************************************************************************/
231
void OGRDXFReader::UnreadValue()
234
CPLAssert( iSrcBufferOffset >= nLastValueSize );
235
CPLAssert( nLastValueSize > 0 );
237
iSrcBufferOffset -= nLastValueSize;