1 : /******************************************************************************
2 : * $Id: ll_recio.cpp 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: EPIInfo .REC Reader
5 : * Purpose: Implements low level REC reading API.
6 : * Author: Frank Warmerdam <warmerdam@pobox.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogr_rec.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ll_recio.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
35 :
36 : static int nNextRecLine = 0;
37 :
38 : /************************************************************************/
39 : /* RECGetFieldCount() */
40 : /************************************************************************/
41 :
42 0 : int RECGetFieldCount( FILE * fp )
43 :
44 : {
45 0 : const char *pszLine = CPLReadLine( fp );
46 0 : if( pszLine == NULL )
47 0 : return -1;
48 0 : if( atoi(pszLine) < 1 )
49 0 : return -1;
50 :
51 0 : nNextRecLine = 1;
52 :
53 0 : return atoi(pszLine);
54 : }
55 :
56 : /************************************************************************/
57 : /* RECGetFieldDefinition() */
58 : /************************************************************************/
59 :
60 0 : int RECGetFieldDefinition( FILE *fp, char *pszFieldname,
61 : int *pnType, int *pnWidth, int *pnPrecision )
62 :
63 : {
64 0 : const char *pszLine = CPLReadLine( fp );
65 : int nTypeCode;
66 0 : OGRFieldType eFType = OFTString;
67 :
68 0 : if( pszLine == NULL )
69 0 : return FALSE;
70 :
71 0 : if( strlen(pszLine) < 44 )
72 0 : return FALSE;
73 :
74 : // Extract field width.
75 0 : *pnWidth = atoi( RECGetField( pszLine, 37, 4 ) );
76 :
77 : // Is this an real, integer or string field? Default to string.
78 0 : nTypeCode = atoi(RECGetField(pszLine,33,4));
79 0 : if( nTypeCode == 0 )
80 0 : eFType = OFTInteger;
81 0 : else if( nTypeCode > 100 && nTypeCode < 120 )
82 : {
83 0 : eFType = OFTReal;
84 : }
85 0 : else if( nTypeCode == 6 )
86 : {
87 0 : if( *pnWidth < 3 )
88 0 : eFType = OFTInteger;
89 : else
90 0 : eFType = OFTReal;
91 : }
92 : else
93 0 : eFType = OFTString;
94 :
95 0 : *pnType = (int) eFType;
96 :
97 0 : strcpy( pszFieldname, RECGetField( pszLine, 2, 10 ) );
98 0 : *pnPrecision = 0;
99 :
100 0 : if( nTypeCode > 100 && nTypeCode < 120 )
101 0 : *pnPrecision = nTypeCode - 100;
102 0 : else if( eFType == OFTReal )
103 : {
104 0 : *pnPrecision = *pnWidth - 1;
105 : }
106 :
107 0 : nNextRecLine++;
108 :
109 0 : return TRUE;
110 : }
111 :
112 : /************************************************************************/
113 : /* RECGetField() */
114 : /************************************************************************/
115 :
116 0 : const char *RECGetField( const char *pszSrc, int nStart, int nWidth )
117 :
118 : {
119 : static char szWorkField[128];
120 : int i;
121 :
122 0 : strncpy( szWorkField, pszSrc+nStart-1, nWidth );
123 0 : szWorkField[nWidth] = '\0';
124 :
125 0 : i = strlen(szWorkField)-1;
126 :
127 0 : while( i >= 0 && szWorkField[i] == ' ' )
128 0 : szWorkField[i--] = '\0';
129 :
130 0 : return szWorkField;
131 : }
132 :
133 : /************************************************************************/
134 : /* RECReadRecord() */
135 : /************************************************************************/
136 :
137 0 : int RECReadRecord( FILE *fp, char *pszRecord, int nRecordLength )
138 :
139 : {
140 0 : int nDataLen = 0;
141 :
142 0 : while( nDataLen < nRecordLength )
143 : {
144 0 : const char *pszLine = CPLReadLine( fp );
145 : int iSegLen;
146 :
147 0 : nNextRecLine++;
148 :
149 0 : if( pszLine == NULL )
150 0 : return FALSE;
151 :
152 0 : if( *pszLine == 26 /* Cntl-Z - DOS EOF */ )
153 0 : return FALSE;
154 :
155 : // If the end-of-line markers is '?' the record is deleted.
156 0 : iSegLen = strlen(pszLine);
157 0 : if( pszLine[iSegLen-1] == '?' )
158 : {
159 0 : pszRecord[0] = '\0';
160 0 : nDataLen = 0;
161 0 : continue;
162 : }
163 :
164 : // Strip off end-of-line '!' marker.
165 0 : if( pszLine[iSegLen-1] != '!'
166 0 : && pszLine[iSegLen-1] != '^' )
167 : {
168 : CPLError( CE_Failure, CPLE_AppDefined,
169 : "Apparent corrupt data line at line=%d",
170 0 : nNextRecLine );
171 0 : return FALSE;
172 : }
173 :
174 0 : iSegLen--;
175 0 : if( nDataLen + iSegLen > nRecordLength )
176 : {
177 : CPLError( CE_Failure, CPLE_AppDefined,
178 : "Too much data for line at line %d.",
179 0 : nNextRecLine-1 );
180 0 : return FALSE;
181 : }
182 :
183 0 : strncpy( pszRecord+nDataLen, pszLine, iSegLen );
184 0 : pszRecord[nDataLen+iSegLen] = '\0';
185 0 : nDataLen += iSegLen;
186 : }
187 :
188 0 : return nDataLen;
189 : }
|