00001
00011 #include <config.h>
00012 #include <libcf_src.h>
00013 #include <libcf_int.h>
00014 #include <netcdf.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <stdio.h>
00018 #include <time.h>
00165 int
00166 nccf_inq_libvers(char *version_string)
00167 {
00168 char ver[NC_MAX_NAME + 1];
00169
00170 sprintf(ver, "libcf library version %s", VERSION);
00171 if (version_string)
00172 strcpy(version_string, ver);
00173
00174 return CF_NOERR;
00175 }
00176
00177
00178
00179 static int
00180 nccf_append_att(int ncid, const char *name, const char *string)
00181 {
00182 char *att_str = NULL;
00183 size_t len, new_len;
00184 int ret;
00185
00186
00187 ret = nc_inq_attlen(ncid, NC_GLOBAL, name, &len);
00188
00189 if (ret == NC_ENOTATT)
00190 {
00191
00192
00193 if ((ret = nc_put_att_text(ncid, NC_GLOBAL, name,
00194 strlen(string) + 1, string)))
00195 return ret;
00196 }
00197 else if (ret == NC_NOERR)
00198 {
00199
00200
00201
00202 new_len = len + strlen(string) + 1;
00203 if (!(att_str = malloc(new_len + 1)))
00204 return CF_ENOMEM;
00205
00206
00207 if ((ret = nc_get_att_text(ncid, NC_GLOBAL, name, att_str)))
00208 BAIL(CF_ENETCDF);
00209
00210
00211 if (strstr(att_str, string))
00212 {
00213 free(att_str);
00214 return CF_NOERR;
00215 }
00216
00217
00218 att_str[len] = 0;
00219 strcat(att_str, " ");
00220 strcat(att_str, string);
00221
00222
00223 if ((ret = nc_del_att(ncid, NC_GLOBAL, name)))
00224 BAIL(ret);
00225
00226
00227 if ((ret = nc_put_att_text(ncid, NC_GLOBAL, name,
00228 strlen(att_str) + 1, att_str)))
00229 BAIL(ret);
00230 }
00231
00232 exit:
00233 if (att_str)
00234 free(att_str);
00235 return ret;
00236 }
00237
00253 int
00254 nccf_def_convention(int ncid)
00255 {
00256 return nccf_append_att(ncid, CF_CONVENTIONS, CF_CONVENTION_STRING);
00257 }
00258
00275 int
00276 nccf_inq_convention(int ncid, int *cf_convention)
00277 {
00278 size_t len, new_len;
00279 char *existing_att = NULL;
00280 int ret = CF_NOERR;
00281
00282
00283 ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_CONVENTIONS, &len);
00284
00285 if (ret == NC_NOERR)
00286 {
00287
00288
00289 new_len = len + strlen(CF_CONVENTION_STRING) + 1;
00290 if (!(existing_att = malloc(new_len)))
00291 return CF_ENOMEM;
00292
00293
00294 if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_CONVENTIONS,
00295 existing_att)))
00296 BAIL(CF_ENETCDF);
00297
00298
00299 if (strstr(existing_att, CF_CONVENTION_STRING))
00300 {
00301 if (cf_convention)
00302 *cf_convention = 1;
00303 ret = CF_NOERR;
00304 }
00305 }
00306 else if (ret == NC_ENOTATT)
00307 {
00308
00309
00310 if (cf_convention)
00311 *cf_convention = 0;
00312 ret = NC_NOERR;
00313 }
00314 else
00315 BAIL(CF_ENETCDF);
00316
00317 exit:
00318 if (existing_att)
00319 free(existing_att);
00320 return ret;
00321 }
00322
00323
00350
00351
00352 int
00353 nccf_def_file(int ncid, const char *title, const char *history)
00354 {
00355 int ret;
00356
00357
00358
00359 if ((ret = nccf_def_convention(ncid)))
00360 return ret;
00361
00362
00363 if (title)
00364 if ((ret = nc_put_att_text(ncid, NC_GLOBAL, CF_TITLE,
00365 strlen(title) + 1, title)))
00366 return ret;
00367
00368
00369
00370 if (history)
00371 ret = nccf_add_history(ncid, history);
00372
00373 return ret;
00374 }
00375
00377 #define NCCF_MAX_TIMESTAMP_LEN 35
00378
00390 int
00391 nccf_add_history(int ncid, const char *history)
00392 {
00393 time_t now;
00394 char *hist_str;
00395 char timestamp[NCCF_MAX_TIMESTAMP_LEN + 1];
00396 struct tm *timptr;
00397 int ret;
00398
00399 if (!history)
00400 return NC_NOERR;
00401
00402
00403 time(&now);
00404 if (!(timptr = localtime(&now)))
00405 return CF_ETIME;
00406 if (!strftime(timestamp, NCCF_MAX_TIMESTAMP_LEN, "%x %X", timptr))
00407 return CF_ETIME;
00408
00409
00410 if (!(hist_str = malloc(strlen(history) + strlen(timestamp) + 2)))
00411 return CF_ENOMEM;
00412
00413
00414
00415 sprintf(hist_str, "%s %s\n", timestamp, history);
00416
00417
00418 ret = nccf_append_att(ncid, CF_HISTORY, hist_str);
00419
00420
00421 free(hist_str);
00422
00423 return ret;
00424 }
00425
00459 int
00460 nccf_inq_file(int ncid, size_t *title_lenp, char *title,
00461 size_t *history_lenp, char *history)
00462 {
00463 int ret;
00464
00465
00466 if (title_lenp)
00467 if ((ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_TITLE, title_lenp)))
00468 return ret;
00469
00470
00471 if (title)
00472 if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_TITLE, title)))
00473 return ret;
00474
00475
00476 if (history_lenp)
00477 if ((ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_HISTORY, history_lenp)))
00478 return ret;
00479
00480
00481 if (history)
00482 if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_HISTORY, history)))
00483 return ret;
00484
00485 return NC_NOERR;
00486
00487 }
00488
00519 int
00520 nccf_def_notes(int ncid, int varid, const char *institution,
00521 const char *source, const char *comment,
00522 const char *references)
00523 {
00524 int ret;
00525
00526 if (institution)
00527 if ((ret = nc_put_att_text(ncid, varid, CF_INSTITUTION,
00528 strlen(institution) + 1, institution)))
00529 return ret;
00530
00531 if (source)
00532 if ((ret = nc_put_att_text(ncid, varid, CF_SOURCE,
00533 strlen(source) + 1, source)))
00534 return ret;
00535
00536 if (comment)
00537 if ((ret = nc_put_att_text(ncid, varid, CF_COMMENT,
00538 strlen(comment) + 1, comment)))
00539 return ret;
00540
00541 if (references)
00542 if ((ret = nc_put_att_text(ncid, varid, CF_REFERENCES,
00543 strlen(references) + 1, references)))
00544 return ret;
00545
00546 return CF_NOERR;
00547 }
00548
00595 int nccf_inq_notes(int ncid, int varid, size_t *institution_lenp,
00596 char *institution, size_t *source_lenp, char *source,
00597 size_t *comment_lenp, char *comment,
00598 size_t *references_lenp, char *references)
00599 {
00600 int ret;
00601
00602 if (institution_lenp)
00603 {
00604 ret = nc_inq_attlen(ncid, varid, CF_INSTITUTION, institution_lenp);
00605 if (ret == NC_ENOTATT)
00606 *institution_lenp = 0;
00607 else if (ret)
00608 return ret;
00609 }
00610
00611 if (institution)
00612 {
00613 ret = nc_get_att_text(ncid, varid, CF_INSTITUTION, institution);
00614 if (ret == NC_ENOTATT)
00615 strcpy(institution, "");
00616 else if (ret)
00617 return ret;
00618 }
00619
00620 if (source_lenp)
00621 {
00622 ret = nc_inq_attlen(ncid, varid, CF_SOURCE, source_lenp);
00623 if (ret == NC_ENOTATT)
00624 *source_lenp = 0;
00625 else if (ret)
00626 return ret;
00627 }
00628
00629 if (source)
00630 {
00631 ret = nc_get_att_text(ncid, varid, CF_SOURCE, source);
00632 if (ret == NC_ENOTATT)
00633 strcpy(source, "");
00634 else if (ret)
00635 return ret;
00636 }
00637
00638 if (comment_lenp)
00639 {
00640 ret = nc_inq_attlen(ncid, varid, CF_COMMENT, comment_lenp);
00641 if (ret == NC_ENOTATT)
00642 *comment_lenp = 0;
00643 else if (ret)
00644 return ret;
00645 }
00646
00647 if (comment)
00648 {
00649 ret = nc_get_att_text(ncid, varid, CF_COMMENT, comment);
00650 if (ret == NC_ENOTATT)
00651 strcpy(comment, "");
00652 else if (ret)
00653 return ret;
00654 }
00655
00656 if (references_lenp)
00657 {
00658 ret = nc_inq_attlen(ncid, varid, CF_REFERENCES, references_lenp);
00659 if (ret == NC_ENOTATT)
00660 *references_lenp = 0;
00661 else if (ret)
00662 return ret;
00663 }
00664
00665 if (references)
00666 {
00667 ret = nc_get_att_text(ncid, varid, CF_REFERENCES, references);
00668 if (ret == NC_ENOTATT)
00669 strcpy(references, "");
00670 else if (ret)
00671 return ret;
00672 }
00673
00674 return NC_NOERR;
00675 }