1 /*
2  * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm.org>
3  *
4  * This file is part of Zrythm
5  *
6  * Zrythm is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Zrythm is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include <string.h>
21 
22 #include "utils/objects.h"
23 #include "utils/yaml.h"
24 
25 #include <gtk/gtk.h>
26 
27 cyaml_log_t _cyaml_log_level = CYAML_LOG_WARNING;
28 
29 void
yaml_set_log_level(cyaml_log_t level)30 yaml_set_log_level (
31   cyaml_log_t level)
32 {
33   _cyaml_log_level = level;
34 }
35 
36 void
yaml_get_cyaml_config(cyaml_config_t * config)37 yaml_get_cyaml_config (
38   cyaml_config_t * config)
39 {
40   /** log level: DEBUG, WARNING, INFO... */
41   config->log_level = _cyaml_log_level;
42   /* use the default loggin function */
43   //.log_fn = cyaml_log,
44   config->log_fn = yaml_cyaml_log_func;
45   /* use the default memory allocator */
46   config->mem_fn = cyaml_mem;
47   config->flags = CYAML_CFG_DOCUMENT_DELIM;
48 }
49 
50 /**
51  * Custom logging function for libcyaml.
52  */
yaml_cyaml_log_func(cyaml_log_t lvl,void * ctxt,const char * fmt,va_list ap)53 void yaml_cyaml_log_func (
54   cyaml_log_t  lvl,
55   void *       ctxt,
56   const char * fmt,
57   va_list      ap)
58 {
59   GLogLevelFlags level = G_LOG_LEVEL_MESSAGE;
60   switch (lvl)
61     {
62     case CYAML_LOG_WARNING:
63       level = G_LOG_LEVEL_WARNING;
64       break;
65     case CYAML_LOG_ERROR:
66       level = G_LOG_LEVEL_WARNING;
67       break;
68     default:
69       break;
70     }
71 
72   char format[900];
73   strcpy (format, fmt);
74   format[strlen (format) - 1] = '\0';
75 
76   g_logv ("cyaml", level, format, ap);
77 }
78 
79 /**
80  * Serializes to XML.
81  *
82  * MUST be free'd.
83  */
84 char *
yaml_serialize(void * data,const cyaml_schema_value_t * schema)85 yaml_serialize (
86   void *                       data,
87   const cyaml_schema_value_t * schema)
88 {
89   cyaml_err_t err;
90   cyaml_config_t cyaml_config;
91   yaml_get_cyaml_config (&cyaml_config);
92   char * output;
93   size_t output_len;
94   err =
95     cyaml_save_data (
96       &output, &output_len,
97       &cyaml_config, schema, data, 0);
98   if (err != CYAML_OK)
99     {
100       g_warning (
101         "error %s",
102         cyaml_strerror (err));
103       return NULL;
104     }
105   char * new_str =
106     object_new_n (output_len + 1, char);
107   memcpy (new_str, output, output_len);
108   new_str[output_len] = '\0';
109   cyaml_config.mem_fn (
110     cyaml_config.mem_ctx, output, 0);
111 
112   return new_str;
113 }
114 
115 void *
yaml_deserialize(const char * yaml,const cyaml_schema_value_t * schema)116 yaml_deserialize (
117   const char *                 yaml,
118   const cyaml_schema_value_t * schema)
119 {
120   void * obj;
121   cyaml_config_t cyaml_config;
122   yaml_get_cyaml_config (&cyaml_config);
123   cyaml_err_t err =
124     cyaml_load_data (
125       (const unsigned char *) yaml, strlen (yaml),
126       &cyaml_config, schema, (cyaml_data_t **) &obj,
127       NULL);
128   if (err != CYAML_OK)
129     {
130       g_warning (
131         "cyaml error: %s", cyaml_strerror (err));
132       return NULL;
133     }
134 
135   return obj;
136 }
137 
138 void
yaml_print(void * data,const cyaml_schema_value_t * schema)139 yaml_print (
140   void *                       data,
141   const cyaml_schema_value_t * schema)
142 {
143   char * yaml = yaml_serialize (data, schema);
144 
145   if (yaml)
146     {
147       g_message ("[YAML]\n%s", yaml);
148       g_free (yaml);
149     }
150   else
151     {
152       g_warning ("failed to deserialize %p", data);
153     }
154 }
155