static gboolean gwyfile_save(GwyContainer *data, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GByteArray *buffer; gchar *filename_orig_utf8, *filename_utf8; FILE *fh; gboolean restore_filename, ok = TRUE; if (!(fh = g_fopen(filename, "wb"))) { err_OPEN_WRITE(error); return FALSE; } /* Assure the saved file contains its own name under "/filename" */ restore_filename = TRUE; filename_orig_utf8 = NULL; gwy_container_gis_string_by_name(data, "/filename", (const guchar**)&filename_orig_utf8); filename_orig_utf8 = g_strdup(filename_orig_utf8); filename_utf8 = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); if (!filename_utf8) gwy_container_remove_by_name(data, "/filename"); else if (filename_orig_utf8 && gwy_strequal(filename_orig_utf8, filename_utf8)) { restore_filename = FALSE; } else { gwy_container_set_string_by_name(data, "/filename", filename_utf8); filename_utf8 = NULL; } /* Serialize */ buffer = gwy_serializable_serialize(G_OBJECT(data), NULL); if (fwrite(MAGIC2, 1, MAGIC_SIZE, fh) != MAGIC_SIZE || fwrite(buffer->data, 1, buffer->len, fh) != buffer->len) { err_WRITE(error); ok = FALSE; g_unlink(filename); } fclose(fh); g_byte_array_free(buffer, TRUE); /* Restore filename if save failed */ if (!ok && restore_filename) { if (filename_orig_utf8) gwy_container_set_string_by_name(data, "/filename", filename_orig_utf8); else gwy_container_remove_by_name(data, "/filename"); filename_orig_utf8 = NULL; } g_free(filename_orig_utf8); g_free(filename_utf8); return ok; }
static void gwyfile_remove_old_data(GObject *object) { GwyContainer *data; GwySelection *rect, *point, *line; if (!object || !GWY_IS_CONTAINER(object)) return; data = GWY_CONTAINER(object); /* Selections */ rect = gwyfile_gather_old_rect_selection(data); point = gwyfile_gather_old_point_selection(data); line = gwyfile_gather_old_line_selection(data); gwy_container_remove_by_prefix(data, "/0/select"); if (rect) { gwy_container_set_object_by_name(data, "/0/select/rectangle", rect); g_object_unref(rect); } if (point) { gwy_container_set_object_by_name(data, "/0/select/point", point); g_object_unref(point); } if (line) { gwy_container_set_object_by_name(data, "/0/select/line", line); g_object_unref(line); } /* 3D */ gwy_container_remove_by_prefix(data, "/0/3d/labels"); gwy_container_remove_by_name(data, "/0/3d/rot_x"); gwy_container_remove_by_name(data, "/0/3d/rot_y"); gwy_container_remove_by_name(data, "/0/3d/view_scale"); gwy_container_remove_by_name(data, "/0/3d/deformation_z"); gwy_container_remove_by_name(data, "/0/3d/light_z"); gwy_container_remove_by_name(data, "/0/3d/light_y"); }
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; }