static inline gdouble gwy_serialize_unpack_double(const guchar *buffer, gsize size, gsize *position) { gdouble value; gwy_debug("buf = %p, size = %" G_GSIZE_FORMAT ", pos = %" G_GSIZE_FORMAT, buffer, size, *position); g_assert(buffer); g_assert(position); g_return_val_if_fail(*position + sizeof(gdouble) <= size, 0.0); #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) memcpy(&value, buffer + *position, sizeof(gdouble)); #else gwy_memcpy_byte_swap(buffer + *position, (guint8*)&value, sizeof(gdouble), 1, sizeof(gdouble) - 1); #endif *position += sizeof(gdouble); gwy_debug("value = <%g>", value); return value; }
static gboolean read_aist_curve(const guchar **p, gsize *size, AistContext *context) { AistCurve curve; GwyGraphModel *gmodel; GwyGraphCurveModel *gcmodel; GwySIUnit *xunit, *yunit; gboolean ok = FALSE; guint len, viewlen, i; const guchar *data, *viewdata; const gdouble *xdata, *ydata; gdouble *xdatacal, *ydatacal; gdouble *must_free = NULL; gdouble qx, qy; GQuark quark; gwy_clear(&curve, 1); gwy_debug("reading common"); if (!read_aist_common(p, size, &curve.common)) goto fail; gwy_debug("reading curve"); if (!read_qt_int(p, size, &curve.res)) goto fail; if (!read_qt_byte_array(p, size, &len, &data)) goto fail; if (len != 2*curve.res*sizeof(gdouble)) goto fail; /* Again something called view data. Skip it. The units follow. */ if (!read_qt_byte_array(p, size, &viewlen, &viewdata)) goto fail; if (!read_qt_string(p, size, &curve.xunits) || !read_qt_string(p, size, &curve.yunits)) goto fail; xunit = extract_units(curve.xunits, &qx); yunit = extract_units(curve.yunits, &qy); /* The data are already stored as doubles in the correct order, so save * work if also the endianess matches. */ if (G_BYTE_ORDER == G_BIG_ENDIAN) { must_free = g_new(gdouble, 2*curve.res); xdata = must_free; ydata = xdata + curve.res; gwy_memcpy_byte_swap(data, (guchar*)must_free, 8, 2*curve.res, 7); } else if (G_BYTE_ORDER == G_LITTLE_ENDIAN) { xdata = (const gdouble *)data; ydata = xdata + curve.res; } xdatacal = g_new(gdouble, curve.res); ydatacal = g_new(gdouble, curve.res); for (i = 0; i < curve.res; i++) { xdatacal[i] = xdata[i]*qx; ydatacal[i] = ydata[i]*qy; } gcmodel = gwy_graph_curve_model_new(); gwy_graph_curve_model_set_data(gcmodel, xdatacal, ydatacal, curve.res); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "description", curve.common.description, NULL); g_free(must_free); g_free(xdatacal); g_free(ydatacal); gmodel = gwy_graph_model_new(); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); g_object_set(gmodel, "title", curve.common.name, "si-unit-x", xunit, "si-unit-y", yunit, NULL); g_object_unref(xunit); g_object_unref(yunit); quark = gwy_app_get_graph_key_for_id(context->graph_id+1); gwy_container_set_object(context->container, quark, gmodel); g_object_unref(gmodel); context->graph_id++; ok = TRUE; fail: free_aist_common(&curve.common); g_free(curve.xunits); g_free(curve.yunits); return ok; }
static GwyContainer* text_dump_import(gchar *buffer, gsize size, const gchar *filename, GError **error) { gchar *val, *key, *pos, *line, *title; GwyContainer *data; GwyDataField *dfield; gdouble xreal, yreal; gint xres, yres, id; GwySIUnit *uxy, *uz; const guchar *s; gdouble *d; gsize n; data = gwy_container_new(); pos = buffer; while ((line = gwy_str_next_line(&pos)) && *line) { val = strchr(line, '='); if (!val || *line != '/') { g_warning("Garbage key: %s", line); continue; } if ((gsize)(val - buffer) + 1 > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when value was expected.")); goto fail; } *val = '\0'; val++; if (!gwy_strequal(val, "[") || !pos || *pos != '[') { gwy_debug("<%s>=<%s>", line, val); if (*val) gwy_container_set_string_by_name(data, line, g_strdup(val)); else gwy_container_remove_by_name(data, line); continue; } g_assert(pos && *pos == '['); pos++; dfield = NULL; gwy_container_gis_object_by_name(data, line, &dfield); id = 0; sscanf(line, "/%d", &id); /* get datafield parameters from already read values, failing back * to values of original data field */ key = g_strconcat(line, "/xres", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) xres = atoi(s); else if (dfield) xres = gwy_data_field_get_xres(dfield); else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data field width.")); goto fail; } g_free(key); key = g_strconcat(line, "/yres", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) yres = atoi(s); else if (dfield) yres = gwy_data_field_get_yres(dfield); else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data field height.")); goto fail; } g_free(key); key = g_strconcat(line, "/xreal", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) xreal = g_ascii_strtod(s, NULL); else if (dfield) xreal = gwy_data_field_get_xreal(dfield); else { g_warning("Missing real data field width."); xreal = 1.0; /* 0 could cause troubles */ } g_free(key); key = g_strconcat(line, "/yreal", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) yreal = g_ascii_strtod(s, NULL); else if (dfield) yreal = gwy_data_field_get_yreal(dfield); else { g_warning("Missing real data field height."); yreal = 1.0; /* 0 could cause troubles */ } g_free(key); if (!(xres > 0 && yres > 0 && xreal > 0 && yreal > 0)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Data field dimensions are not positive numbers.")); goto fail; } key = g_strconcat(line, "/unit-xy", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) uxy = gwy_si_unit_new((const gchar*)s); else if (dfield) { uxy = gwy_data_field_get_si_unit_xy(dfield); uxy = gwy_si_unit_duplicate(uxy); } else { g_warning("Missing lateral units."); uxy = gwy_si_unit_new("m"); } g_free(key); key = g_strconcat(line, "/unit-z", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) uz = gwy_si_unit_new((const gchar*)s); else if (dfield) { uz = gwy_data_field_get_si_unit_z(dfield); uz = gwy_si_unit_duplicate(uz); } else { g_warning("Missing value units."); uz = gwy_si_unit_new("m"); } g_free(key); key = g_strconcat(line, "/title", NULL); title = NULL; gwy_container_gis_string_by_name(data, key, (const guchar**)&title); /* We got the contained string but that would disappear. */ title = g_strdup(title); g_free(key); n = xres*yres*sizeof(gdouble); if ((gsize)(pos - buffer) + n + 3 > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached inside a data field.")); goto fail; } dfield = GWY_DATA_FIELD(gwy_data_field_new(xres, yres, xreal, yreal, FALSE)); gwy_data_field_set_si_unit_xy(dfield, GWY_SI_UNIT(uxy)); gwy_object_unref(uxy); gwy_data_field_set_si_unit_z(dfield, GWY_SI_UNIT(uz)); gwy_object_unref(uz); d = gwy_data_field_get_data(dfield); #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) memcpy(d, pos, n); #else gwy_memcpy_byte_swap(pos, (guint8*)d, sizeof(gdouble), xres*yres, sizeof(gdouble)-1); #endif pos += n; val = gwy_str_next_line(&pos); if (!gwy_strequal(val, "]]")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing end of data field marker.")); gwy_object_unref(dfield); goto fail; } gwy_container_remove_by_prefix(data, line); gwy_container_set_object_by_name(data, line, dfield); g_object_unref(dfield); if (title) { key = g_strconcat(line, "/title", NULL); gwy_container_set_string_by_name(data, key, title); g_free(key); } gwy_file_channel_import_log_add(data, id, NULL, filename); } return data; fail: gwy_container_remove_by_prefix(data, NULL); g_object_unref(data); return NULL; }