1
/******************************************************************************
2
* $Id: ogrdxf_diskio.cpp 18223 2009-12-09 01:15:31Z warmerdam $
4
* Project: DXF Translator
5
* Purpose: Implements Disk IO and low level parsing portions of the
6
* OGRDXFDataSource class
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 18223 2009-12-09 01:15:31Z warmerdam $");
38
/************************************************************************/
39
/* ResetReadPointer() */
40
/************************************************************************/
42
void OGRDXFDataSource::ResetReadPointer( int iNewOffset )
47
iSrcBufferFileOffset = iNewOffset;
50
VSIFSeekL( fp, iNewOffset, SEEK_SET );
53
/************************************************************************/
56
/* Load another block (512 bytes) of input from the source */
58
/************************************************************************/
60
void OGRDXFDataSource::LoadDiskChunk()
63
CPLAssert( iSrcBufferOffset >= 0 );
65
if( nSrcBufferBytes - iSrcBufferOffset > 511 )
68
if( iSrcBufferOffset > 0 )
70
CPLAssert( nSrcBufferBytes <= 1024 );
71
CPLAssert( iSrcBufferOffset <= nSrcBufferBytes );
73
memmove( achSrcBuffer, achSrcBuffer + iSrcBufferOffset,
74
nSrcBufferBytes - iSrcBufferOffset );
75
iSrcBufferFileOffset += iSrcBufferOffset;
76
nSrcBufferBytes -= iSrcBufferOffset;
80
nSrcBufferBytes += VSIFReadL( achSrcBuffer + nSrcBufferBytes,
82
achSrcBuffer[nSrcBufferBytes] = '\0';
84
CPLAssert( nSrcBufferBytes <= 1024 );
85
CPLAssert( iSrcBufferOffset <= nSrcBufferBytes );
88
/************************************************************************/
91
/* Read one type code and value line pair from the DXF file. */
92
/************************************************************************/
94
int OGRDXFDataSource::ReadValue( char *pszValueBuf, int nValueBufSize )
97
/* -------------------------------------------------------------------- */
98
/* Make sure we have lots of data in our buffer for one value. */
99
/* -------------------------------------------------------------------- */
100
if( nSrcBufferBytes - iSrcBufferOffset < 512 )
103
if( nValueBufSize > 512 )
106
/* -------------------------------------------------------------------- */
107
/* Capture the value code, and skip past it. */
108
/* -------------------------------------------------------------------- */
109
int iStartSrcBufferOffset = iSrcBufferOffset;
110
int nValueCode = atoi(achSrcBuffer + iSrcBufferOffset);
112
// proceed to newline.
113
while( achSrcBuffer[iSrcBufferOffset] != '\n'
114
&& achSrcBuffer[iSrcBufferOffset] != '\r'
115
&& achSrcBuffer[iSrcBufferOffset] != '\0' )
118
// skip past newline. CR, CRLF, or LFCR
119
if( (achSrcBuffer[iSrcBufferOffset] == '\r'
120
&& achSrcBuffer[iSrcBufferOffset+1] == '\n' )
121
|| (achSrcBuffer[iSrcBufferOffset] == '\n'
122
&& achSrcBuffer[iSrcBufferOffset+1] == '\r' ) )
123
iSrcBufferOffset += 2;
125
iSrcBufferOffset += 1;
127
if( achSrcBuffer[iSrcBufferOffset] == '\0' )
130
/* -------------------------------------------------------------------- */
131
/* Capture the value string. */
132
/* -------------------------------------------------------------------- */
133
int iEOL = iSrcBufferOffset;
135
// proceed to newline.
136
while( achSrcBuffer[iEOL] != '\n'
137
&& achSrcBuffer[iEOL] != '\r'
138
&& achSrcBuffer[iEOL] != '\0' )
141
if( achSrcBuffer[iEOL] == '\0' )
144
if( (iEOL - iSrcBufferOffset) > nValueBufSize-1 )
146
strncpy( pszValueBuf, achSrcBuffer + iSrcBufferOffset,
148
pszValueBuf[nValueBufSize-1] = '\0';
150
CPLDebug( "DXF", "Long line truncated to %d characters.\n%s...",
156
strncpy( pszValueBuf, achSrcBuffer + iSrcBufferOffset,
157
iEOL - iSrcBufferOffset );
158
pszValueBuf[iEOL - iSrcBufferOffset] = '\0';
161
iSrcBufferOffset = iEOL;
163
// skip past newline. CR, CRLF, or LFCR
164
if( (achSrcBuffer[iSrcBufferOffset] == '\r'
165
&& achSrcBuffer[iSrcBufferOffset+1] == '\n' )
166
|| (achSrcBuffer[iSrcBufferOffset] == '\n'
167
&& achSrcBuffer[iSrcBufferOffset+1] == '\r' ) )
168
iSrcBufferOffset += 2;
170
iSrcBufferOffset += 1;
172
/* -------------------------------------------------------------------- */
173
/* Record how big this value was, so it can be unread safely. */
174
/* -------------------------------------------------------------------- */
175
nLastValueSize = iSrcBufferOffset - iStartSrcBufferOffset;
177
/* -------------------------------------------------------------------- */
178
/* Is this a comment? If so, tail recurse to get another line. */
179
/* -------------------------------------------------------------------- */
180
if( nValueCode == 999 )
181
return ReadValue(pszValueBuf,nValueBufSize);
186
/************************************************************************/
189
/* Unread the last value read, accomplished by resetting the */
191
/************************************************************************/
193
void OGRDXFDataSource::UnreadValue()
196
CPLAssert( iSrcBufferOffset >= nLastValueSize );
197
CPLAssert( nLastValueSize > 0 );
199
iSrcBufferOffset -= nLastValueSize;