-
Notifications
You must be signed in to change notification settings - Fork 66
/
dbfdump.c
240 lines (211 loc) · 8.7 KB
/
dbfdump.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/******************************************************************************
*
* Project: Shapelib
* Purpose: Sample application for dumping .dbf files to the terminal.
* Author: Frank Warmerdam, [email protected]
*
******************************************************************************
* Copyright (c) 1999, Frank Warmerdam
*
* SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
******************************************************************************
*
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "shapefil.h"
int main(int argc, char **argv)
{
/* -------------------------------------------------------------------- */
/* Handle arguments. */
/* -------------------------------------------------------------------- */
bool bHeader = false;
bool bRaw = false;
bool bMultiLine = false;
const char *pszFilename = NULL;
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "-h") == 0)
bHeader = true;
else if (strcmp(argv[i], "-r") == 0)
bRaw = true;
else if (strcmp(argv[i], "-m") == 0)
bMultiLine = true;
else
pszFilename = argv[i];
}
/* -------------------------------------------------------------------- */
/* Display a usage message. */
/* -------------------------------------------------------------------- */
if (pszFilename == NULL)
{
printf("dbfdump [-h] [-r] [-m] xbase_file\n");
printf(" -h: Write header info (field descriptions)\n");
printf(" -r: Write raw field info, numeric values not "
"reformatted\n");
printf(" -m: Multiline, one line per field.\n");
exit(1);
}
/* -------------------------------------------------------------------- */
/* Open the file. */
/* -------------------------------------------------------------------- */
DBFHandle hDBF = DBFOpen(pszFilename, "rb");
if (hDBF == NULL)
{
printf("DBFOpen(%s,\"r\") failed.\n", argv[1]);
exit(2);
}
/* -------------------------------------------------------------------- */
/* If there is no data in this file let the user know. */
/* -------------------------------------------------------------------- */
if (DBFGetFieldCount(hDBF) == 0)
{
printf("There are no fields in this table!\n");
DBFClose(hDBF);
exit(3);
}
/* -------------------------------------------------------------------- */
/* Dump header definitions. */
/* -------------------------------------------------------------------- */
char szTitle[XBASE_FLDNAME_LEN_READ + 1];
int nWidth;
int nDecimals;
if (bHeader)
{
for (int i = 0; i < DBFGetFieldCount(hDBF); i++)
{
const char chNativeType = DBFGetNativeFieldType(hDBF, i);
const DBFFieldType eType =
DBFGetFieldInfo(hDBF, i, szTitle, &nWidth, &nDecimals);
const char *pszTypeName = NULL;
if (eType == FTString)
pszTypeName = "String";
else if (eType == FTInteger)
pszTypeName = "Integer";
else if (eType == FTDouble)
pszTypeName = "Double";
else if (eType == FTLogical)
pszTypeName = "Logical";
else if (eType == FTDate)
pszTypeName = "Date";
else
pszTypeName = "Invalid";
printf("Field %d: Type=%c/%s, Title=`%s', Width=%d, Decimals=%d\n",
i, chNativeType, pszTypeName, szTitle, nWidth, nDecimals);
}
}
/* -------------------------------------------------------------------- */
/* Compute offsets to use when printing each of the field */
/* values. We make each field as wide as the field title+1, or */
/* the field value + 1. */
/* -------------------------------------------------------------------- */
int *panWidth = (int *)malloc(DBFGetFieldCount(hDBF) * sizeof(int));
char szFormat[32];
for (int i = 0; i < DBFGetFieldCount(hDBF) && !bMultiLine; i++)
{
const DBFFieldType eType =
DBFGetFieldInfo(hDBF, i, szTitle, &nWidth, &nDecimals);
const int titleLen = (int)strlen(szTitle);
if (titleLen > nWidth)
panWidth[i] = titleLen;
else
panWidth[i] = nWidth;
if (eType == FTString)
sprintf(szFormat, "%%-%ds ", panWidth[i]);
else
sprintf(szFormat, "%%%ds ", panWidth[i]);
printf(szFormat, szTitle);
}
printf("\n");
/* -------------------------------------------------------------------- */
/* Read all the records */
/* -------------------------------------------------------------------- */
for (int iRecord = 0; iRecord < DBFGetRecordCount(hDBF); iRecord++)
{
if (bMultiLine)
printf("Record: %d\n", iRecord);
for (int i = 0; i < DBFGetFieldCount(hDBF); i++)
{
const DBFFieldType eType =
DBFGetFieldInfo(hDBF, i, szTitle, &nWidth, &nDecimals);
if (bMultiLine)
{
printf("%s: ", szTitle);
}
/* -------------------------------------------------------------------- */
/* Print the record according to the type and formatting */
/* information implicit in the DBF field description. */
/* -------------------------------------------------------------------- */
if (!bRaw)
{
if (DBFIsAttributeNULL(hDBF, iRecord, i))
{
if (eType == FTString)
sprintf(szFormat, "%%-%ds", nWidth);
else
sprintf(szFormat, "%%%ds", nWidth);
printf(szFormat, "(NULL)");
}
else
{
switch (eType)
{
case FTString:
case FTDate:
sprintf(szFormat, "%%-%ds", nWidth);
printf(szFormat,
DBFReadStringAttribute(hDBF, iRecord, i));
break;
case FTInteger:
sprintf(szFormat, "%%%dd", nWidth);
printf(szFormat,
DBFReadIntegerAttribute(hDBF, iRecord, i));
break;
case FTDouble:
sprintf(szFormat, "%%%d.%dlf", nWidth, nDecimals);
printf(szFormat,
DBFReadDoubleAttribute(hDBF, iRecord, i));
break;
case FTLogical:
sprintf(szFormat, "%%-%ds", nWidth);
printf(szFormat,
DBFReadLogicalAttribute(hDBF, iRecord, i));
break;
default:
break;
}
}
}
/* -------------------------------------------------------------------- */
/* Just dump in raw form (as formatted in the file). */
/* -------------------------------------------------------------------- */
else
{
sprintf(szFormat, "%%-%ds", nWidth);
printf(szFormat, DBFReadStringAttribute(hDBF, iRecord, i));
}
/* -------------------------------------------------------------------- */
/* Write out any extra spaces required to pad out the field */
/* width. */
/* -------------------------------------------------------------------- */
if (bMultiLine)
{
printf("\n");
}
else
{
sprintf(szFormat, "%%%ds", panWidth[i] - nWidth + 1);
printf(szFormat, "");
}
fflush(stdout);
}
if (DBFIsRecordDeleted(hDBF, iRecord))
printf("(DELETED)");
printf("\n");
}
DBFClose(hDBF);
free(panWidth);
return (0);
}