00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00099 #define BUFR_MAIN
00100
00101 #include <stdlib.h>
00102 #include <math.h>
00103 #include <stdio.h>
00104 #include <string.h>
00105 #include <assert.h>
00106 #include <time.h>
00107 #include "desc.h"
00108 #include "bufr.h"
00109 #include "bitio.h"
00110 #include "rlenc.h"
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 #define SUBCENTER 255
00124 #define GENCENTER 255
00125 #define VMTAB 11
00126 #define VLTAB 4
00127
00128
00129
00130
00131
00132 #define MAXREPCOUNT 300
00133 #define MAX_ADDFIELDS 50
00134
00135
00136
00137
00138 static long year_, mon_, day_, hour_, min_;
00139 static int af_[MAX_ADDFIELDS];
00140 static int naf_ = 0;
00141 static int datah_ = -1;
00142 static bufrval_t* vals_ = NULL;
00143
00144
00145
00146
00147
00148 static int bufr_val_to_datasect (varfl val, int ind);
00149 static int bufr_val_from_datasect (varfl *val, int ind);
00150 static int get_lens (char* buf, long len, int* secl);
00151
00152
00153
00154
00155
00156
00163 void bufr_clean (void)
00164
00165
00166 {
00167 free_descs();
00168 }
00169
00170
00224 int bufr_create_msg (dd* descs, int ndescs, varfl* vals, void **datasec,
00225 void **ddsec, size_t *datasecl, size_t *ddescl)
00226
00227
00228 {
00229 bufrval_t* valarray = NULL;
00230 int ok, desch;
00231 bufr_t msg;
00232
00233 memset (&msg, 0, sizeof (bufr_t));
00234
00235 year_ = mon_ = day_ = hour_ = min_ = 0;
00236
00237
00238
00239 desch = bufr_open_descsec_w ();
00240
00241 ok = (desch >= 0);
00242
00243 if (ok)
00244 ok = (bufr_open_datasect_w () >= 0);
00245
00246
00247
00248 if (ok)
00249 bufr_out_descsec (descs, ndescs, desch);
00250
00251
00252
00253 if (ok) {
00254 valarray = bufr_open_val_array ();
00255 ok = (valarray != (bufrval_t*) NULL);
00256 }
00257
00258 if (ok) {
00259 valarray->vals = vals;
00260 valarray->vali = 0;
00261 }
00262
00263
00264
00265 if (ok) {
00266 ok = bufr_parse_in (descs, 0, ndescs - 1, bufr_val_from_global, 0);
00267 valarray->vals = (varfl*) NULL;
00268 bufr_close_val_array ();
00269 }
00270
00271
00272
00273 bufr_close_descsec_w (&msg, desch);
00274
00275 *ddsec = msg.sec[3];
00276 *ddescl = (size_t) msg.secl[3];
00277
00278 bufr_close_datasect_w (&msg);
00279
00280 *datasec = msg.sec[4];
00281 *datasecl = (size_t) msg.secl[4];
00282
00283 return ok;
00284 }
00285
00325 int bufr_encode_sections34 (dd* descs, int ndescs, varfl* vals, bufr_t* msg)
00326
00327
00328 {
00329 char *datasec = NULL;
00330 char *ddsec = NULL;
00331 size_t datasecl = 0;
00332 size_t ddescl = 0;
00333 int ret;
00334
00335 if (msg == (bufr_t*) NULL) {
00336 fprintf (stderr, "Error writing data to BUFR message\n");
00337 return 0;
00338 }
00339
00340 ret = bufr_create_msg (descs, ndescs, vals, (void**) &datasec,
00341 (void**) &ddsec, &datasecl, &ddescl);
00342
00343 msg->sec[3] = ddsec;
00344 msg->sec[4] = datasec;
00345 msg->secl[3] = ddescl;
00346 msg->secl[4] = datasecl;
00347
00348 return ret;
00349 }
00350
00351
00369 int bufr_read_file (bufr_t* msg, char* file) {
00370
00371 FILE* fp;
00372 char* bm;
00373 int len;
00374
00375
00376
00377 fp = fopen (file, "rb");
00378 if (fp == NULL) {
00379 fprintf (stderr, "unable to open file '%s'\n", file);
00380 return 0;
00381 }
00382
00383
00384
00385 fseek (fp, 0L, SEEK_END);
00386 len = ftell (fp);
00387 fseek (fp, 0L, SEEK_SET);
00388
00389
00390
00391 bm = (char *) malloc ((size_t) len);
00392 if (bm == NULL) {
00393 fprintf (stderr,
00394 "unable to allocate %d bytes to hold BUFR-message !\n", len);
00395 fclose (fp);
00396 return 0;
00397 }
00398 if (fread (bm, 1, (size_t) len, fp) != (size_t) len) {
00399 fprintf (stderr, "Error reading BUFR message from file!\n");
00400 fclose (fp);
00401 free (bm);
00402 return 0;
00403 }
00404
00405 fclose (fp);
00406
00407
00408
00409 if (!bufr_get_sections (bm, len, msg)) {
00410 free (bm);
00411 return 0;
00412 }
00413
00414 free (bm);
00415 return 1;
00416 }
00417
00437 int bufr_get_sections (char* bm, int len, bufr_t* msg)
00438
00439 {
00440 int co, l;
00441 char* buf;
00442 char* b7777;
00443 int i;
00444
00445
00446
00447 buf = NULL;
00448 for (l = 0; l < len - 4 && buf == NULL; l ++) {
00449 if (*(bm + l) == 'B' &&
00450 *(bm + l + 1) == 'U' &&
00451 *(bm + l + 2) == 'F' &&
00452 *(bm + l + 3) == 'R') buf = bm + l;
00453 }
00454 if (buf == NULL) {
00455 fprintf (stderr, "'BUFR' not found in BUFR-message !\n");
00456 return 0;
00457 }
00458
00459
00460
00461 b7777 = NULL;
00462 for (l = 0; l < len - 3 && b7777 == NULL; l ++) {
00463 if (*(bm + l) == '7' &&
00464 *(bm + l + 1) == '7' &&
00465 *(bm + l + 2) == '7' &&
00466 *(bm + l + 3) == '7') b7777 = bm + l;
00467 }
00468 if (b7777 == NULL) {
00469 fprintf (stderr, "'7777' not found in BUFR-message !\n");
00470 return 0;
00471 }
00472
00473
00474
00475 if (!get_lens (buf, len, msg->secl)) {
00476 fprintf (stderr, "unable to read lengths of BUFR-sections !\n");
00477 return 0;
00478 }
00479
00480
00481
00482 co = 0;
00483 for (i = 0; i < 6; i ++) {
00484 msg->sec[i] = (char *) malloc ((size_t) msg->secl[i] + 1);
00485 if (msg->sec[i] == NULL) {
00486 fprintf (stderr,
00487 "unable to allocate %d bytes for section %d !\n",
00488 msg->secl[i], i);
00489 return 0;
00490 }
00491 memcpy (msg->sec[i], buf + co, (size_t) msg->secl[i]);
00492 co += msg->secl[i];
00493 }
00494 return co;
00495 }
00496
00497
00514 int bufr_out_descsec (dd *descp, int ndescs, int desch)
00515
00516 {
00517 unsigned long l;
00518 int i;
00519
00520
00521
00522 for (i = 0; i < ndescs; i ++) {
00523 l = (unsigned long) descp->f;
00524 if (!bitio_o_append (desch, l, 2)) return 0;
00525 l = (unsigned long) descp->x;
00526 if (!bitio_o_append (desch, l, 6)) return 0;
00527 l = (unsigned long) descp->y;
00528 if (!bitio_o_append (desch, l, 8)) return 0;
00529 descp ++;
00530 }
00531
00532 return 1;
00533 }
00534
00546 int bufr_open_descsec_w () {
00547
00548 size_t n;
00549 int desch;
00550
00551
00552
00553 desch = bitio_o_open ();
00554 if (desch == -1) {
00555 bitio_o_close (desch, &n);
00556 return -1;
00557 }
00558
00559
00560
00561 bitio_o_append (desch, 0L, 24);
00562
00563
00564 bitio_o_append (desch, 0L, 8);
00565 bitio_o_append (desch, 1L, 16);
00566 bitio_o_append (desch, 128L, 8);
00567 return desch;
00568 }
00569
00570
00584 void bufr_close_descsec_w(bufr_t* bufr, int desch) {
00585
00586 int n;
00587 size_t st;
00588
00589 if (desch == -1 || bufr == (bufr_t*) NULL) return;
00590
00591
00592
00593 n = (int) bitio_o_get_size (desch);
00594
00595
00596
00597 if (n % 2 != 0) bitio_o_append (desch, 0L, 8);
00598
00599
00600
00601 n = (int) bitio_o_get_size (desch);
00602 bitio_o_outp (desch, (long) n, 24, 0L);
00603
00604
00605
00606 bufr->sec[3] = (char *) bitio_o_close (desch, &st);
00607 bufr->secl[3] = (int) st;
00608 }
00609
00610
00611
00622 int setup_sec0125 (char* sec[], size_t secl[], sect_1_t s1)
00623
00624 {
00625 bufr_t msg;
00626 int i;
00627
00628 for (i = 0; i < 6; i++) {
00629 msg.secl[i] = (int) secl[i];
00630 msg.sec[i] = sec[i];
00631 }
00632
00633 if (!bufr_encode_sections0125 (&s1, &msg))
00634 return 0;
00635
00636 for (i = 0; i < 6; i++) {
00637 secl[i] = (size_t) msg.secl[i];
00638 sec[i] = msg.sec[i];
00639 }
00640
00641 return 1;
00642
00643 }
00644
00657 int save_sections (char** sec, size_t* secl, char* buffile)
00658
00659 {
00660 FILE *fp;
00661 int i;
00662
00663
00664
00665 fp = fopen (buffile, "wb");
00666 if (fp == NULL) {
00667 fprintf (stderr, "Could not open file %s!\n", buffile);
00668 return 0;
00669 }
00670
00671
00672
00673 for (i = 0; i < 6; i ++) {
00674 if (fwrite (sec[i], 1, secl[i], fp) != secl[i]) {
00675 fclose (fp);
00676 fprintf (stderr,
00677 "An error occoured writing '%s'. File is invalid !\n",
00678 buffile);
00679 return 0;
00680 }
00681 }
00682
00683
00684
00685 fclose (fp);
00686 return 1;
00687 }
00688
00689
00690
00691
00735 int bufr_parse_new (dd *descs, int start, int end,
00736 int (*inputfkt) (varfl *val, int ind),
00737 int (*outputfkt) (varfl val, int ind),
00738 int callback_all_descs) {
00739
00740 int i, j, nrep, nd;
00741 int ind;
00742 varfl d;
00743 dd descr;
00744 static int level = 0;
00745 char* tmp;
00746 int operator_qual;
00747
00748
00749
00750
00751
00752 level ++;
00753
00754
00755
00756 for (ind = start; ind <= end; ind++) {
00757
00758
00759
00760 memcpy (&descr, descs + ind, sizeof (dd));
00761
00762 if (descr.f == 0) {
00763
00764
00765
00766 if ((i = get_index (ELDESC, &descr)) < 0) {
00767
00768
00769
00770 fprintf (stderr,
00771 "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n",
00772 descr.f, descr.x, descr.y);
00773 return 0;
00774 }
00775
00776
00777
00778 if (strcmp (des[i]->el->unit, "CCITT IA5") == 0) {
00779
00780
00781
00782
00783 if (callback_all_descs) {
00784 varfl v;
00785 des[_desc_special]->el->d.f = descr.f;
00786 des[_desc_special]->el->d.x = descr.x;
00787 des[_desc_special]->el->d.y = descr.y;
00788 des[_desc_special]->el->dw = des[i]->el->dw;
00789 tmp = des[_desc_special]->el->unit;
00790 des[_desc_special]->el->unit = des[i]->el->unit;
00791 if (!(*inputfkt) (&v, _desc_special)) return 0;
00792 if (!(*outputfkt) (0, _desc_special)) return 0;
00793 des[_desc_special]->el->unit = tmp;
00794 continue;
00795 }
00796
00797
00798
00799
00800
00801 for (j = 0; j < des[i]->el->dw / 8; j ++) {
00802
00803 if (!(*inputfkt) (&d, ccitt_special)) return 0;
00804 if (!(*outputfkt) (d, ccitt_special)) return 0;
00805 }
00806 continue;
00807 }
00808
00809
00810
00811
00812
00813 if (_bufr_edition < 3) {
00814 operator_qual = (des[i]->el->d.x == 31 &&
00815 des[i]->el->d.y == 21);
00816 } else {
00817 operator_qual = des[i]->el->d.x == 31;
00818 }
00819
00820 if (addfields != 0 && !operator_qual) {
00821
00822
00823
00824 des[add_f_special]->el->scale = 0;
00825 des[add_f_special]->el->refval = 0;
00826 des[add_f_special]->el->dw = addfields;
00827
00828
00829
00830 if (!(*inputfkt) (&d, add_f_special)) return 0;
00831 if (!(*outputfkt) (d, add_f_special)) return 0;
00832 }
00833
00834
00835
00836 if (!(*inputfkt) (&d, i)) return 0;
00837 if (!(*outputfkt) (d, i)) return 0;
00838
00839
00840
00841
00842 if (descr.x == 4) switch (descr.y)
00843 {
00844 case 1:
00845 if (_bufr_edition >= 4) {
00846 year_ = (long) d;
00847 }
00848 else {
00849 year_ = (long) ((int) (d-1) %100 + 1);
00850 }
00851 break;
00852 case 2: mon_ = (long) d; break;
00853 case 3: day_ = (long) d; break;
00854 case 4: hour_ = (long) d; break;
00855 case 5: min_ = (long) d; break;
00856 }
00857 continue;
00858 }
00859
00860 else if (descr.f == 3) {
00861
00862
00863
00864
00865
00866
00867 if ((i = get_index (SEQDESC, &descr)) < 0) {
00868
00869
00870
00871 fprintf (stderr,
00872 "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n",
00873 descr.f, descr.x, descr.y);
00874 return 0;
00875 }
00876
00877 if (!callback_all_descs) {
00878 if (!bufr_parse_new (des[i]->seq->del, 0,
00879 des[i]->seq->nel - 1,
00880 inputfkt, outputfkt, 0)) {
00881 return 0;
00882 }
00883 }
00884 else {
00885 if (!inputfkt (&d, i)) return 0;
00886 if (!outputfkt (0, i)) return 0;
00887 }
00888
00889 continue;
00890 }
00891
00892 else if (descr.f == 1) {
00893
00894
00895
00896 nd = descr.x;
00897 nrep = descr.y;
00898
00899
00900
00901 if (callback_all_descs) {
00902
00903 des[_desc_special]->el->d.f = descr.f;
00904 des[_desc_special]->el->d.x = descr.x;
00905 des[_desc_special]->el->d.y = descr.y;
00906 if (!(*outputfkt) (0, _desc_special)) return 0;
00907 }
00908
00909
00910
00911 if (nrep == 0) {
00912
00913
00914
00915 ind++;
00916 memcpy (&descr, descs + ind, sizeof (dd));
00917 if ((i = get_index (ELDESC, &descr)) < 0) {
00918 fprintf (stderr,
00919 "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n",
00920 descr.f, descr.x, descr.y);
00921 return 0;
00922 }
00923 if (!(*inputfkt) (&d, i)) return 0;
00924 nrep = (int) d;
00925 if (!(*outputfkt) (nrep, i)) return 0;
00926 }
00927
00928
00929
00930
00931 for (i = 0; i < nrep; i ++) {
00932 _replicating = i;
00933 if (!bufr_parse_new (descs, ind + 1, ind + nd, inputfkt,
00934 outputfkt, callback_all_descs))
00935 return 0;
00936 }
00937 _replicating = 0;
00938 ind += nd;
00939 continue;
00940 }
00941
00942 else if (descr.f == 2) {
00943
00944
00945
00946 if (callback_all_descs) {
00947
00948 des[_desc_special]->el->d.f = descr.f;
00949 des[_desc_special]->el->d.x = descr.x;
00950 des[_desc_special]->el->d.y = descr.y;
00951 if (!(*outputfkt) (0, _desc_special)) return 0;
00952 }
00953
00954 switch (descr.x) {
00955
00956
00957 case 1:
00958 if (descr.y == 0) {
00959 dw = 128;
00960 } else {
00961 dw = descr.y;
00962 }
00963 continue;
00964
00965
00966 case 2:
00967 if (descr.y == 0) {
00968 sc = 128;
00969 } else {
00970 sc = descr.y;
00971 }
00972 continue;
00973
00974
00975
00976
00977
00978 case 4:
00979 if (descr.y == 0) {
00980 naf_ --;
00981 if (naf_ < 0) {
00982 fprintf (stderr, "Illegal call of 2 04 000!\n");
00983 return 0;
00984 }
00985 addfields = af_[naf_];
00986 }
00987 else {
00988 af_[naf_] = addfields;
00989 naf_ ++;
00990 if (naf_ > MAX_ADDFIELDS) {
00991 fprintf (stderr,
00992 "Maximum number of associated fields reached!\n");
00993 return 0;
00994 }
00995 addfields += descr.y;
00996 }
00997 continue;
00998
00999
01000 default:
01001 fprintf (stderr,
01002 "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n",
01003 descr.f, descr.x, descr.y);
01004 return 0;
01005 }
01006 }
01007 else {
01008
01009
01010
01011 fprintf (stderr,
01012 "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n",
01013 descr.f, descr.x, descr.y);
01014 return 0;
01015 }
01016
01017 }
01018
01019
01020
01021 level --;
01022 return 1;
01023
01024 }
01025
01052 int bufr_parse (dd* descs, int start, int end, varfl *vals, unsigned *vali,
01053 int (*userfkt) (varfl val, int ind)) {
01054 int ok;
01055 bufrval_t* bufrvals;
01056
01057 bufrvals = bufr_open_val_array ();
01058
01059 if (bufrvals == (bufrval_t*) NULL) {
01060 return 0;
01061 }
01062
01063 bufrvals->vals = vals;
01064 bufrvals->vali = *vali;
01065 ok = bufr_parse_new (descs, start, end, bufr_val_from_global, userfkt,
01066 0);
01067 *vali = bufrvals->vali;
01068
01069 bufrvals->vals = (varfl*) NULL;
01070 bufr_close_val_array ();
01071 return ok;
01072 }
01073
01074
01075
01114 int bufr_parse_in (dd *descs, int start, int end,
01115 int (*inputfkt) (varfl *val, int ind),
01116 int callback_descs) {
01117
01118 return bufr_parse_new (descs, start, end, inputfkt,
01119 bufr_val_to_datasect, callback_descs);
01120 }
01121
01122
01160 int bufr_parse_out (dd *descs, int start, int end,
01161 int (*outputfkt) (varfl val, int ind),
01162 int callback_all_descs) {
01163
01164 return bufr_parse_new (descs, start, end, bufr_val_from_datasect,
01165 outputfkt, callback_all_descs);
01166 }
01167
01168
01169
01184 void bufr_sect_1_from_file (sect_1_t* s1, char* file)
01185 {
01186 FILE *fp;
01187 char buf[200];
01188 int val, count;
01189
01190
01191
01192 s1->mtab = 0;
01193 s1->subcent = SUBCENTER;
01194 s1->gencent = GENCENTER;
01195 s1->updsequ = 0;
01196 s1->opsec = 0;
01197 s1->dcat = 6;
01198 s1->idcatst = 0;
01199 s1->dcatst = 0;
01200 s1->vmtab = VMTAB;
01201 s1->vltab = VLTAB;
01202 s1->year = 999;
01203 s1->mon = 999;
01204 s1->day = 999;
01205 s1->hour = 999;
01206 s1->min = 999;
01207 s1->sec = 0;
01208
01209
01210
01211 fp = fopen (file, "r");
01212 if (fp == NULL) {
01213 return;
01214 }
01215
01216 count = 0;
01217 while (fgets (buf, 200, fp) != NULL) {
01218 if (sscanf (buf, "%d", &val) == 1) {
01219 switch (count) {
01220 case 0: s1->mtab = val; break;
01221 case 1: s1->subcent = val; break;
01222 case 2: s1->gencent = val; break;
01223 case 3: s1->updsequ = val; break;
01224 case 4: s1->opsec = val; break;
01225 case 5: s1->dcat = val; break;
01226 case 6: s1->dcatst = val; break;
01227 case 7: s1->vmtab = val; break;
01228 case 8: s1->vltab = val; break;
01229 case 9: s1->year = val; break;
01230 case 10: s1->mon = val; break;
01231 case 11: s1->day = val; break;
01232 case 12: s1->hour = val; break;
01233 case 13: s1->min = val; break;
01234
01235 case 14: s1->sec = val; break;
01236 case 15: s1->idcatst = val; break;
01237 }
01238 count ++;
01239 }
01240 }
01241 fclose (fp);
01242 }
01243
01244
01266 int bufr_encode_sections0125 (sect_1_t* s1, bufr_t* msg)
01267 {
01268
01269 char** sec = msg->sec;
01270 int* secl = msg->secl;
01271
01272 size_t st;
01273 int i, hand;
01274 long len;
01275 time_t t;
01276 struct tm t1;
01277
01278
01279
01280 hand = bitio_o_open ();
01281 if (hand == -1) return 0;
01282 if (_bufr_edition >= 4) {
01283 bitio_o_append (hand, 22L, 24);
01284 }
01285 else {
01286 bitio_o_append (hand, 18L, 24);
01287 }
01288 bitio_o_append (hand, s1->mtab, 8);
01289 if (_bufr_edition >= 4) {
01290 bitio_o_append (hand, s1->gencent, 16);
01291
01292 bitio_o_append (hand, s1->subcent, 16);
01293
01294 }
01295 else {
01296 bitio_o_append (hand, s1->subcent, 8);
01297 bitio_o_append (hand, s1->gencent, 8);
01298
01299 }
01300 bitio_o_append (hand, s1->updsequ, 8);
01301 bitio_o_append (hand, s1->opsec, 8);
01302 bitio_o_append (hand, s1->dcat, 8);
01303 if (_bufr_edition >= 4)
01304 bitio_o_append (hand, s1->idcatst, 8);
01305
01306 bitio_o_append (hand, s1->dcatst, 8);
01307 bitio_o_append (hand, s1->vmtab, 8);
01308 bitio_o_append (hand, s1->vltab, 8);
01309
01310
01311
01312 if (s1->year == 999) {
01313 time (&t);
01314 memcpy (&t1, localtime (&t), sizeof (struct tm));
01315 if (_bufr_edition >= 4) {
01316 bitio_o_append (hand, (long) t1.tm_year + 1900, 16);
01317 }
01318 else {
01319 t1.tm_year = (t1.tm_year - 1) % 100 + 1;
01320 bitio_o_append (hand, (long) t1.tm_year, 8);
01321 }
01322 bitio_o_append (hand, (long) t1.tm_mon + 1, 8);
01323 bitio_o_append (hand, (long) t1.tm_mday, 8);
01324 bitio_o_append (hand, (long) t1.tm_hour, 8);
01325 bitio_o_append (hand, (long) t1.tm_min, 8);
01326 if (_bufr_edition >= 4)
01327 bitio_o_append (hand, (long) t1.tm_sec, 8);
01328 }
01329 else {
01330 if (_bufr_edition >= 4) {
01331 bitio_o_append (hand, s1->year, 16);
01332 }
01333 else {
01334 s1->year = (s1->year - 1) % 100 + 1;
01335 bitio_o_append (hand, s1->year, 8);
01336 }
01337 bitio_o_append (hand, s1->mon, 8);
01338 bitio_o_append (hand, s1->day, 8);
01339 bitio_o_append (hand, s1->hour, 8);
01340 bitio_o_append (hand, s1->min, 8);
01341 if (_bufr_edition >= 4)
01342 bitio_o_append (hand, s1->sec, 8);
01343 }
01344 if (_bufr_edition < 4)
01345 bitio_o_append (hand, 0L, 8);
01346 sec[1] = (char *) bitio_o_close (hand, &st);
01347 secl[1] = (int) st;
01348
01349
01350
01351 sec[2] = NULL;
01352 secl[2] = 0;
01353
01354
01355
01356 hand = bitio_o_open ();
01357 for (i = 0; i < 4; i ++) bitio_o_append (hand, (long) '7', 8);
01358 sec[5] = (char *) bitio_o_close (hand, &st);
01359 secl[5] = (int) st;
01360
01361
01362
01363 secl[0] = 8;
01364 len = 0L;
01365 for (i = 0; i < 6; i ++) len += (long) secl[i];
01366
01367
01368
01369
01370 hand = bitio_o_open ();
01371 if (hand == -1) return 0;
01372 bitio_o_append (hand, (unsigned long) 'B', 8);
01373 bitio_o_append (hand, (unsigned long) 'U', 8);
01374 bitio_o_append (hand, (unsigned long) 'F', 8);
01375 bitio_o_append (hand, (unsigned long) 'R', 8);
01376 bitio_o_append (hand, len, 24);
01377 bitio_o_append (hand, (long) _bufr_edition, 8);
01378 sec[0] = (char *) bitio_o_close (hand, &st);
01379 secl[0] = (int) st;
01380 return 1;
01381 }
01382
01396 int bufr_write_file (bufr_t* msg, char* file)
01397 {
01398
01399 char** sec = msg->sec;
01400 int* secl = msg->secl;
01401 FILE *fp;
01402 int i;
01403
01404
01405
01406 fp = fopen (file, "wb");
01407 if (fp == NULL) {
01408 fprintf (stderr, "Could not open file %s!\n", file);
01409 return 0;
01410 }
01411
01412
01413
01414 for (i = 0; i < 6; i ++) {
01415 if (fwrite (sec[i], 1, (size_t) secl[i], fp) != (size_t) secl[i]) {
01416 fclose (fp);
01417 fprintf (stderr,
01418 "An error occoured during writing '%s'. File is invalid !\n",
01419 file);
01420 return 0;
01421
01422 }
01423 }
01424
01425
01426
01427 fclose (fp);
01428 return 1;
01429 }
01430
01431
01432
01445 void bufr_free_data (bufr_t* msg) {
01446
01447 int i;
01448
01449 if (msg == (bufr_t*) NULL) return;
01450
01451 for (i = 0; i <= 5; i++) {
01452 if (msg->sec[i] != NULL)
01453 free (msg->sec[i]);
01454 }
01455 memset (msg, 0, sizeof (bufr_t));
01456 }
01457
01458
01459
01460
01473 int bufr_check_fxy(dd *d, int ff, int xx, int yy) {
01474
01475 if (d == (dd*) NULL) return -1;
01476 return (d->f == ff) && (d->x == xx) && (d->y == yy);
01477 }
01478
01479
01480
01481
01495 int bufr_decode_sections01 (sect_1_t* s1, bufr_t* msg)
01496
01497 {
01498 int h, edition;
01499 unsigned long l;
01500
01501
01502 h = bitio_i_open (msg->sec[0], (size_t) msg->secl[0]);
01503 if (h == -1) return 0;
01504
01505 bitio_i_input (h, &l, 32);
01506 bitio_i_input (h, &l, 24);
01507 bitio_i_input (h, &l, 8); edition = l;
01508 bitio_i_close (h);
01509
01510
01511
01512 h = bitio_i_open (msg->sec[1], (size_t) msg->secl[1]);
01513 if (h == -1) return 0;
01514
01515 bitio_i_input (h, &l, 24);
01516
01517 bitio_i_input (h, &l, 8); s1->mtab = l;
01518 if (edition >= 4) {
01519 bitio_i_input (h, &l, 16); s1->gencent = l;
01520 bitio_i_input (h, &l, 16); s1->subcent = l;
01521 }
01522 else {
01523 bitio_i_input (h, &l, 8); s1->subcent = l;
01524 bitio_i_input (h, &l, 8); s1->gencent = l;
01525 }
01526 bitio_i_input (h, &l, 8); s1->updsequ = l;
01527 bitio_i_input (h, &l, 8); s1->opsec = l;
01528 bitio_i_input (h, &l, 8); s1->dcat = l;
01529 if (edition >= 4)
01530 bitio_i_input (h, &l, 8); s1->idcatst = l;
01531
01532 bitio_i_input (h, &l, 8); s1->dcatst = l;
01533 bitio_i_input (h, &l, 8); s1->vmtab = l;
01534
01535 bitio_i_input (h, &l, 8); s1->vltab = l;
01536
01537 if (edition >= 4) {
01538 bitio_i_input (h, &l, 16); s1->year = l;
01539 } else {
01540 bitio_i_input (h, &l, 8); s1->year = l;
01541 }
01542 bitio_i_input (h, &l, 8); s1->mon = l;
01543 bitio_i_input (h, &l, 8); s1->day = l;
01544 bitio_i_input (h, &l, 8); s1->hour = l;
01545 bitio_i_input (h, &l, 8); s1->min = l;
01546 if (edition >= 4)
01547 bitio_i_input (h, &l, 8); s1->sec = l;
01548 bitio_i_close (h);
01549
01550
01551
01552 _bufr_edition = edition;
01553
01554 return 1;
01555 }
01556
01557
01569 int bufr_sect_1_to_file (sect_1_t* s1, char* file) {
01570
01571 FILE* fp;
01572
01573 fp = fopen (file, "w");
01574 if (fp == NULL) {
01575 fprintf (stderr, "unable to open output file for section 1 !\n");
01576 return 0;
01577 }
01578
01579 fprintf (fp, "%5d master table used \n", s1->mtab);
01580 fprintf (fp, "%5d originating subcenter \n", s1->subcent);
01581 fprintf (fp, "%5d generating center \n", s1->gencent);
01582 fprintf (fp, "%5d original BUFR message \n", s1->updsequ);
01583 fprintf (fp, "%5d no optional section \n", s1->opsec);
01584 fprintf (fp, "%5d message type \n", s1->dcat);
01585 fprintf (fp, "%5d local message subtype \n", s1->dcatst);
01586 fprintf (fp, "%5d version number of master table used\n", s1->vmtab);
01587 fprintf (fp, "%5d version number of local table used \n", s1->vltab);
01588 fprintf (fp, "%5d year \n", s1->year);
01589 fprintf (fp, "%5d month \n", s1->mon);
01590 fprintf (fp, "%5d day \n", s1->day);
01591 fprintf (fp, "%5d hour \n", s1->hour);
01592 fprintf (fp, "%5d minute \n", s1->min);
01593
01594 if (_bufr_edition >= 4) {
01595 fprintf (fp, "%5d second \n", s1->sec);
01596 fprintf (fp, "%5d international message subtype \n",
01597 s1->idcatst);
01598 }
01599
01600 fclose (fp);
01601
01602 return 1;
01603 }
01604
01605
01645 int bufr_read_msg (void* datasec, void* ddsec, size_t datasecl, size_t ddescl,
01646 dd** descr, int* ndescs, varfl** vals, size_t* nvals)
01647
01648
01649 {
01650 int ok = 0, desch;
01651 dd *d;
01652 bufr_t msg;
01653 bufrval_t* bufrvals;
01654
01655 memset (&msg, 0, sizeof (bufr_t));
01656
01657 msg.sec[3] = ddsec;
01658 msg.secl[3] = (int) ddescl;
01659 msg.sec[4] = datasec;
01660 msg.secl[4] = (int) datasecl;
01661
01662
01663
01664 desch = bufr_open_descsec_r (&msg);
01665 if (desch < 0)
01666 return 0;
01667
01668 if (bufr_open_datasect_r (&msg) < 0) {
01669 bufr_close_descsec_r (desch);
01670 return 0;
01671 }
01672
01673
01674
01675 *ndescs = bufr_get_ndescs (&msg);
01676
01677
01678
01679 ok = bufr_in_descsec (descr, *ndescs, desch);
01680
01681
01682
01683 *vals = NULL;
01684 *nvals = 0;
01685 d = *descr;
01686
01687 bufrvals = bufr_open_val_array ();
01688
01689 if (bufrvals == (bufrval_t*) NULL) {
01690 ok = 0;
01691 }
01692
01693 if (ok) {
01694 ok = bufr_parse_out (d, 0, *ndescs - 1, bufr_val_to_global, 0);
01695 if (!ok)
01696 fprintf (stderr, "Error reading data from data-section !\n");
01697
01698 *vals = bufrvals->vals;
01699 *nvals = (size_t) bufrvals->nvals;
01700 bufrvals->vals = (varfl*) NULL;
01701 bufr_close_val_array ();
01702 }
01703
01704
01705
01706 bufr_close_descsec_r (desch);
01707 bufr_close_datasect_r ();
01708
01709 return ok;
01710 }
01711
01712
01728 int bufr_in_descsec (dd** descs, int ndescs, int desch) {
01729
01730 int err, i;
01731 unsigned long l = 0;
01732 dd* d;
01733
01734 if (desch < 0) {
01735 fprintf (stderr, "Descriptor handle not available! \n");
01736 return 0;
01737 }
01738
01739
01740 d = *descs = (dd *) malloc (ndescs * sizeof (dd));
01741 if (*descs == (dd*) NULL) {
01742 fprintf (stderr, "Unable to allocate memory for data descriptors !\n");
01743 return 0;
01744 }
01745
01746 for (i = 0; i < ndescs; i ++) {
01747 err = 0;
01748 err = err || !bitio_i_input (desch, &l, 2);
01749 d->f = (unsigned char) l;
01750 if (!err) err = err || !bitio_i_input (desch, &l, 6);
01751 d->x = (unsigned char) l;
01752 if (!err) err = err || !bitio_i_input (desch, &l, 8);
01753 d->y = (unsigned char) l;
01754 if (err) {
01755 fprintf (stderr,
01756 "Number of bits for descriptor-section exceeded !\n");
01757 free (*descs);
01758 *descs = (dd*) NULL;
01759 return 0;
01760 }
01761 d ++;
01762 }
01763 return 1;
01764 }
01765
01780 int bufr_open_descsec_r (bufr_t* msg) {
01781
01782 unsigned long l;
01783 int i, desch;
01784
01785
01786
01787 desch = bitio_i_open (msg->sec[3], msg->secl[3]);
01788
01789 if (desch == -1) {
01790 bitio_i_close (desch);
01791 return -1;
01792 }
01793
01794
01795
01796 for (i = 0; i < 56; i ++) bitio_i_input (desch, &l, 1);
01797
01798 return desch;
01799 }
01800
01801
01802
01814 void bufr_close_descsec_r (int desch) {
01815
01816 if (desch == -1) return;
01817 bitio_i_close (desch);
01818 }
01819
01820
01836 int val_to_array (varfl** vals, varfl v, size_t* nvals)
01837
01838 {
01839 static unsigned int nv;
01840 static unsigned int memsize;
01841 varfl *d;
01842
01843
01844
01845 if (*vals == NULL) {
01846 *vals = (varfl *) malloc (MEMBLOCK * sizeof (varfl));
01847 if (*vals == NULL) return 0;
01848 memset (*vals, 0, MEMBLOCK * sizeof (varfl));
01849 nv = 0;
01850 memsize = MEMBLOCK;
01851 }
01852
01853
01854
01855 if (memsize == nv) {
01856 *vals = (varfl *) realloc (*vals, (memsize + MEMBLOCK) * sizeof (varfl));
01857 if (*vals == NULL) return 0;
01858 memset ((char *) (*vals + memsize), 0, MEMBLOCK * sizeof (varfl));
01859 memsize += MEMBLOCK;
01860 if (memsize - 1 > (~(unsigned int) 0) / sizeof (varfl)) {
01861 fprintf (stderr, "VAL_TO_ARRAY failed in file %s, line %d\n", __FILE__, __LINE__);
01862 fprintf (stderr, "Try to define varfl as float in file desc.h \n");
01863 return 0;
01864 }
01865 }
01866
01867
01868
01869 d = *vals;
01870 *(d + nv) = v;
01871 nv ++;
01872 *nvals = nv;
01873 return 1;
01874 }
01875
01876
01894 int bufr_val_to_array (varfl** vals, varfl v, int* nv)
01895 {
01896
01897
01898 if (*vals == (varfl*) NULL) {
01899 *vals = (varfl *) malloc (MEMBLOCK * sizeof (varfl));
01900 if (*vals == (varfl*) NULL) {
01901 fprintf (stderr, "Could not allocate memory for value array!\n");
01902 return 0;
01903 }
01904 memset (*vals, 0, MEMBLOCK * sizeof (varfl));
01905 *nv = 0;
01906 }
01907
01908
01909
01910 if (*nv != 0 && *nv % MEMBLOCK == 0) {
01911 *vals = (varfl*) realloc (*vals, (*nv + MEMBLOCK) * sizeof (varfl));
01912 if (*vals == (varfl*) NULL) {
01913 fprintf (stderr, "Could not allocate memory for value array!\n");
01914 return 0;
01915 }
01916 memset ((varfl*) (*vals + *nv), 0, MEMBLOCK * sizeof (varfl));
01917 }
01918
01919
01920
01921
01922 (*vals)[*nv] = v;
01923 (*nv)++;
01924 return 1;
01925 }
01926
01927
01943 int bufr_desc_to_array (dd* descs, dd d, int* ndescs)
01944 {
01945
01946 if (*ndescs >= MAX_DESCS) {
01947 fprintf (stderr, "Maximum number of descriptors exceeded!\n");
01948 return 0;
01949 }
01950
01951
01952
01953
01954 descs[(*ndescs)++] = d;
01955 return 1;
01956 }
01957
01958
01959
01974 int bufr_get_ndescs (bufr_t* msg) {
01975
01976 if (msg == (bufr_t*) NULL) {
01977 fprintf (stderr, "Error in bufr_get_ndescs!\n");
01978 return -1;
01979 }
01980 return (((msg->secl[3] - 7)* 8) / 16);
01981 }
01982
01983
02000 void bufr_get_date_time (long *year, long *mon, long *day, long *hour,
02001 long *min)
02002
02003
02004 {
02005 *year = year_;
02006 *mon = mon_;
02007 *day = day_;
02008 *hour = hour_;
02009 *min = min_;
02010 }
02011
02012
02013
02014
02015
02016
02034 static int bufr_val_to_datasect (varfl val, int ind)
02035
02036
02037 {
02038 unsigned long l;
02039 int ret, wi, scale, ccitt, no_change = 0;
02040
02041 assert (datah_ >= 0);
02042
02043 ret = 1;
02044
02045
02046
02047 if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02048
02049
02050
02051
02052 if (_bufr_edition < 3) {
02053
02054 no_change = (des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31);
02055 }
02056 else {
02057 ccitt = (strcmp (des[ind]->el->unit, "CCITT IA5") == 0 ||
02058 ind == ccitt_special);
02059 no_change = ((des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31) ||
02060 ccitt || desc_is_codetable(ind) || desc_is_flagtable(ind) ||
02061 ind == add_f_special);
02062 }
02063
02064 if (no_change) {
02065 wi = des[ind]->el->dw;
02066 scale = des[ind]->el->scale;
02067 }
02068 else {
02069 wi = des[ind]->el->dw + dw - 128;
02070 scale = des[ind]->el->scale + sc - 128;
02071 }
02072
02073
02074
02075 if (val == MISSVAL) {
02076 l = 0xffffffff;
02077 if (bitio_o_append (datah_, l, wi) == -1) ret = 0;
02078 }
02079
02080
02081
02082 else {
02083 l = (unsigned long) (val * pow (10.0, (varfl) scale)
02084 - des[ind]->el->refval + 0.5);
02085
02086
02087 if (bitio_o_append (datah_, l, wi) == -1) ret = 0;
02088
02089
02090
02091 if (l >> wi != 0) {
02092 fprintf (stderr,
02093 "WARNING: Tried to code the value %ld to %d bits (Datadesc.=%2d%3d%4d) !\n",
02094 l, wi, des[ind]->el->d.f, des[ind]->el->d.x,
02095 des[ind]->el->d.y);
02096 fprintf (stderr, " Decoding will fail !\n");
02097 }
02098 }
02099
02100 return ret;
02101 }
02102
02103
02116 int bufr_open_datasect_w() {
02117 size_t n;
02118
02119 if (datah_ >= 0) {
02120 fprintf (stderr, "Global data handle not available.\n");
02121 return -1;
02122 }
02123
02124
02125
02126 datah_ = bitio_o_open ();
02127 if (datah_ == -1) {
02128 bitio_o_close (datah_, &n);
02129 return -1;
02130 }
02131
02132
02133
02134 bitio_o_append (datah_, 0L, 24);
02135
02136 bitio_o_append (datah_, 0L, 8);
02137 return datah_;
02138 }
02139
02140
02154 int bufr_open_datasect_r (bufr_t* msg) {
02155
02156 unsigned long l;
02157 int i;
02158
02159 if (datah_ >= 0) {
02160 fprintf (stderr, "Global data handle not available.\n");
02161 return -1;
02162 }
02163
02164
02165
02166 datah_ = bitio_i_open (msg->sec[4], (size_t) msg->secl[4]);
02167
02168 if (datah_ == -1) {
02169 bitio_i_close (datah_);
02170 return -1;
02171 }
02172
02173
02174
02175 for (i = 0; i < 32; i ++) bitio_i_input (datah_, &l, 1);
02176
02177 return datah_;
02178 }
02179
02192
02193
02194 void bufr_close_datasect_w(bufr_t* msg) {
02195
02196 int n;
02197 size_t st;
02198
02199 if (datah_ == -1 || msg == (bufr_t*) NULL) return;
02200
02201
02202
02203 n = (int) bitio_o_get_size (datah_);
02204
02205
02206
02207 if (n % 2 != 0) bitio_o_append (datah_, 0L, 8);
02208
02209
02210
02211 n = (int) bitio_o_get_size (datah_);
02212 bitio_o_outp (datah_, (long) n, 24, 0L);
02213
02214
02215
02216 msg->sec[4] = (char *) bitio_o_close (datah_, &st);
02217 msg->secl[4] = (int) st;
02218 datah_ = -1;
02219 }
02220
02221
02230 void bufr_close_datasect_r () {
02231
02232 if (datah_ == -1) return;
02233 bitio_i_close (datah_);
02234 datah_ = -1;
02235 }
02236
02252 int bufr_val_from_global (varfl *val, int ind) {
02253
02254 assert (val != (varfl*) NULL);
02255 assert (vals_ != NULL);
02256 assert (vals_->vals != NULL);
02257
02258
02259
02260 if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02261
02262 *val = *(vals_->vals + vals_->vali++);
02263 return 1;
02264
02265 }
02266
02267
02268
02284 int bufr_val_to_global (varfl val, int ind) {
02285
02286 assert (vals_ != (bufrval_t*) NULL);
02287
02288
02289
02290 if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02291
02292 return bufr_val_to_array (&(vals_->vals), val, &(vals_->nvals));
02293 }
02294
02295
02296
02310 bufrval_t* bufr_open_val_array () {
02311
02312
02313 if (vals_ != (bufrval_t*) NULL) {
02314 fprintf (stderr, "Value array not empty!\n");
02315 return (bufrval_t*) NULL;
02316 }
02317 vals_ = malloc (sizeof (bufrval_t));
02318
02319 if (vals_ == (bufrval_t*) NULL) {
02320 fprintf (stderr, "Error allocating memory for Value array!\n");
02321 return (bufrval_t*) NULL;
02322 }
02323 memset (vals_, 0, sizeof (bufrval_t));
02324 return vals_;
02325 }
02326
02337 void bufr_close_val_array () {
02338
02339 if (vals_ == (bufrval_t*) NULL) return;
02340
02341 if (vals_->vals != (varfl*) NULL) {
02342 free (vals_->vals);
02343 vals_->vals = (varfl*) NULL;
02344 }
02345 free (vals_);
02346 vals_ = (bufrval_t*) NULL;
02347 }
02348
02349
02368 static int bufr_val_from_datasect (varfl *val, int ind)
02369
02370
02371 {
02372 int data_width;
02373 int scale, no_change = 0, ccitt;
02374 unsigned long l, mv;
02375
02376 assert (datah_ >= 0);
02377
02378
02379
02380 if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02381
02382
02383
02384
02385 if (_bufr_edition < 3) {
02386
02387 no_change = (des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31);
02388 }
02389 else {
02390 ccitt = (strcmp (des[ind]->el->unit, "CCITT IA5") == 0 ||
02391 ind == ccitt_special);
02392 no_change = ((des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31) ||
02393 ccitt || desc_is_codetable(ind) || desc_is_flagtable(ind) ||
02394 ind == add_f_special);
02395 }
02396
02397 if (no_change) {
02398 data_width = des[ind]->el->dw;
02399 scale = des[ind]->el->scale;
02400 }
02401 else {
02402 data_width = des[ind]->el->dw + dw - 128;
02403 scale = des[ind]->el->scale + sc - 128;
02404 }
02405
02406 if (!bitio_i_input (datah_, &l, data_width)) {
02407 fprintf (stderr, "Error reading data from bitstrem !\n");
02408 return 0;
02409 }
02410
02411
02412
02413
02414
02415 mv = (1 << data_width) - 1;
02416
02417 if (l == mv && des[ind]->el->d.x != 31 &&
02418 !(des[ind]->el->d.x == 30 && des[ind]->el->d.y <= 4 && _opera_mode) &&
02419 !(des[ind]->el->d.x == 13 && des[ind]->el->d.y == 11 && _opera_mode) &&
02420 !(des[ind]->el->d.x == 21 && des[ind]->el->d.y == 14 && _opera_mode)) {
02421 *val = MISSVAL;
02422 }
02423 else {
02424 *val = ((varfl) l + des[ind]->el->refval) /
02425 pow (10.0, (varfl) (scale));
02426 }
02427 return 1;
02428 }
02429
02430
02431
02432
02433
02434
02435
02436
02449 static int get_lens (char* buf, long len, int* secl)
02450
02451 {
02452 int h, co, i, totlen, lens0;
02453 unsigned long l;
02454 long sum;
02455
02456
02457
02458
02459 h = bitio_i_open (buf, 8);
02460 bitio_i_input (h, &l, 32);
02461 bitio_i_input (h, &l, 24);
02462 bitio_i_close (h);
02463 lens0 = l;
02464
02465 secl[0] = 8;
02466 co = 8;
02467 sum = 8;
02468
02469
02470
02471 h = bitio_i_open (buf + co, 20);
02472 if (h == -1) return 0;
02473 bitio_i_input (h, &l, 24);
02474 secl[1] = (int) l;
02475 co += secl[1];
02476 bitio_i_close (h);
02477 sum += l;
02478 if (sum > len) goto err;
02479
02480
02481
02482 secl[2] = 0;
02483
02484
02485
02486 h = bitio_i_open (buf + co, 20);
02487 if (h == -1) return 0;
02488 bitio_i_input (h, &l, 24);
02489 secl[3] = (int) l;
02490 co += secl[3];
02491 bitio_i_close (h);
02492 sum += l;
02493 if (sum > len) goto err;
02494
02495
02496
02497 h = bitio_i_open (buf + co, 20);
02498 if (h == -1) return 0;
02499 bitio_i_input (h, &l, 24);
02500 secl[4] = (int) l;
02501 co += secl[4];
02502 bitio_i_close (h);
02503 sum += l;
02504 if (sum > len) goto err;
02505
02506
02507
02508 secl[5] = 4;
02509 sum += 4;
02510 if (sum > len) goto err;
02511
02512
02513
02514
02515 totlen = 0;
02516 for (i = 0; i < 6; i ++) {
02517 #ifdef VERBOSE
02518 fprintf (stderr, "section %d length = %d\n", i, secl[i]);
02519 #endif
02520 totlen += secl[i];
02521 }
02522 if (totlen != lens0) {
02523 fprintf (stderr,
02524 "WARNING: Total length of message doesn't match with the lengths\n"
02525 "of the individual sections !\n");
02526 }
02527
02528 return 1;
02529
02530
02531
02532 err:
02533 fprintf (stderr, "Lengths of BUFR-sections > size of input-file !\n");
02534 return 0;
02535 }
02536
02537