static int warts_trace_lastditch_read(scamper_trace_t *trace, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_trace_hop_t *hops; uint16_t count; if(warts_params_read(buf, off, len, NULL, 0) != 0) goto err; if(extract_uint16(buf, off, len, &count, NULL) != 0) goto err; if(count != 0) { if(warts_trace_hops_read(&hops,state,table,buf,off,len,count) != 0) goto err; trace->lastditch = hops; } return 0; err: return -1; }
static int extract_dealias_prefixscan_xs(const uint8_t *buf, uint32_t *off, const uint32_t len, scamper_dealias_prefixscan_t *pfs, void *param) { scamper_addr_t **xs; uint16_t xc, i; if(extract_uint16(buf, off, len, &xc, NULL) != 0) return -1; if(scamper_dealias_prefixscan_xs_alloc(pfs, xc) != 0) return -1; xs = pfs->xs; for(i=0; i<xc; i++) { if(extract_addr(buf, off, len, &xs[i], param) != 0) return -1; } pfs->xs = xs; pfs->xc = xc; return 0; }
bool GET_LIST_SIZE(serial_context *ser_cont, uint32_t *size) { int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); if (type == EOF) { err("Error while reading list type"); return false; } if (type == 0xdc) { uint16_t tmp; if (!extract_uint16(ser_cont, &tmp)) { err("Error while reading 16-bit list size"); return false; } *size = tmp; return true; } if (type == 0xdd) { uint32_t tmp; if (!extract_uint32(ser_cont, &tmp)) { err("Error while reading 32-bit list size"); return false; } *size = tmp; return true; } if ((type & 0xf0) == 0x90) { *size = type & 0x0f; return true; } err("Serialized value is not a list"); return false; }
int scamper_file_warts_ping_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_ping_t **ping_out) { warts_state_t *state = scamper_file_getstate(sf); scamper_ping_t *ping = NULL; uint8_t *buf = NULL; uint32_t off = 0; uint16_t i; scamper_ping_reply_t *reply; uint16_t reply_count; warts_addrtable_t table; memset(&table, 0, sizeof(table)); if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *ping_out = NULL; return 0; } if((ping = scamper_ping_alloc()) == NULL) { goto err; } if(warts_ping_params_read(ping, state, &table, buf, &off, hdr->len) != 0) { goto err; } /* determine how many replies to read */ if(extract_uint16(buf, &off, hdr->len, &reply_count, NULL) != 0) { goto err; } /* allocate the ping_replies array */ if(scamper_ping_replies_alloc(ping, ping->ping_sent) != 0) { goto err; } /* if there are no replies, then we are done */ if(reply_count == 0) { goto done; } /* for each reply, read it and insert it into the ping structure */ for(i=0; i<reply_count; i++) { if((reply = scamper_ping_reply_alloc()) == NULL) { goto err; } if(warts_ping_reply_read(ping,reply,state,&table,buf,&off,hdr->len) != 0) { goto err; } if(scamper_ping_reply_append(ping, reply) != 0) { goto err; } } assert(off == hdr->len); done: warts_addrtable_clean(&table); *ping_out = ping; free(buf); return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(ping != NULL) scamper_ping_free(ping); return -1; }
static void nids_count_polygons_radials_16(struct nids_data_st *nd){ unsigned char *b = nd->data; struct nids_digital_radial_packet_st radial_packet; int i, j; int run_code, run_bins, total_bins; double theta1, theta2; /* double r1, r2, theta1p, theta2p; */ double r2, theta2p; /* r1, theta1p not used in this function */ double dtheta; int numpolygons = 0; /* * We will run through the radials twice. The first time is just to * count the number of polygons, and the second time to actually * fill in the polygons. In other words, we must compute the total * number of "run bins". */ /* * Go to the start of the "individual radials" */ b += NIDS_PACKET_RADIALS_START_RUNS; numpolygons = 0; for(i = 0; i < nd->radial_packet_header.numradials; ++i){ radial_packet.num_bytes = extract_uint16(b, 1); radial_packet.angle_start = extract_int16(b, 2); radial_packet.angle_delta = extract_uint16(b, 3); b += 6; radial_packet.angle_start_deg = (double)radial_packet.angle_start/10.0; radial_packet.angle_delta_deg = (double)radial_packet.angle_delta/10.0; /* theta1 and theta2 in degrees */ theta1 = radial_packet.angle_start_deg; theta2 = radial_packet.angle_start_deg + radial_packet.angle_delta_deg; total_bins = 0; for(j = 0; j < radial_packet.num_bytes; ++j){ run_code = b[0]; run_bins = 1; ++b; /* radius in km - alspo update "total_bins */ /* r1 = ((double)(total_bins * nd->radial_packet_header.scale))/1000.0; */ total_bins += run_bins; r2 = ((double)(total_bins * nd->radial_packet_header.scale))/1000.0; /* According to doc, 0 and 1 are not data values */ if(run_code < 2) continue; dtheta = DEG_PER_RAD/r2; if(radial_packet.angle_delta_deg < dtheta) dtheta = radial_packet.angle_delta_deg; /* theta1p = theta1; */ theta2p = theta1; while(theta2p < theta2){ theta2p += dtheta; if(theta2p > theta2) theta2p = theta2; ++numpolygons; /* theta1p = theta2p; */ } } } nd->polygon_map.numpolygons = numpolygons; }
void nids_decode_digital_radials_16_orig(struct nids_data_st *nd){ unsigned char *b = nd->data; unsigned char *bsave; /* used when counting the polygons */ struct dcnids_polygon_st *polygon; struct nids_digital_radial_packet_st radial_packet; int i, j; int run_code, run_bins, total_bins; double r1, r2, theta1, theta2; double sin_theta1, cos_theta1, sin_theta2, cos_theta2; int numpoints = 0; int numpolygons = 0; int run_level = 0; /* * We will run through the radials twice. The first time is just to * count the number of polygons, and the second time to actually * fill in the polygons. In other words, we must compute the total * number of "run bins". */ /* * Go to the start of the "individual radials" */ b += NIDS_PACKET_RADIALS_START_RUNS; bsave = b; for(i = 0; i < nd->radial_packet_header.numradials; ++i){ radial_packet.num_bytes = extract_uint16(b, 1); b += 6; b += radial_packet.num_bytes; numpolygons += radial_packet.num_bytes; } b = bsave; /* * Allocate space for all the polygons. */ nd->polygon_map.numpolygons = numpolygons; nd->polygon_map.polygons = malloc(sizeof(struct dcnids_polygon_st) * nd->polygon_map.numpolygons); if(nd->polygon_map.polygons == NULL) log_err(1, "Error from malloc()"); /* XXX fprintf(stdout, "numpolygons = %d\n", nd->polygon_map.numpolygons); */ /* * Go through the run bins again, this time to get the polygons. */ /* * Initialize the polygon pointer to the start of the polygon array, * and count them again to check. */ polygon = nd->polygon_map.polygons; numpolygons = 0; for(i = 0; i < nd->radial_packet_header.numradials; ++i){ radial_packet.num_bytes = extract_uint16(b, 1); radial_packet.angle_start = extract_int16(b, 2); radial_packet.angle_delta = extract_uint16(b, 3); b += 6; radial_packet.angle_start_deg = (double)radial_packet.angle_start/10.0; radial_packet.angle_delta_deg = (double)radial_packet.angle_delta/10.0; /* XXX fprintf(stdout, "%d %d %f %f\n", nd->radial_packet_header.numradials, radial_packet.num_bytes, radial_packet.angle_start_deg, radial_packet.angle_delta_deg); */ /* theta1 and theta2 in degrees */ theta1 = radial_packet.angle_start_deg; theta2 = radial_packet.angle_start_deg + radial_packet.angle_delta_deg; dcnids_sine_cosine(theta1, &sin_theta1, &cos_theta1); dcnids_sine_cosine(theta2, &sin_theta2, &cos_theta2); total_bins = 0; for(j = 0; j < radial_packet.num_bytes; ++j){ run_code = b[0]; run_bins = 1; ++b; numpoints += run_bins; /* radius in km - alspo update "total_bins */ r1 = ((double)(total_bins * nd->radial_packet_header.scale))/1000.0; total_bins += run_bins; r2 = ((double)(total_bins * nd->radial_packet_header.scale))/1000.0; /* XXX fprintf(stdout, "\t%f %f\n", r1, r2); */ /* According to doc, 0 and 1 are not data values */ if(run_code < 2) continue; /* * Translate the code to a "level". The level that corresponds to the * code depends on the product type (pdb_code). */ if(nd->nids_header.pdb_code == NIDS_PDB_CODE_NXQ){ run_level = nids_decode_bref_codetolevel(nd->nids_header.pdb_mode, run_code); }else if(nd->nids_header.pdb_code == NIDS_PDB_CODE_NXU){ run_level = nids_decode_rvel_codetolevel(run_code); }else{ log_errx(1, "Unsupported value of nd->nids_header.pdb_code."); } if(nd->polygon_map.flag_usefilter == 1){ if((run_level < nd->polygon_map.level_min) || (run_level > nd->polygon_map.level_max)){ continue; } } polygon->code = run_code; polygon->level = run_level; /* * The reference lat, lon are the site coordinates */ dcnids_define_polygon(nd->nids_header.lon, nd->nids_header.lat, r1, r2, sin_theta1, cos_theta1, sin_theta2, cos_theta2, polygon); /* XXX int k; for(k = 0; k < 4; ++k){ fprintf(stdout, "%.2f:%.2f,", polygon->lon[k], polygon->lat[k]); } fprintf(stdout, "%d\n", polygon->level); */ ++polygon; ++numpolygons; } /* XXX fprintf(stdout, "\ntotal_bins: %d\n", total_bins); fprintf(stdout, "\n"); */ } assert(numpolygons <= nd->polygon_map.numpolygons); nd->polygon_map.numpolygons = numpolygons; dcnids_polygonmap_bb(&nd->polygon_map); /* XXX fprintf(stdout, "\nnumpoints= %d, numpolygons = %d:%d\n", numpoints, numpolygons, nd->polygon_map.numpolygons); */ }
static int warts_trace_pmtud_read(scamper_trace_t *trace, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { uint16_t ifmtu = 0, pmtu = 0, outmtu = 0; uint8_t ver = 1, notec = 0; warts_param_reader_t handlers[] = { {&ifmtu, (wpr_t)extract_uint16, NULL}, {&pmtu, (wpr_t)extract_uint16, NULL}, {&outmtu, (wpr_t)extract_uint16, NULL}, {&ver, (wpr_t)extract_byte, NULL}, {¬ec, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); scamper_trace_pmtud_n_t *n = NULL; scamper_trace_hop_t *hops; uint16_t count; uint8_t u8; if(scamper_trace_pmtud_alloc(trace) != 0) goto err; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) goto err; trace->pmtud->ifmtu = ifmtu; trace->pmtud->pmtu = pmtu; trace->pmtud->outmtu = outmtu; trace->pmtud->ver = ver; trace->pmtud->notec = notec; /* the number of hop records that follow */ if(extract_uint16(buf, off, len, &count, NULL) != 0) goto err; if(count != 0) { if(warts_trace_hops_read(&hops,state,table,buf,off,len,count) != 0) goto err; trace->pmtud->hops = hops; } if(trace->pmtud->notec != 0) { if(scamper_trace_pmtud_n_alloc_c(trace->pmtud, trace->pmtud->notec) != 0) goto err; for(u8=0; u8<trace->pmtud->notec; u8++) { if((n = scamper_trace_pmtud_n_alloc()) == NULL) goto err; if(warts_trace_pmtud_n_read(trace->pmtud, n, buf, off, len) != 0) goto err; trace->pmtud->notes[u8] = n; n = NULL; } } return 0; err: if(n != NULL) scamper_trace_pmtud_n_free(n); return -1; }
/* * warts_trace_read * */ int scamper_file_warts_trace_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_trace_t **trace_out) { warts_state_t *state = scamper_file_getstate(sf); scamper_trace_t *trace = NULL; uint8_t *buf = NULL; uint32_t i, off = 0; scamper_trace_hop_t *hops = NULL; scamper_trace_hop_t *hop; uint16_t count; uint8_t max_ttl; uint8_t type; uint16_t len; uint16_t u16; warts_addrtable_t *table = NULL; if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *trace_out = NULL; return 0; } if((trace = scamper_trace_alloc()) == NULL) { goto err; } if((table = warts_addrtable_alloc_byid()) == NULL) goto err; /* read the trace's parameters */ if(warts_trace_params_read(trace, state, table, buf, &off, hdr->len) != 0) { goto err; } /* * the next two bytes tell us how many scamper_hops to read out of trace * if we did not get any responses, we are done. */ if(extract_uint16(buf, &off, hdr->len, &count, NULL) != 0) { goto err; } /* read all the hop records */ if(warts_trace_hops_read(&hops,state,table,buf,&off,hdr->len,count) != 0) goto err; /* work out the maximum ttl probed with that got a response */ max_ttl = 0; for(i=0, hop = hops; i < count; i++) { if(hop->hop_probe_ttl > max_ttl) max_ttl = hop->hop_probe_ttl; hop = hop->hop_next; } /* * if the hop_count field was provided in the file, then * make sure it makes sense based on the hop data we've just scanned */ if(trace->hop_count != 0) { if(trace->hop_count < max_ttl) goto err; if(trace->hop_count > 255) goto err; } else { trace->hop_count = max_ttl; } /* allocate enough hops to string the trace together */ if(scamper_trace_hops_alloc(trace, trace->hop_count) == -1) { goto err; } if(hops == NULL) { assert(count == 0); goto done; } /* * now loop through the hops array stored in this procedure * and assemble the responses into trace->hops. */ trace->hops[hops->hop_probe_ttl-1] = hop = hops; while(hop->hop_next != NULL) { if(hop->hop_probe_ttl != hop->hop_next->hop_probe_ttl) { i = hop->hop_next->hop_probe_ttl-1; trace->hops[i] = hop->hop_next; hop->hop_next = NULL; hop = trace->hops[i]; } else hop = hop->hop_next; } hops = NULL; for(;;) { if(extract_uint16(buf, &off, hdr->len, &u16, NULL) != 0) goto err; if(u16 == WARTS_TRACE_ATTR_EOF) break; type = WARTS_TRACE_ATTR_HDR_TYPE(u16); len = WARTS_TRACE_ATTR_HDR_LEN(u16); if(type == WARTS_TRACE_ATTR_PMTUD) { i = off; if(warts_trace_pmtud_read(trace,state,table,buf,&i,hdr->len) != 0) goto err; } else if(type == WARTS_TRACE_ATTR_LASTDITCH) { i = off; if(warts_trace_lastditch_read(trace, state, table, buf, &i, hdr->len) != 0) goto err; } else if(type == WARTS_TRACE_ATTR_DTREE) { i = off; if(warts_trace_dtree_read(trace,state,table,buf,&i,hdr->len) != 0) goto err; } off += len; } done: warts_addrtable_free(table); free(buf); *trace_out = trace; return 0; err: if(table != NULL) warts_addrtable_free(table); if(hops != NULL) free(hops); if(buf != NULL) free(buf); if(trace != NULL) scamper_trace_free(trace); return -1; }
int scamper_file_warts_tbit_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_tbit_t **tbit_out) { scamper_tbit_t *tbit = NULL; warts_addrtable_t table; warts_state_t *state = scamper_file_getstate(sf); uint8_t *buf = NULL; uint16_t junk16; uint32_t junk32; uint32_t off = 0; uint32_t i; memset(&table, 0, sizeof(table)); /* Read in the header */ if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *tbit_out = NULL; return 0; } /* Allocate space for a tbit object */ if((tbit = scamper_tbit_alloc()) == NULL) { goto err; } /* Read in the tbit data from the warts file */ if(warts_tbit_params_read(tbit, &table, state, buf, &off, hdr->len) != 0) { goto err; } switch(tbit->type) { case SCAMPER_TBIT_TYPE_PMTUD: if((tbit->data = scamper_tbit_pmtud_alloc()) == NULL) goto err; break; case SCAMPER_TBIT_TYPE_NULL: if((tbit->data = scamper_tbit_null_alloc()) == NULL) goto err; break; } /* Determine how many tbit_pkts to read */ if(tbit->pktc > 0) { /* Allocate the tbit_pkts array */ if(scamper_tbit_pkts_alloc(tbit, tbit->pktc) != 0) goto err; /* For each tbit packet, read it and insert it into the tbit structure */ for(i=0; i<tbit->pktc; i++) { tbit->pkts[i] = warts_tbit_pkt_read(state, buf, &off, hdr->len); if(tbit->pkts[i] == NULL) goto err; } } for(;;) { if(extract_uint16(buf, &off, hdr->len, &junk16, NULL) != 0) goto err; if(junk16 == WARTS_TBIT_STRUCT_EOF) break; if(extract_uint32(buf, &off, hdr->len, &junk32, NULL) != 0) goto err; i = off; if(junk16 == WARTS_TBIT_STRUCT_TYPE) { switch(tbit->type) { case SCAMPER_TBIT_TYPE_PMTUD: if(warts_tbit_pmtud_read(tbit, &table, buf, &i, hdr->len) != 0) goto err; break; case SCAMPER_TBIT_TYPE_NULL: if(warts_tbit_null_read(tbit, buf, &i, hdr->len) != 0) goto err; break; } } else if(junk16 == WARTS_TBIT_STRUCT_APP) { if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP) { if(warts_tbit_app_http_read(tbit, buf, &i, hdr->len) != 0) goto err; } } off += junk32; } assert(off == hdr->len); warts_addrtable_clean(&table); *tbit_out = tbit; free(buf); return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(tbit != NULL) scamper_tbit_free(tbit); return -1; }
/* * decoding functions */ static void nids_decode_data(struct nids_data_st *nd){ unsigned char *b = nd->data; int packet_code; int divider; int status, bzerror; /* * The "divider" should be -1 for legacy products, but for the new * products that are bz2 compressed the first two bytes are "BZ". * In the first case we continue, but if the divider is not -1 * we assume it is a new product and try to send it to libbz2. */ divider = (int)extract_int16(b, 1); if(divider != -1){ status = dcnids_bunz(&nd->data, &nd->data_size, &bzerror); if(status == 1) log_errx(1, "Error from libbz2: %d", bzerror); else if(status == -1) log_err(1, "Error from libbz2."); /* repoint b */ b = nd->data; } divider = (int)extract_int16(b, 1); if(divider != -1) log_errx(1, "Corrupt file."); nd->psb.blockid = extract_uint16(b, 2); /* should be 1 */ nd->psb.blocklength = extract_uint32(b, 3); nd->psb.numlayers = extract_uint16(b, 5); b += 10; /* XXX fprintf(stdout, "\npsb: %d %u %d\n", nd->psb.blockid, nd->psb.blocklength, nd->psb.numlayers); */ nd->psb.psb_layer_blocklength = extract_uint32(b, 2); b += 6; /* XXX fprintf(stdout, "psb_layer_blocklength = %u\n", nd->psb.psb_layer_blocklength); */ /* start of display packets */ packet_code = extract_uint16(b, 1); /* * XXX * To find out the product and packet codes: * fprintf(stdout, "%d %d %d\n", * nd->nids_header.m_code, * nd->nids_header.pdb_code, * packet_code); * exit(0); */ if((packet_code != NIDS_PACKET_RADIALS_AF1F) && (packet_code != NIDS_PACKET_DIGITAL_RADIALS_16)) log_errx(1, "Unsupported packet code: %d", packet_code); nd->radial_packet_header.packet_code = packet_code; nd->radial_packet_header.first_bin_index = extract_int16(b, 2); nd->radial_packet_header.numbins = extract_uint16(b, 3); nd->radial_packet_header.center_i = extract_int16(b, 4); nd->radial_packet_header.center_j = extract_int16(b, 5); nd->radial_packet_header.scale = extract_uint16(b, 6); nd->radial_packet_header.numradials = extract_uint16(b, 7); b += 14; /* XXX fprintf(stdout, "\n%x %d %d %d %d %d %d\n", nd->radial_packet_header.packet_code, nd->radial_packet_header.first_bin_index, nd->radial_packet_header.numbins, nd->radial_packet_header.center_i, nd->radial_packet_header.center_j, nd->radial_packet_header.scale, nd->radial_packet_header.numradials); */ /* * Here we extract the polygon data. Only the polygons that have * level values within the specified limits will be included if * the option to use the filter is set. The filter is used only * for bref. */ nd->polygon_map.flag_usefilter = 0; /* default*/ if(g.opt_filter == 1){ nd->polygon_map.flag_usefilter = 1; /* * The limits depend on the product code. */ if((nd->nids_header.pdb_code == NIDS_PDB_CODE_NXR) || (nd->nids_header.pdb_code == NIDS_PDB_CODE_N0Z) || (nd->nids_header.pdb_code == NIDS_PDB_CODE_NXQ)){ nd->polygon_map.level_min = NIDS_BREF_LEVEL_MIN_VAL; nd->polygon_map.level_max = NIDS_BREF_LEVEL_MAX_VAL; } else if((nd->nids_header.pdb_code == NIDS_PDB_CODE_NXV) || (nd->nids_header.pdb_code == NIDS_PDB_CODE_NXU)){ nd->polygon_map.level_min = NIDS_RVEL_LEVEL_MIN_VAL; nd->polygon_map.level_max = NIDS_RVEL_LEVEL_MAX_VAL; } else if((nd->nids_header.pdb_code == NIDS_PDB_CODE_NXP) || (nd->nids_header.pdb_code == NIDS_PDB_CODE_NTP)){ nd->polygon_map.level_min = NIDS_NXP_LEVEL_MIN_VAL; nd->polygon_map.level_max = NIDS_NXP_LEVEL_MAX_VAL; } else if(nd->nids_header.pdb_code == NIDS_PDB_CODE_NXS){ nd->polygon_map.level_min = NIDS_SRVEL_LEVEL_MIN_VAL; nd->polygon_map.level_max = NIDS_SRVEL_LEVEL_MAX_VAL; } else log_errx(1, "Unsupported value [%d] of nd->nids_header.pdb_code.", nd->nids_header.pdb_code); /* * If the user specified min and max the use them. */ if(g.level_min != g.level_max){ nd->polygon_map.level_min = g.level_min; nd->polygon_map.level_max = g.level_max; } } /* * The layout of the "run bins" in the radials depends on the packet type. */ if(packet_code == NIDS_PACKET_RADIALS_AF1F) nids_decode_radials_af1f(nd); else if(packet_code == NIDS_PACKET_DIGITAL_RADIALS_16) nids_decode_digital_radials_16(nd); else { /* Already caught above */ log_errx(1, "Unsupported packet code: %d", packet_code); } }
int dcnids_decode_header(struct nids_header_st *nheader){ /* * This function returns the same error codes as nids_verify_header(), * namely 0, or a positive error code indicative of the failure. */ int status; unsigned char *b; int n; struct tm tm; /* Go past the wmo header and to the start of the awips line */ b = nheader->buffer; b += CTRLHDR_WMO_SIZE; for(n = 0; n < WMO_AWIPS_SIZE; ++n) nheader->awipsid[n] = tolower(*b++); nheader->awipsid[WMO_AWIPS_SIZE] = '\0'; /* Go past the the wmo and awips headers */ b = nheader->buffer; b += WMOAWIPS_HEADER_SIZE; nheader->m_code = extract_uint16(b, 1); nheader->m_days = extract_uint16(b, 2) - 1; nheader->m_seconds = extract_uint32(b, 3); /* msglength is the file length without headers or trailers */ nheader->m_msglength = extract_uint32(b, 5); nheader->m_source = extract_uint16(b, 7); nheader->m_destination = extract_uint16(b, 8); nheader->m_numblocks = extract_uint16(b, 9); nheader->pdb_divider = extract_int16(b, 10); nheader->pdb_lat = extract_int32(b, 11); nheader->pdb_lon = extract_int32(b, 13); nheader->pdb_height = extract_uint16(b, 15); nheader->pdb_code = extract_uint16(b, 16); /* same as m_code */ nheader->pdb_mode = extract_uint16(b, 17); nheader->pdb_version = extract_uint8(b, 54); nheader->pdb_symbol_block_offset = extract_uint32(b, 55) * 2; nheader->pdb_graphic_block_offset = extract_uint32(b, 57) * 2; nheader->pdb_tabular_block_offset = extract_uint32(b, 59) * 2; /* derived */ nheader->lat = ((double)nheader->pdb_lat)/1000.0; nheader->lon = ((double)nheader->pdb_lon)/1000.0; nheader->unixseconds = nheader->m_days * 24 * 3600 + nheader->m_seconds; (void)gmtime_r(&nheader->unixseconds, &tm); nheader->year = tm.tm_year + 1900; nheader->month = tm.tm_mon + 1; nheader->day = tm.tm_mday; nheader->hour = tm.tm_hour; nheader->min = tm.tm_min; nheader->sec = tm.tm_sec; status = nids_verify_pdb_header(nheader); return(status); }
bool UNPACK_VALUE(serial_context *ser_cont, as_val **value) { int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); if (type == EOF) { err("Error while reading value type"); return false; } switch (type) { case 0xc0: // nil return unpack_nil(ser_cont, value); case 0xc3: // boolean true return unpack_boolean(ser_cont, true, value); case 0xc2: // boolean false return unpack_boolean(ser_cont, false, value); case 0xca: { // float float tmp; return extract_float(ser_cont, &tmp) && unpack_double(ser_cont, tmp, value); } case 0xcb: { // double double tmp; return extract_double(ser_cont, &tmp) && unpack_double(ser_cont, tmp, value); } case 0xd0: { // signed 8 bit integer int8_t tmp; return extract_uint8(ser_cont, (uint8_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xcc: { // unsigned 8 bit integer uint8_t tmp; return extract_uint8(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value); } case 0xd1: { // signed 16 bit integer int16_t tmp; return extract_uint16(ser_cont, (uint16_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xcd: { // unsigned 16 bit integer uint16_t tmp; return extract_uint16(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value); } case 0xd2: { // signed 32 bit integer int32_t tmp; return extract_uint32(ser_cont, (uint32_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xce: { // unsigned 32 bit integer uint32_t tmp; return extract_uint32(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value); } case 0xd3: { // signed 64 bit integer int64_t tmp; return extract_uint64(ser_cont, (uint64_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xcf: { // unsigned 64 bit integer uint64_t tmp; return extract_uint64(ser_cont, &tmp) && unpack_integer(ser_cont, (int64_t)tmp, value); } case 0xc4: case 0xd9: { // raw bytes with 8 bit header uint8_t size; return extract_uint8(ser_cont, &size) && unpack_blob(ser_cont, size, value); } case 0xc5: case 0xda: { // raw bytes with 16 bit header uint16_t size; return extract_uint16(ser_cont, &size) && unpack_blob(ser_cont, size, value); } case 0xc6: case 0xdb: { // raw bytes with 32 bit header uint32_t size; return extract_uint32(ser_cont, &size) && unpack_blob(ser_cont, size, value); } case 0xdc: { // list with 16 bit header uint16_t size; return extract_uint16(ser_cont, &size) && unpack_list(ser_cont, size, value); } case 0xdd: { // list with 32 bit header uint32_t size; return extract_uint32(ser_cont, &size) && unpack_list(ser_cont, size, value); } case 0xde: { // map with 16 bit header uint16_t size; return extract_uint16(ser_cont, &size) && unpack_map(ser_cont, size, value); } case 0xdf: { // map with 32 bit header uint32_t size; return extract_uint32(ser_cont, &size) && unpack_map(ser_cont, size, value); } default: if ((type & 0xe0) == 0xa0) { // raw bytes with 8 bit combined header return unpack_blob(ser_cont, type & 0x1f, value); } if ((type & 0xf0) == 0x80) { // map with 8 bit combined header return unpack_map(ser_cont, type & 0x0f, value); } if ((type & 0xf0) == 0x90) { // list with 8 bit combined header return unpack_list(ser_cont, type & 0x0f, value); } if (type < 0x80) { // 8 bit combined unsigned integer return unpack_integer(ser_cont, type, value); } if (type >= 0xe0) { // 8 bit combined signed integer return unpack_integer(ser_cont, type - 0xe0 - 32, value); } return false; } }