tws::geoarray::geoarray_t tws::geoarray::read_array_metadata(const rapidjson::Value& jmetadata) { if(!jmetadata.IsObject()) throw tws::parse_error() << tws::error_description("error parsing array metadata."); geoarray_t ameta; const rapidjson::Value& jarray_name = jmetadata["name"]; if(!jarray_name.IsString() || jarray_name.IsNull()) throw tws::parse_error() << tws::error_description("error in array entry name in metadata."); ameta.name = jarray_name.GetString(); if(ameta.name.empty()) throw tws::parse_error() << tws::error_description("array name can not be empty in metadata."); const rapidjson::Value& jarray_dsc = jmetadata["description"]; if(jarray_dsc.IsString() && !jarray_dsc.IsNull()) ameta.description = jarray_dsc.GetString(); const rapidjson::Value& jarray_detail = jmetadata["detail"]; if(jarray_detail.IsString() && !jarray_detail.IsNull()) ameta.detail = jarray_detail.GetString(); const rapidjson::Value& jarray_dimensions = jmetadata["dimensions"]; ameta.dimensions = read_dimensions(jarray_dimensions); const rapidjson::Value& jarray_attributes = jmetadata["attributes"]; ameta.attributes = read_array_attributes(jarray_attributes); const rapidjson::Value& jarray_geo_extent = jmetadata["geo_extent"]; ameta.geo_extent = read_geo_extent(jarray_geo_extent); return ameta; }
static GwyContainer* sly_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta = NULL; gchar *buffer = NULL; GError *err = NULL; GHashTable *hash = NULL; gchar *p, *line, *value; guint expecting_data = 0; SensolyticsChannel *channels = NULL; Dimensions dimensions; gint ndata = 0, i; if (!g_file_get_contents(filename, &buffer, NULL, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } p = buffer; line = gwy_str_next_line(&p); g_strstrip(line); if (!gwy_strequal(line, MAGIC)) { err_FILE_TYPE(error, "Sensolytics"); goto fail; } hash = g_hash_table_new(g_str_hash, g_str_equal); for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { if (!line[0]) continue; if (expecting_data) { expecting_data--; /* The columns are comma-separated and numbers use decimal points. * Do not tempt the number parsing functions more than necessary * and fix commas to tab characters. */ g_strdelimit(line, ",", '\t'); /* Ignore X, Y and Z, each is two values */ for (i = 0; i < 6; i++) g_ascii_strtod(line, &line); for (i = 0; i < ndata; i++) channels[i].data[expecting_data] = channels[i].q * g_ascii_strtod(line, &line); } else { g_strstrip(line); if (line[0] != '#') { g_warning("Comment line does not start with #."); continue; } do { line++; } while (g_ascii_isspace(*line)); if (g_str_has_prefix(line, "X [")) { if (channels) { g_warning("Multiple data headers!?"); continue; } if (!read_dimensions(hash, &ndata, &dimensions, error) || !(channels = create_fields(hash, line, ndata, &dimensions))) goto fail; expecting_data = dimensions.xres * dimensions.yres; continue; } value = strchr(line, ':'); if (!value) { if (!gwy_strequal(line, "ArrayScan")) g_warning("Non-parameter-like line %s", line); continue; } *value = '\0'; g_strchomp(line); do { value++; } while (g_ascii_isspace(*value)); if (gwy_strequal(line, "Warning")) continue; gwy_debug("<%s>=<%s>", line, value); g_hash_table_insert(hash, line, value); } } if (!channels) { err_NO_DATA(error); goto fail; } container = gwy_container_new(); for (i = 0; i < ndata; i++) { GQuark key = gwy_app_get_data_key_for_id(i); gwy_data_field_invert(channels[i].dfield, FALSE, TRUE, FALSE); gwy_container_set_object(container, key, channels[i].dfield); gwy_app_channel_check_nonsquare(container, i); if (channels[i].name) { gchar *s = g_strconcat(g_quark_to_string(key), "/title", NULL); gwy_container_set_string_by_name(container, s, g_strdup(channels[i].name)); g_free(s); } else gwy_app_channel_title_fall_back(container, i); gwy_file_channel_import_log_add(container, i, NULL, filename); } meta = get_meta(hash); clone_meta(container, meta, ndata); g_object_unref(meta); fail: g_free(buffer); if (hash) g_hash_table_destroy(hash); if (channels) { for (i = 0; i < ndata; i++) g_object_unref(channels[i].dfield); g_free(channels); } return container; }
/* Opens an HDF file and reads all its SDS metadata, returning an SDSInfo * structure containing this metadata. Returns NULL on error. */ SDSInfo *open_h4_sds(const char *path) { int i, status; int sd_id = SDstart(path, DFACC_READ); CHECK_HDF_ERROR(path, sd_id); // get dataset and global att counts int32 n_datasets, n_global_atts; status = SDfileinfo(sd_id, &n_datasets, &n_global_atts); CHECK_HDF_ERROR(path, status); SDSInfo *sds = NEW0(SDSInfo); sds->path = xstrdup(path); sds->type = SDS_HDF4_FILE; sds->id = sd_id; // read global attributes sds->gatts = read_attributes(path, sd_id, n_global_atts); // read variables ('datasets') for (i = 0; i < n_datasets; i++) { int sds_id = SDselect(sd_id, i); CHECK_HDF_ERROR(path, sds_id); char buf[_H4_MAX_SDS_NAME + 1]; memset(buf, 0, sizeof(buf)); int32 rank, dim_sizes[H4_MAX_VAR_DIMS], type, natts; status = SDgetinfo(sds_id, buf, &rank, dim_sizes, &type, &natts); CHECK_HDF_ERROR(path, status); SDSVarInfo *var = NEW0(SDSVarInfo); var->name = xstrdup(buf); var->type = h4_to_sdstype(type); var->iscoord = SDiscoordvar(sds_id); var->ndims = rank; var->dims = read_dimensions(sds, sds_id, rank, dim_sizes); var->atts = read_attributes(path, sds_id, natts); var->id = i; // actually the sds_index comp_coder_t comp_type; comp_info c_info; status = SDgetcompinfo(sds_id, &comp_type, &c_info); CHECK_HDF_ERROR(path, status); switch (comp_type) { case COMP_CODE_NONE: var->compress = 0; break; case COMP_CODE_DEFLATE: var->compress = c_info.deflate.level; break; default: // any other compression method is 'worth' 1 imo *trollface* // better than claiming 0 to the user var->compress = 1; break; } var->sds = sds; var->next = sds->vars; sds->vars = var; status = SDendaccess(sds_id); CHECK_HDF_ERROR(path, status); } sds->vars = (SDSVarInfo *)list_reverse((List *)sds->vars); sds->dims = (SDSDimInfo *)list_reverse((List *)sds->dims); sds->funcs = &h4_funcs; return sds; }
int main(void) { buffer_t buf = buf_new(1); screen_t fake, real; int rows, cols; read_dimensions(&rows, &cols); fake_screen_init(&fake, rows, cols); real_screen_init(&buf, &real, rows, cols); prepare_events(); int x = 0, y = 0; char text[cols*rows]; bool marks[cols*rows]; memset(text, ' ', sizeof text); memset(marks, 0, sizeof marks); await: { event_t e = await_event(); switch (e.type) { case E_SIG: goto quit; break; case E_KEY: switch (e.key) { case '\b': if (x > 0) x -= 1; break; case '\n': x = 0; y += 1; break; case '~': marks[x + y*cols] = !marks[x + y*cols]; x++; break; default: text[x + y*cols] = e.key; x++; break; } break; case E_UP: y -= 1; break; case E_DOWN: y += 1; break; case E_LEFT: x -= 1; break; case E_RIGHT: x += 1; break; default: break; } int cx, cy; for (cx = 0; cx < cols; cx++) { for (cy = 0; cy < rows; cy++) { fake.cells[cx + cy*cols].codes[0] = text[cx + cy*cols]; } } int j; for (j = 0; j < cols*rows; j++) { if (marks[j]) { fake.cells[j].style.back.rgb = 0xff0000; } } fake.cursor.x = x; fake.cursor.y = y; fake.cursor.visible = true; screen_flush(&buf, &fake, &real); write(STDOUT_FILENO, buf.data, buf.used); buf.used = 0; fake_screen_reset(&fake, 25, 80); goto await; } quit: cleanup_events(); real_screen_cleanup(&buf, &real); write(STDOUT_FILENO, buf.data, buf.used); screen_free(&fake); screen_free(&real); buf_free(&buf); return 0; }