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

Generated by: LCOV version 2.0-1