LCOV - code coverage report
Current view: top level - libgnucash/backend/xml - sixtp-dom-generators.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 88.5 % 165 146
Test Date: 2025-02-07 16:25:45 Functions: 85.7 % 14 12
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /********************************************************************
       2                 :             :  * sixtp-dom-generators.c                                           *
       3                 :             :  * Copyright 2001 Gnumatic, Inc.                                    *
       4                 :             :  *                                                                  *
       5                 :             :  * This program is free software; you can redistribute it and/or    *
       6                 :             :  * modify it under the terms of the GNU General Public License as   *
       7                 :             :  * published by the Free Software Foundation; either version 2 of   *
       8                 :             :  * the License, or (at your option) any later version.              *
       9                 :             :  *                                                                  *
      10                 :             :  * This program is distributed in the hope that it will be useful,  *
      11                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      12                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      13                 :             :  * GNU General Public License for more details.                     *
      14                 :             :  *                                                                  *
      15                 :             :  * You should have received a copy of the GNU General Public License*
      16                 :             :  * along with this program; if not, contact:                        *
      17                 :             :  *                                                                  *
      18                 :             :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      19                 :             :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      20                 :             :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      21                 :             :  *                                                                  *
      22                 :             :  ********************************************************************/
      23                 :             : #include <glib.h>
      24                 :             : 
      25                 :             : #define __EXTENSIONS__
      26                 :             : 
      27                 :             : #include <config.h>
      28                 :             : 
      29                 :             : #include <gnc-date.h>
      30                 :             : #include <cstdint>
      31                 :             : 
      32                 :             : #include "gnc-xml-helper.h"
      33                 :             : #include "sixtp-dom-generators.h"
      34                 :             : #include "sixtp-utils.h"
      35                 :             : 
      36                 :             : #include <kvp-frame.hpp>
      37                 :             : #include <gnc-datetime.hpp>
      38                 :             : 
      39                 :             : static QofLogModule log_module = GNC_MOD_IO;
      40                 :             : 
      41                 :             : xmlNodePtr
      42                 :           0 : boolean_to_dom_tree (const char* tag, gboolean val)
      43                 :             : {
      44                 :           0 :     return text_to_dom_tree (tag, val ? "TRUE" : "FALSE");
      45                 :             : }
      46                 :             : 
      47                 :             : xmlNodePtr
      48                 :        2041 : text_to_dom_tree (const char* tag, const char* str)
      49                 :             : {
      50                 :        2041 :     g_return_val_if_fail (tag, NULL);
      51                 :        2041 :     g_return_val_if_fail (str, NULL);
      52                 :             : 
      53                 :        2041 :     xmlNodePtr result = xmlNewNode (NULL, BAD_CAST tag);
      54                 :        2041 :     g_return_val_if_fail (result, NULL);
      55                 :             : 
      56                 :        2041 :     gchar* newstr = g_strdup (str);
      57                 :        2041 :     xmlNodeAddContent (result, checked_char_cast (newstr));
      58                 :        2041 :     g_free (newstr);
      59                 :             : 
      60                 :        2041 :     return result;
      61                 :             : }
      62                 :             : 
      63                 :             : xmlNodePtr
      64                 :         293 : int_to_dom_tree (const char* tag, gint64 val)
      65                 :             : {
      66                 :             :     gchar* text;
      67                 :             :     xmlNodePtr result;
      68                 :             : 
      69                 :         293 :     text = g_strdup_printf ("%" G_GINT64_FORMAT, val);
      70                 :         293 :     g_return_val_if_fail (text, NULL);
      71                 :         293 :     result = text_to_dom_tree (tag, text);
      72                 :         293 :     g_free (text);
      73                 :         293 :     return result;
      74                 :             : }
      75                 :             : 
      76                 :             : xmlNodePtr
      77                 :           2 : guint_to_dom_tree (const char* tag, guint an_int)
      78                 :             : {
      79                 :             :     gchar* text;
      80                 :             :     xmlNodePtr result;
      81                 :             : 
      82                 :           2 :     text = g_strdup_printf ("%u", an_int);
      83                 :           2 :     g_return_val_if_fail (text, NULL);
      84                 :           2 :     result = text_to_dom_tree (tag, text);
      85                 :           2 :     g_free (text);
      86                 :           2 :     return result;
      87                 :             : }
      88                 :             : 
      89                 :             : 
      90                 :             : xmlNodePtr
      91                 :        1258 : guid_to_dom_tree (const char* tag, const GncGUID* gid)
      92                 :             : {
      93                 :             :     char guid_str[GUID_ENCODING_LENGTH + 1];
      94                 :             :     xmlNodePtr ret;
      95                 :             : 
      96                 :        1258 :     ret = xmlNewNode (NULL, BAD_CAST tag);
      97                 :             : 
      98                 :        1258 :     xmlSetProp (ret, BAD_CAST "type", BAD_CAST "guid");
      99                 :             : 
     100                 :        1258 :     if (!guid_to_string_buff (gid, guid_str))
     101                 :             :     {
     102                 :           0 :         PERR ("guid_to_string_buff failed\n");
     103                 :           0 :         return NULL;
     104                 :             :     }
     105                 :             : 
     106                 :        1258 :     xmlNodeAddContent (ret, BAD_CAST guid_str);
     107                 :             : 
     108                 :        1258 :     return ret;
     109                 :             : }
     110                 :             : 
     111                 :             : xmlNodePtr
     112                 :        1169 : commodity_ref_to_dom_tree (const char* tag, const gnc_commodity* c)
     113                 :             : {
     114                 :             :     xmlNodePtr ret;
     115                 :             :     gchar* name_space, *mnemonic;
     116                 :             : 
     117                 :        1169 :     g_return_val_if_fail (c, NULL);
     118                 :             : 
     119                 :        1169 :     ret = xmlNewNode (NULL, BAD_CAST tag);
     120                 :             : 
     121                 :        1169 :     if (!gnc_commodity_get_namespace (c) || !gnc_commodity_get_mnemonic (c))
     122                 :             :     {
     123                 :           0 :         return NULL;
     124                 :             :     }
     125                 :        1169 :     name_space = g_strdup (gnc_commodity_get_namespace (c));
     126                 :        1169 :     mnemonic = g_strdup (gnc_commodity_get_mnemonic (c));
     127                 :        1169 :     xmlNewTextChild (ret, NULL, BAD_CAST "cmdty:space",
     128                 :        1169 :                      checked_char_cast (name_space));
     129                 :        1169 :     xmlNewTextChild (ret, NULL, BAD_CAST "cmdty:id",
     130                 :        1169 :                      checked_char_cast (mnemonic));
     131                 :        1169 :     g_free (name_space);
     132                 :        1169 :     g_free (mnemonic);
     133                 :        1169 :     return ret;
     134                 :             : }
     135                 :             : 
     136                 :             : xmlNodePtr
     137                 :         664 : time64_to_dom_tree (const char* tag, const time64 time)
     138                 :             : {
     139                 :             :     xmlNodePtr ret;
     140                 :         664 :     g_return_val_if_fail (time != INT64_MAX, NULL);
     141                 :         664 :     auto date_str = GncDateTime(time).format_iso8601();
     142                 :         664 :     if (date_str.empty())
     143                 :           0 :         return NULL;
     144                 :         664 :     date_str += " +0000"; //Tack on a UTC offset to mollify GnuCash for Android
     145                 :         664 :     ret = xmlNewNode (NULL, BAD_CAST tag);
     146                 :         664 :     xmlNewTextChild (ret, NULL, BAD_CAST "ts:date",
     147                 :         664 :                      checked_char_cast (const_cast<char*>(date_str.c_str())));
     148                 :         664 :     return ret;
     149                 :         664 : }
     150                 :             : 
     151                 :             : xmlNodePtr
     152                 :           8 : gdate_to_dom_tree (const char* tag, const GDate* date)
     153                 :             : {
     154                 :             :     xmlNodePtr ret;
     155                 :           8 :     gchar* date_str = NULL;
     156                 :             : 
     157                 :           8 :     g_return_val_if_fail (date, NULL);
     158                 :           8 :     date_str = g_new (gchar, 512);
     159                 :             : 
     160                 :           8 :     g_date_strftime (date_str, 512, "%Y-%m-%d", date);
     161                 :             : 
     162                 :           8 :     ret = xmlNewNode (NULL, BAD_CAST tag);
     163                 :             : 
     164                 :           8 :     xmlNewTextChild (ret, NULL, BAD_CAST "gdate", checked_char_cast (date_str));
     165                 :             : 
     166                 :           8 :     g_free (date_str);
     167                 :             : 
     168                 :           8 :     return ret;
     169                 :             : }
     170                 :             : 
     171                 :             : xmlNodePtr
     172                 :         675 : gnc_numeric_to_dom_tree (const char* tag, const gnc_numeric* num)
     173                 :             : {
     174                 :             :     xmlNodePtr ret;
     175                 :             :     gchar* numstr;
     176                 :             : 
     177                 :         675 :     g_return_val_if_fail (num, NULL);
     178                 :             : 
     179                 :         675 :     numstr = gnc_numeric_to_string (*num);
     180                 :         675 :     g_return_val_if_fail (numstr, NULL);
     181                 :             : 
     182                 :         675 :     ret = xmlNewNode (NULL, BAD_CAST tag);
     183                 :             : 
     184                 :         675 :     xmlNodeAddContent (ret, checked_char_cast (numstr));
     185                 :             : 
     186                 :         675 :     g_free (numstr);
     187                 :             : 
     188                 :         675 :     return ret;
     189                 :             : }
     190                 :             : 
     191                 :             : gchar*
     192                 :           0 : double_to_string (double value)
     193                 :             : {
     194                 :             :     gchar* numstr;
     195                 :           0 :     numstr = g_strdup_printf ("%24.18g", value);
     196                 :             : 
     197                 :           0 :     if (!numstr)
     198                 :             :     {
     199                 :           0 :         return NULL;
     200                 :             : 
     201                 :             :     }
     202                 :             :     else
     203                 :             :     {
     204                 :           0 :         return g_strstrip (numstr);
     205                 :             :     }
     206                 :             : }
     207                 :             : 
     208                 :             : static void
     209                 :        1749 : add_text_to_node (xmlNodePtr node, const gchar* type, gchar* val)
     210                 :             : {
     211                 :        1749 :     xmlSetProp (node, BAD_CAST "type", BAD_CAST type);
     212                 :        1749 :     xmlNodeSetContent (node, checked_char_cast (val));
     213                 :        1749 : }
     214                 :             : 
     215                 :             : static void add_kvp_slot (const char* key, KvpValue* value, void* data);
     216                 :             : 
     217                 :             : static void
     218                 :        2744 : add_kvp_value_node (xmlNodePtr node, const gchar* tag, KvpValue* val)
     219                 :             : {
     220                 :             :     xmlNodePtr val_node;
     221                 :             : 
     222                 :        2744 :     switch (val->get_type ())
     223                 :             :     {
     224                 :         482 :     case KvpValue::Type::STRING:
     225                 :             :     {
     226                 :         482 :         auto newstr = g_strdup (val->get<const char*> ());
     227                 :         964 :         val_node = xmlNewTextChild (node, NULL, BAD_CAST tag,
     228                 :         482 :                                     checked_char_cast (newstr));
     229                 :         482 :         g_free (newstr);
     230                 :         482 :         break;
     231                 :             :     }
     232                 :           2 :     case KvpValue::Type::TIME64:
     233                 :           2 :         val_node = NULL;
     234                 :           2 :         break;
     235                 :           2 :     case KvpValue::Type::GDATE:
     236                 :             :     {
     237                 :           2 :         auto d = val->get<GDate> ();
     238                 :           2 :         val_node = gdate_to_dom_tree (tag, &d);
     239                 :           2 :         xmlAddChild (node, val_node);
     240                 :           2 :         break;
     241                 :             :     }
     242                 :        2258 :     default:
     243                 :        2258 :         val_node = xmlNewTextChild (node, NULL, BAD_CAST tag, NULL);
     244                 :        2258 :         break;
     245                 :             :     }
     246                 :             : 
     247                 :        2744 :     switch (val->get_type ())
     248                 :             :     {
     249                 :         862 :     case KvpValue::Type::INT64:
     250                 :             :     {
     251                 :         862 :         char *int_str = g_strdup_printf ("%" G_GINT64_FORMAT, val->get<int64_t> ());
     252                 :         862 :         add_text_to_node (val_node, "integer", int_str);
     253                 :         862 :         g_free (int_str);
     254                 :         862 :         break;
     255                 :             :     }
     256                 :           0 :     case KvpValue::Type::DOUBLE:
     257                 :             :     {
     258                 :           0 :         char *dbl_str = double_to_string (val->get<double> ());
     259                 :           0 :         add_text_to_node (val_node, "double", dbl_str);
     260                 :           0 :         g_free (dbl_str);
     261                 :           0 :         break;
     262                 :             :     }
     263                 :         446 :     case KvpValue::Type::NUMERIC:
     264                 :             :     {
     265                 :         446 :         char *num_str = gnc_numeric_to_string (val->get<gnc_numeric> ());
     266                 :         446 :         add_text_to_node (val_node, "numeric", num_str);
     267                 :         446 :         g_free (num_str);
     268                 :         446 :         break;
     269                 :             :     }
     270                 :         482 :     case KvpValue::Type::STRING:
     271                 :         482 :         xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "string");
     272                 :         482 :         break;
     273                 :         441 :     case KvpValue::Type::GUID:
     274                 :             :     {
     275                 :             :         gchar guidstr[GUID_ENCODING_LENGTH + 1];
     276                 :         441 :         guid_to_string_buff (val->get<GncGUID*> (), guidstr);
     277                 :         441 :         add_text_to_node (val_node, "guid", guidstr);
     278                 :         441 :         break;
     279                 :             :     }
     280                 :             :     /* Note: The type attribute must remain 'timespec' to maintain
     281                 :             :      * compatibility.
     282                 :             :      */
     283                 :           2 :     case KvpValue::Type::TIME64:
     284                 :             :     {
     285                 :           2 :         auto t = val->get<Time64> ();
     286                 :           2 :         val_node = time64_to_dom_tree (tag, t.t);
     287                 :           2 :         xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
     288                 :           2 :         xmlAddChild (node, val_node);
     289                 :           2 :         break;
     290                 :             :     }
     291                 :           2 :     case KvpValue::Type::GDATE:
     292                 :           2 :         xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "gdate");
     293                 :           2 :         break;
     294                 :         254 :     case KvpValue::Type::GLIST:
     295                 :         254 :         xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "list");
     296                 :        1014 :         for (auto cursor = val->get<GList*> (); cursor; cursor = cursor->next)
     297                 :             :         {
     298                 :         760 :             auto val = static_cast<KvpValue*> (cursor->data);
     299                 :         760 :             add_kvp_value_node (val_node, "slot:value", val);
     300                 :             :         }
     301                 :         254 :         break;
     302                 :         255 :     case KvpValue::Type::FRAME:
     303                 :             :     {
     304                 :         255 :         xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "frame");
     305                 :             : 
     306                 :         255 :         auto frame = val->get<KvpFrame*> ();
     307                 :         255 :         if (!frame)
     308                 :           0 :             break;
     309                 :         255 :         frame->for_each_slot_temp (&add_kvp_slot, val_node);
     310                 :         255 :         break;
     311                 :             :     }
     312                 :           0 :     default:
     313                 :           0 :         break;
     314                 :             :     }
     315                 :        2744 : }
     316                 :             : 
     317                 :             : static void
     318                 :        1984 : add_kvp_slot (const char* key, KvpValue* value, void* data)
     319                 :             : {
     320                 :        1984 :     auto newkey = g_strdup ((gchar*)key);
     321                 :        1984 :     auto node = static_cast<xmlNodePtr> (data);
     322                 :        1984 :     auto slot_node = xmlNewChild (node, NULL, BAD_CAST "slot", NULL);
     323                 :             : 
     324                 :        1984 :     xmlNewTextChild (slot_node, NULL, BAD_CAST "slot:key",
     325                 :        1984 :                      checked_char_cast (newkey));
     326                 :        1984 :     g_free (newkey);
     327                 :        1984 :     add_kvp_value_node (slot_node, "slot:value", value);
     328                 :        1984 : }
     329                 :             : 
     330                 :             : xmlNodePtr
     331                 :        1395 : qof_instance_slots_to_dom_tree (const char* tag, const QofInstance* inst)
     332                 :             : {
     333                 :             :     xmlNodePtr ret;
     334                 :        1395 :     KvpFrame* frame = qof_instance_get_slots (inst);
     335                 :        1395 :     if (!frame || frame->empty())
     336                 :        1160 :         return nullptr;
     337                 :             : 
     338                 :         235 :     ret = xmlNewNode (nullptr, BAD_CAST tag);
     339                 :         235 :     frame->for_each_slot_temp (&add_kvp_slot, ret);
     340                 :         235 :     return ret;
     341                 :             : }
        

Generated by: LCOV version 2.0-1