📄 fsio.cpp
字号:
/* * fsio.cpp - ввод/вывод, сохранение/загрузка функций * Copyright (C) 2007 lester * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */#include "fsio.h"#include <gsf/gsf.h>#include <gsf/gsf-utils.h>#include <gsf/gsf-output.h>#include <gsf/gsf-output-stdio.h>#include <gsf/gsf-input.h>#include <gsf/gsf-input-stdio.h>#include <libxml/xmlmemory.h>#include <libxml/parser.h>#include <iostream>/* * Нет, я не сошел с ума. (Хотя...) * Дело в том что стдлибовский атоф тупо не видит цифры после зяпятой. * Скажем "0.2" он возвращает как 0. Я потратил бессонную ночь на дебагинг * и решил забить. Поэтому выдрал из иррлихта реализацию его собственного атоф. * Это код Николауса Гебхардта. */const float fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug 0.f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f, 0.0000000001f, 0.00000000001f, 0.000000000001f, 0.0000000000001f, 0.00000000000001f, 0.000000000000001f };inline guint strtol10( const char* in, const char* &out){ guint value = 0; char symbol; while ( 1 ) { symbol = *in; // где здесь синтакс еррор? или еклипс глючит или меня if ( symbol < '0' || symbol > '9' ) break; value = ( value * 10 ) + ( symbol - '0' ); in += 1; } out = in; return value;}//! Provides a fast function for converting a string into a float,//! about 6 times faster than atof in win32.// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.inline const char* fast_atof_move( const char* c, float& out){ bool inv = false; const char *t; float f; if (*c=='-') { c++; inv = true; } //f = (float)strtol(c, &t, 10); f = (float) strtol10 ( c, t ); c = t; if (*c == '.') { c++; //float pl = (float)strtol(c, &t, 10); float pl = (float) strtol10 ( c, t ); pl *= fast_atof_table[t-c]; f += pl; c = t; if (*c == 'e') { ++c; //float exp = (float)strtol(c, &t, 10); bool einv = (*c=='-'); if (einv) c++; float exp = (float)strtol10(c, t); if (einv) exp *= -1.0f; f *= (float)pow(10.0f, exp); c = t; } } if (inv) f *= -1.0f; out = f; return c;}inline float fast_atof(const char* c){ float ret; fast_atof_move(c, ret); return ret;}voidfsio_write_function (GsfXMLOut *out, const Function *f){ // я сначала хотел использовать libgsf для io, но потом перешел на libxml // а код сохранения переписывать влом gsf_xml_out_start_element (out, "graph"); gsf_xml_out_add_cstr (out, "equation", f->eq); gsf_xml_out_add_float (out, "xmin", f->xmin, 4); gsf_xml_out_add_float (out, "xmax", f->xmax, 4); gsf_xml_out_add_float (out, "step", f->step, 4); gsf_xml_out_add_cstr (out, "style", f->style); gsf_xml_out_add_int (out, "draw-method", static_cast<int>(f->dmethod)); gsf_xml_out_add_bool (out, "show", f->show ); gsf_xml_out_end_element (out);}voidfsio_write_functions (const gchar *filename){ GError **errors = NULL; GsfOutput *outfile = gsf_output_stdio_new (filename, errors); GsfXMLOut *xmlout = gsf_xml_out_new (outfile); FunctionList &flist = functions_get_function_list (); FunctionList::iterator it; float xmin, xmax, ymin, ymax; graph_get_dims (xmin, xmax, ymin, ymax); gsf_xml_out_start_element (xmlout, "sheet"); gsf_xml_out_add_float (xmlout, "xmin", xmin, -1); gsf_xml_out_add_float (xmlout, "xmax", xmax, -1); gsf_xml_out_add_float (xmlout, "ymin", ymin, -1); gsf_xml_out_add_float (xmlout, "ymax", ymax, -1); for (it = flist.begin(); it != flist.end(); ++it) { fsio_write_function (xmlout, *it); } gsf_xml_out_end_element (xmlout); gsf_output_close (outfile);}// наверно так делать нельзя#define CHECK_ERROR \ if (text == NULL ) \ { \ delete function; \ return -1; \ }intfsio_get_graph_nodes (xmlDocPtr doc, xmlNodePtr cur){ cur = cur->xmlChildrenNode; gchar *text = NULL; Function *function = NULL; while (cur != NULL) { if (!xmlStrcmp (cur->name, (const xmlChar *) "graph")) { text = (gchar *) xmlGetProp (cur, (const xmlChar *) "xmin"); CHECK_ERROR gdouble xmin = fast_atof ((const char *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "xmax"); CHECK_ERROR gdouble xmax = fast_atof ((const char *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "step"); CHECK_ERROR gdouble step = fast_atof ((const char *)text); function = functions_add_function_with_dims1 (xmin, xmax, step); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "equation"); CHECK_ERROR functions_modify_function1 (function, std::string ((const char *)text)); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "style"); CHECK_ERROR function->style = (gchar *)xmlStrdup ((const xmlChar *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "draw-method"); CHECK_ERROR function->dmethod = (DRAW_METHOD)atoi ((const char *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "show"); CHECK_ERROR function->show = (xmlStrcmp((const xmlChar *)text, (const xmlChar *)"0") == 0)? FALSE : TRUE; std::cout << function->eq << std::endl; } cur = cur->next; } return 0;}#undef CHECK_ERRORintfsio_read_functions (const char *filename){ xmlDocPtr doc; xmlNodePtr cur; doc = xmlParseFile (filename); if (doc == NULL ) { return -1; } cur = xmlDocGetRootElement (doc); if (cur == NULL) { xmlFreeDoc (doc); } if (xmlStrcmp (cur->name, (const xmlChar *) "sheet")) { xmlFreeDoc (doc); return -1; } else { gchar *text = NULL; gfloat xmin, xmax, ymin, ymax; // господи, как я люблю libxml2 с ее типом xmlChar text = (gchar *) xmlGetProp (cur, (const xmlChar *) "xmin"); if (text == NULL) { return -1; } xmin = fast_atof ((const char *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "xmax"); if (text == NULL) { return -1; } xmax = fast_atof ((const char *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "ymin"); if (text == NULL) { return -1; } ymin = fast_atof ((const char *)text); text = (gchar *) xmlGetProp (cur, (const xmlChar *) "ymax"); if (text == NULL) { return -1; } ymax = fast_atof ((const char *)text); graph_set_dims (xmin, xmax, ymin, ymax); } if (fsio_get_graph_nodes (doc, cur)) { xmlFreeDoc (doc); return -1; // надо както похендлить это, ну там ворнинг показать чтоли } xmlFreeDoc (doc); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -