/* prints a full description of a varid, expanding sequence contents*/ void gabufr_print_varid (gabufr_varid *varid, gaint indent) { gabufr_varid * seq_varid; gabufr_varinf * varinf; gaint i; static gaint delrep = 0; for (i = 0; i < indent; i++) { printf(" "); } printf("%d %.2d %.3d ", varid->f, varid->x, varid->y); if (delrep) { printf("(replication count)\n"); delrep = 0; return; } switch (varid->f) { case 0: varinf = gabufr_get_varinf(varid->x, varid->y); printf("(%s) %s\n", (varinf->datatype == GABUFR_STR_TYPE) ? "text" : "numeric", varinf->description); break; case 1: printf("(replicate next %d", varid->x); if (varid->y == 0) { printf(", not including replication count)\n"); delrep = 1; } else { printf(", %d times)\n", varid->y); } break; case 2: printf("(operator)\n"); break; case 3: printf("(sequence)\n"); for (seq_varid = gabufr_get_seq(varid->x, varid->y); seq_varid; seq_varid = seq_varid->next) { gabufr_print_varid(seq_varid, indent + 2); } break; } }
gaint gabufr_read_tbl_b(const char * tbl_b_path) { FILE *tbl_b_file; char line[GABUFR_MAX_LINE_LEN]; gaint f, x, y, scale, offset, width; gabufr_varinf * entry; /* allocate memory and initialize to zero */ tbl_b = (gabufr_varinf *) calloc(GABUFR_TBL_SIZE, sizeof(gabufr_varinf)); if (tbl_b == NULL) { printf("Memory error loading table B\n"); return GABUFR_ERR; } /* open file */ tbl_b_file = fopen(tbl_b_path, "r"); if (tbl_b_file == NULL) { printf ("Error opening table B file (%s): %s\n", tbl_b_path, strerror(errno)); return GABUFR_ERR; } /* read entries into table array */ while ( fgets(line, GABUFR_MAX_LINE_LEN, tbl_b_file) ) { if (GABUFR_TBL_DEBUG) printf("line: %s", line); if (line[0] == '#' || strlen(line) < 2) { continue; } sscanf(line, "%d;%d;%d;%d;%d;%d", &f, &x, &y, &scale, &offset, &width); entry = gabufr_get_varinf(x, y); entry->scale = scale; entry->offset = offset; entry->width = width; entry->datatype = gabufr_entry_is_text(line); entry->description = gabufr_copy_desc(line); if (GABUFR_TBL_DEBUG) printf("(%d,%d,%d): (val+%d)*%d - %d bits of %s data\n", f, x, y, offset, scale, width, (entry->datatype == GABUFR_STR_TYPE) ? "text" : "numeric"); } fclose(tbl_b_file); return GABUFR_OK; }
gaint gabufr_parse_f0(gabufr_parseinf * inf, gaint x, gaint y) { gabufr_val * val; gabufr_val delrepval; gabufr_varinf * varinf; gaint numdesc, numreps; if (x == 0 && y == 0) { if (GABUFR_DEBUG) printf("null descriptor\n"); return GABUFR_OK; } else { varinf = gabufr_get_varinf(x, y); if (GABUFR_DEBUG) printf("\t%s\n", varinf->description); } if (inf->delrep) { if ( x != 31 ) { printf("error: expected F=0 Y=31 X=... for delayed replication\n"); return GABUFR_ERR; } if (gabufr_parseval(inf, x, y, &delrepval) == GABUFR_ERR) { return GABUFR_ERR; } numreps = delrepval.val; numdesc = inf->delrep; inf->delrep = 0; if (gabufr_replicate(inf, numdesc, numreps) == GABUFR_ERR) { return GABUFR_ERR; } } else { val = (gabufr_val *) malloc(sizeof(gabufr_val)); if (val == NULL) { printf("Memory allocation failed during parsing\n"); return GABUFR_ERR; } if (gabufr_parseval(inf, x, y, val) == GABUFR_ERR) { return GABUFR_ERR; } gabufr_addval(inf, val); } return GABUFR_OK; }
gaint gabufr_parseval(gabufr_parseinf *inf, gaint x, gaint y, gabufr_val * val) { gabufr_varinf * varinf; long packedval; varinf = gabufr_get_varinf(x, y); if (varinf->width == 0) { printf("error: no entry for descriptor (0, %d, %d)\n", x, y); return GABUFR_ERR; } if (varinf->datatype == GABUFR_STR_TYPE) { val->sval = gabufr_readbits2str(inf->datapos, inf->databits, varinf->width); val->val = DBL_MIN; } else { packedval = (double) gabufr_readbits2num(inf->datapos, inf->databits, varinf->width); if (packedval == gabufr_all_ones(varinf->width)) { val->undef = GABUFR_UNDEF; if (GABUFR_DEBUG) printf("missing data flag set\n"); } else { val->undef = GABUFR_DEF; } val->val = gabufr_exp10(packedval + varinf->offset, varinf->scale); if (GABUFR_DEBUG) printf("unpacking: ( %d + %d ) / 10^%d -> %g\n", (gaint) packedval, varinf->offset, varinf->scale, val->val); val->sval = NULL; } val->x = x; val->y = y; val->z = inf->z; gabufr_seekbits(inf, varinf->width); return GABUFR_OK; }
void gabufr_print_tbl_b() { gaint x, y; gabufr_varinf * entry; for (x = 0; x < (1<<6); x++) { for (y = 0; y < (1<<8); y++) { entry = gabufr_get_varinf(x, y); if (entry->width > 0) { printf("(%d,%d,%d): ", 0, x, y); if (entry->datatype == GABUFR_STR_TYPE) { printf("text: "); } else { printf("numeric ((%d bits + %d) * 10^%d): ", entry->width, entry->offset, entry->scale); } printf(entry->description); printf("\n"); } } } }
/* builds a list of varid's from the message header */ gabufr_varid * gabufr_extract_msg_desc(gabufr_msg * msg, gaint parse_data) { unsigned char * pos, * start, * end; gabufr_varid * head, * current, * next; gabufr_varinf * varinf; if (msg == NULL) { return NULL; } if (GABUFR_DEBUG || parse_data == GABUFR_NO_PARSE_DATA) { printf("\n\n\n>>> start of message\n"); } head = current = NULL; start = msg->section3 + 7; end = msg->section4; for (pos = start; pos < end; pos += 2) { next = (gabufr_varid *) malloc(sizeof(gabufr_varid)); if (next == NULL) { printf("Memory allocation failed during parsing\n"); gabufr_free_varids(head); return NULL; } next->f = gagbb(pos, 0, 2); next->x = gagbb(pos, 2, 6); next->y = gagbb(pos, 8, 8); if (next->f == 0 && next->x == 0 && next->y == 0) { free(next); continue; } next->next = NULL; if (!gabufr_valid_varid(next->f, next->x, next->y)) { printf("error: corrupt message (contains invalid FXY %d-%.2d-%.3d)\n", next->f, next->x, next->y); free(next); gabufr_free_varids(head); return NULL; } if (next->f == 0) { varinf = gabufr_get_varinf(next->x, next->y); if (varinf->width == 0) { printf("error: no table information for FXY %d-%.2d-%.3d\n", next->f, next->x, next->y); free(next); gabufr_free_varids(head); return NULL; } } if (GABUFR_DEBUG || parse_data == GABUFR_NO_PARSE_DATA) gabufr_print_varid(next, 0); if (head) { current->next = next; } else { head = next; } current = next; } if (GABUFR_DEBUG || parse_data == GABUFR_NO_PARSE_DATA) { printf("\n<<< end of message"); } return head; }
gabufr_val * gabufr_update_ncep_tbl_b(gabufr_dset * file, gabufr_msg * msg, gabufr_val * pos) { gabufr_varinf new_entry; gaint new_x, new_y; gaint y_expected, z_expected; char description[65]; gabufr_varinf * entry_to_replace; new_x = new_y = 0; description[64] = '\0'; z_expected = pos->z; for (y_expected = 11; y_expected <= 20; y_expected++) { if (!pos) { printf("Ran out of data in middle of entry!\n"); return pos; } if (pos->y != y_expected) { printf("Expected y = %d; got y = %d\n", y_expected, pos->y); return pos; } if (pos->z != z_expected) { printf("Expected z = %d; got z = %d\n", z_expected, pos->z); return pos; } if (!pos->sval) { printf("Expected string data!\n"); return pos; } switch (pos->y) { case 11: new_x = strtol(pos->sval, NULL, 10); break; case 12: new_y = strtol(pos->sval, NULL, 10); break; case 13: memcpy(description, pos->sval, 32); break; case 14: memcpy(description + 32, pos->sval, 32); break; case 15: if (strstr(pos->sval, "CCITT_IA5") || strstr(pos->sval, "CCITT IA5")) { new_entry.datatype = GABUFR_STR_TYPE; } else { new_entry.datatype = GABUFR_NUM_TYPE; } break; case 16: if (strchr(pos->sval, '-')) { new_entry.scale = -1; } else if (strchr(pos->sval, '+')) { new_entry.scale = 1; } else { printf("invalid scale sign string: %s\n", pos->sval); } break; case 17: new_entry.scale *= strtol(pos->sval, NULL, 10); break; case 18: if (strchr(pos->sval, '-')) { new_entry.offset = -1; } else if (strchr(pos->sval, '+')) { new_entry.offset = 1; } else { printf("invalid offset sign string: %s\n", pos->sval); } break; case 19: new_entry.offset *= strtol(pos->sval, NULL, 10); break; case 20: new_entry.width = strtol(pos->sval, NULL, 10); break; } pos = pos->next; } if (GABUFR_TBL_DEBUG) printf("updated entry: (%d,%d,%d): (val+%d)*%d - %d bits of %s data\n", 0, new_x, new_y, new_entry.offset, new_entry.scale, new_entry.width, (new_entry.datatype == GABUFR_STR_TYPE) ? "text" : "numeric"); new_entry.description = (char *) malloc(65); if (new_entry.description == NULL) { printf("Memory allocation failed during parsing\n"); return NULL; } strcpy(new_entry.description, description); if (GABUFR_TBL_DEBUG) printf("\tdescription: %s\n", new_entry.description); /* copy entry into table */ entry_to_replace = gabufr_get_varinf(new_x, new_y); memcpy(entry_to_replace, &new_entry, sizeof(gabufr_varinf)); return pos; }