1/*
2 * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved.
3
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#include "tvgCommon.h"
24#include "tvgSaveModule.h"
25
26#ifdef THORVG_TVG_SAVER_SUPPORT
27 #include "tvgTvgSaver.h"
28#endif
29
30/************************************************************************/
31/* Internal Class Implementation */
32/************************************************************************/
33
34struct Saver::Impl
35{
36 SaveModule* saveModule = nullptr;
37 ~Impl()
38 {
39 delete(saveModule);
40 }
41};
42
43
44static SaveModule* _find(FileType type)
45{
46 switch(type) {
47 case FileType::Tvg: {
48#ifdef THORVG_TVG_SAVER_SUPPORT
49 return new TvgSaver;
50#endif
51 break;
52 }
53 default: {
54 break;
55 }
56 }
57
58#ifdef THORVG_LOG_ENABLED
59 const char *format;
60 switch(type) {
61 case FileType::Tvg: {
62 format = "TVG";
63 break;
64 }
65 default: {
66 format = "???";
67 break;
68 }
69 }
70 TVGLOG("SAVER", "%s format is not supported", format);
71#endif
72 return nullptr;
73}
74
75
76static SaveModule* _find(const string& path)
77{
78 auto ext = path.substr(path.find_last_of(".") + 1);
79 if (!ext.compare("tvg")) {
80 return _find(FileType::Tvg);
81 }
82 return nullptr;
83}
84
85
86/************************************************************************/
87/* External Class Implementation */
88/************************************************************************/
89
90Saver::Saver() : pImpl(new Impl())
91{
92}
93
94
95Saver::~Saver()
96{
97 delete(pImpl);
98}
99
100
101Result Saver::save(std::unique_ptr<Paint> paint, const string& path, bool compress) noexcept
102{
103 auto p = paint.release();
104 if (!p) return Result::MemoryCorruption;
105
106 //Already on saving an other resource.
107 if (pImpl->saveModule) {
108 delete(p);
109 return Result::InsufficientCondition;
110 }
111
112 if (auto saveModule = _find(path)) {
113 if (saveModule->save(p, path, compress)) {
114 pImpl->saveModule = saveModule;
115 return Result::Success;
116 } else {
117 delete(p);
118 delete(saveModule);
119 return Result::Unknown;
120 }
121 }
122 delete(p);
123 return Result::NonSupport;
124}
125
126
127Result Saver::sync() noexcept
128{
129 if (!pImpl->saveModule) return Result::InsufficientCondition;
130 pImpl->saveModule->close();
131 delete(pImpl->saveModule);
132 pImpl->saveModule = nullptr;
133
134 return Result::Success;
135}
136
137
138unique_ptr<Saver> Saver::gen() noexcept
139{
140 return unique_ptr<Saver>(new Saver);
141}
142