1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 27 янв. 2016 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <core/types.h>
23 #include <core/IWrapper.h>
24 #include <core/system.h>
25 #include <core/JsonDumper.h>
26 #include <core/plugin.h>
27 #include <metadata/metadata.h>
28 #include <time.h>
29 
30 namespace lsp
31 {
IWrapper(plugin_t * plugin)32     IWrapper::IWrapper(plugin_t *plugin)
33     {
34         pPlugin     = plugin;
35     }
36 
~IWrapper()37     IWrapper::~IWrapper()
38     {
39     }
40 
get_executor()41     ipc::IExecutor *IWrapper::get_executor()
42     {
43         return NULL;
44     }
45 
query_display_draw()46     void IWrapper::query_display_draw()
47     {
48     }
49 
position()50     const position_t *IWrapper::position()
51     {
52         return NULL;
53     }
54 
create_canvas(ICanvas * & cv,size_t width,size_t height)55     ICanvas *IWrapper::create_canvas(ICanvas *&cv, size_t width, size_t height)
56     {
57         return NULL;
58     }
59 
kvt_lock()60     KVTStorage *IWrapper::kvt_lock()
61     {
62         return NULL;
63     }
64 
kvt_trylock()65     KVTStorage *IWrapper::kvt_trylock()
66     {
67         return NULL;
68     }
69 
kvt_release()70     bool IWrapper::kvt_release()
71     {
72         return false;
73     }
74 
state_changed()75     void IWrapper::state_changed()
76     {
77     }
78 
dump_plugin_state()79     void IWrapper::dump_plugin_state()
80     {
81         if (pPlugin == NULL)
82             return;
83 
84         io::Path path;
85         status_t res;
86         if ((res = system::get_temporary_dir(&path)) != STATUS_OK)
87         {
88             lsp_warn("Could not obtain temporary directory: %d", int(res));
89             return;
90         }
91         if ((res = path.append_child(LSP_ARTIFACT_ID "-dumps")) != STATUS_OK)
92         {
93             lsp_warn("Could not form path to directory: %d", int(res));
94             return;
95         }
96         if ((res = path.mkdir(true)) != STATUS_OK)
97         {
98             lsp_warn("Could not create directory %s: %d", path.as_utf8(), int(res));
99             return;
100         }
101 
102         // Get current time
103         struct timespec stime;
104         struct tm *t;
105         clock_gettime(CLOCK_REALTIME, &stime);
106     #if defined(_POSIX_C_SOURCE) || defined(_BSD_SOURCE) || defined(_SVID_SOURCE)
107         struct tm ctime;
108         t           = localtime_r(&stime.tv_sec, &ctime);
109     #else
110         t           = localtime(&stime.tv_sec);
111     #endif
112 
113         const plugin_metadata_t *meta = pPlugin->get_metadata();
114         if (meta == NULL)
115             return;
116 
117         // Build the file name
118         LSPString fname;
119         if (!fname.fmt_ascii("%04d%02d%02d-%02d%02d%02d-%03d-%s.json",
120                 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, int(stime.tv_nsec / 1000000),
121                 meta->lv2_uid
122             ))
123         {
124             lsp_warn("Could not format the file name");
125             return;
126         }
127 
128         if ((res = path.append_child(&fname)) != STATUS_OK)
129         {
130             lsp_warn("Could not form the file name: %d", int(res));
131             return;
132         }
133 
134         lsp_info("Dumping plugin state to file:\n%s...", path.as_utf8());
135 
136         JsonDumper v;
137         if ((res = v.open(&path)) != STATUS_OK)
138         {
139             lsp_warn("Could not create file %s: %d", path.as_utf8(), int(res));
140             return;
141         }
142 
143         v.begin_raw_object();
144         {
145             LSPString tmp;
146 
147             v.write("name", meta->name);
148             v.write("description", meta->description);
149             v.write("package", LSP_MAIN_VERSION);
150             tmp.fmt_ascii("%d.%d.%d",
151                     int(LSP_VERSION_MAJOR(meta->version)),
152                     int(LSP_VERSION_MINOR(meta->version)),
153                     int(LSP_VERSION_MICRO(meta->version))
154                 );
155             v.write("version", tmp.get_utf8());
156             tmp.fmt_ascii("%s%s", LSP_URI(lv2), meta->lv2_uid);
157             v.write("lv2_uri", tmp.get_utf8());
158             v.write("vst_id", meta->vst_uid);
159             v.write("ladspa_id", meta->ladspa_id);
160             v.write("this", pPlugin);
161             v.begin_raw_object("data");
162             {
163                 pPlugin->dump(&v);
164             }
165             v.end_raw_object();
166         }
167 
168         v.end_raw_object();
169         v.close();
170 
171         lsp_info("State has been dumped to file:\n%s", path.as_utf8());
172     }
173 
174 } /* namespace lsp */
175