1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include <math.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8
9 #include "cdi.h"
10
11 static void
12 printAtts(int vlistID);
13
main(int argc,const char ** argv)14 int main(int argc, const char **argv)
15 {
16 // todo: handle optional arguments here to increase test coverage
17 const char *fname = (argc > 1) ? argv[1] : "test.nc";
18
19 int countMissingValues = 1;
20
21 int streamID = streamOpenRead(fname);
22 if (streamID < 0)
23 {
24 fprintf(stderr, "Open failed for file %s: %s\n",
25 fname, cdiStringError(streamID));
26 return EXIT_FAILURE;
27 }
28 int vlistID = streamInqVlist(streamID);
29 size_t nVars = (size_t)vlistNvars(vlistID);
30
31 double *buf = NULL;
32 size_t bufSize = 0;
33 size_t allNmissSum = 0;
34
35 printAtts(vlistID);
36
37 for (int tsID = 0; streamInqTimestep(streamID, tsID); ++tsID)
38 {
39 for (size_t varID = 0; varID < nVars; ++varID)
40 {
41 size_t memSize = (size_t)vlistInqVarSize(vlistID, (int)varID)
42 * sizeof (double);
43 SizeType nmiss;
44 if (memSize > bufSize)
45 {
46 double *temp = (double *)realloc(buf, memSize);
47 if (!temp)
48 {
49 perror("read buffer reallocation failed");
50 return EXIT_FAILURE;
51 }
52 buf = temp;
53 }
54 streamReadVar(streamID, (int)varID, buf, &nmiss);
55 allNmissSum += nmiss;
56 }
57 }
58 if (countMissingValues)
59 printf("missing values count = %zu\n", allNmissSum);
60 streamClose(streamID);
61 return EXIT_SUCCESS;
62 }
63
64 static void
printAtts(int vlistID)65 printAtts(int vlistID)
66 {
67 size_t nVars = (size_t)vlistNvars(vlistID);
68 static const char globDesc[] = "global",
69 varDescPrefix[] = "variable ";
70 size_t digitsPerInt = 9;
71 size_t bufSize = digitsPerInt + sizeof (varDescPrefix);
72 void *restrict buf = malloc(bufSize);
73 if (!buf)
74 {
75 perror("attribute buffer resize failed");
76 exit(EXIT_FAILURE);
77 }
78 for (size_t varIdx = 0; varIdx <= nVars; ++varIdx)
79 {
80 int nAtts, attType, attLen;
81 char attName[CDI_MAX_NAME + 1];
82 int varID = (int)varIdx - 1;
83 cdiInqNatts(vlistID, varID, &nAtts);
84 for (size_t attIdx = 0; attIdx < (size_t)nAtts; attIdx++ )
85 {
86 int rc = cdiInqAtt(vlistID, varID, (int)attIdx,
87 attName, &attType, &attLen);
88 {
89 const char *varDesc = varIdx > 0
90 ? (sprintf((char *)buf, "%s%d", varDescPrefix,
91 vlistInqVarCode(vlistID, varID)), (char *)buf)
92 : globDesc;
93 printf("%s attribute \"%s\", value: ",
94 varDesc, attName);
95 }
96 if (attLen < 0)
97 {
98 puts("error retrieving value");
99 continue;
100 }
101 size_t elemSize = 0;
102 switch (attType)
103 {
104 case CDI_DATATYPE_TXT:
105 elemSize = 1;
106 break;
107 case CDI_DATATYPE_FLT:
108 elemSize = sizeof (double);
109 break;
110 case CDI_DATATYPE_INT:
111 elemSize = sizeof (int);
112 break;
113 }
114
115 size_t attSize = elemSize * ((size_t)attLen + 1);
116 if (attSize > bufSize)
117 {
118 if (!(buf = realloc(buf, attSize)))
119 {
120 perror("attribute buffer resize failed");
121 exit(EXIT_FAILURE);
122 }
123 }
124
125 switch (attType)
126 {
127 case CDI_DATATYPE_TXT:
128 rc = cdiInqAttTxt(vlistID, (int)varID, attName,
129 attLen, (char *)buf);
130 if (rc == CDI_NOERR)
131 printf("\"%.*s\"", attLen, (char *)buf);
132 break;
133 case CDI_DATATYPE_FLT:
134 rc = cdiInqAttFlt(vlistID, (int)varID, attName,
135 attLen + 1, (double *)buf);
136 if (rc == CDI_NOERR && attLen)
137 {
138 const double *restrict dp = (const double*)buf;
139 printf("%10g", dp[0]);
140 for (size_t i = 1; i < (size_t)attLen; ++i)
141 printf(", %10g", dp[i]);
142 }
143 break;
144 case CDI_DATATYPE_INT:
145 rc = cdiInqAttInt(vlistID, (int)varID, attName,
146 attLen + 1, (int *)buf);
147 if (rc == CDI_NOERR && attLen)
148 {
149 const int *restrict ip = (const int *)buf;
150 printf("%d", ip[0]);
151 for (size_t i = 1; i < (size_t)attLen; ++i)
152 printf(", %d", ip[i]);
153 }
154 break;
155 }
156
157 if (rc == CDI_NOERR)
158 {
159 putchar('\n');
160 }
161 else
162 {
163 puts("error retrieving value");
164 }
165 }
166 }
167 free(buf);
168 }
169
170
171 /*
172 * Local Variables:
173 * c-file-style: "Java"
174 * c-basic-offset: 2
175 * indent-tabs-mode: nil
176 * show-trailing-whitespace: t
177 * require-trailing-newline: t
178 * End:
179 */
180