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: 29 окт. 2019 г. 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 <ui/XMLNode.h> 23 #include <ui/XMLHandler.h> 24 25 namespace lsp 26 { 27 //------------------------------------------------------------------------- 28 // XML Node implementation XMLNode()29 XMLNode::XMLNode() 30 { 31 } 32 ~XMLNode()33 XMLNode::~XMLNode() 34 { 35 } 36 find_attribute(const LSPString * const * atts,const LSPString * name)37 const LSPString *XMLNode::find_attribute(const LSPString * const *atts, const LSPString *name) 38 { 39 for ( ; *atts != NULL; atts += 2) 40 { 41 if (atts[0]->equals(name)) 42 return atts[1]; 43 } 44 45 return NULL; 46 } 47 find_attribute(const LSPString * const * atts,const char * name)48 const LSPString *XMLNode::find_attribute(const LSPString * const *atts, const char *name) 49 { 50 LSPString tmp; 51 if (!tmp.set_utf8(name)) 52 return NULL; 53 return find_attribute(atts, &tmp); 54 } 55 enter()56 status_t XMLNode::enter() 57 { 58 return STATUS_OK; 59 } 60 start_element(XMLNode ** child,const LSPString * name,const LSPString * const * atts)61 status_t XMLNode::start_element(XMLNode **child, const LSPString *name, const LSPString * const *atts) 62 { 63 return STATUS_OK; 64 } 65 end_element(const LSPString * name)66 status_t XMLNode::end_element(const LSPString *name) 67 { 68 return STATUS_OK; 69 } 70 quit()71 status_t XMLNode::quit() 72 { 73 return STATUS_OK; 74 } 75 completed(XMLNode * child)76 status_t XMLNode::completed(XMLNode *child) 77 { 78 return STATUS_OK; 79 } 80 81 //------------------------------------------------------------------------- 82 // XML Playback Node implementation xml_event_t(event_t type)83 XMLPlaybackNode::xml_event_t::xml_event_t(event_t type) 84 { 85 nEvent = type; 86 } 87 ~xml_event_t()88 XMLPlaybackNode::xml_event_t::~xml_event_t() 89 { 90 for (size_t i=0, n=vData.size(); i<n; ++i) 91 { 92 LSPString *s = vData.at(i); 93 if (s != NULL) 94 delete s; 95 } 96 vData.flush(); 97 } 98 add_param(const LSPString * name)99 status_t XMLPlaybackNode::xml_event_t::add_param(const LSPString *name) 100 { 101 LSPString *tmp; 102 if ((tmp = name->clone()) == NULL) 103 return STATUS_NO_MEM; 104 else if (!vData.add(tmp)) 105 { 106 delete tmp; 107 return STATUS_NO_MEM; 108 } 109 return STATUS_OK; 110 } 111 add_event(event_t ev)112 XMLPlaybackNode::xml_event_t *XMLPlaybackNode::add_event(event_t ev) 113 { 114 xml_event_t *evt = new xml_event_t(ev); 115 if (evt == NULL) 116 return NULL; 117 else if (!vEvents.add(evt)) 118 { 119 delete evt; 120 evt = NULL; 121 } 122 return evt; 123 } 124 XMLPlaybackNode(XMLNode * handler)125 XMLPlaybackNode::XMLPlaybackNode(XMLNode *handler) 126 { 127 pHandler = handler; 128 } 129 ~XMLPlaybackNode()130 XMLPlaybackNode::~XMLPlaybackNode() 131 { 132 for (size_t i=0, n=vEvents.size(); i<n; ++i) 133 { 134 xml_event_t *ev = vEvents.at(i); 135 if (ev != NULL) 136 delete ev; 137 } 138 vEvents.flush(); 139 } 140 init(const LSPString * const * atts)141 status_t XMLPlaybackNode::init(const LSPString * const *atts) 142 { 143 return STATUS_OK; 144 } 145 playback_start_element(xml::IXMLHandler * handler,const LSPString * name,const LSPString * const * atts)146 status_t XMLPlaybackNode::playback_start_element(xml::IXMLHandler *handler, const LSPString *name, const LSPString * const *atts) 147 { 148 return handler->start_element(name, atts); 149 } 150 playback_end_element(xml::IXMLHandler * handler,const LSPString * name)151 status_t XMLPlaybackNode::playback_end_element(xml::IXMLHandler *handler, const LSPString *name) 152 { 153 return handler->end_element(name); 154 } 155 playback()156 status_t XMLPlaybackNode::playback() 157 { 158 status_t res = STATUS_OK; 159 XMLHandler h(pHandler); 160 161 for (size_t i=0, n=vEvents.size(); i<n; ++i) 162 { 163 // Fetch event 164 xml_event_t *ev = vEvents.at(i); 165 if (ev == NULL) 166 { 167 res = STATUS_CORRUPTED; 168 break; 169 } 170 171 // Parse event 172 LSPString **atts = ev->vData.get_array(); 173 switch (ev->nEvent) 174 { 175 case EVT_START_ELEMENT: 176 res = playback_start_element(&h, atts[0], &atts[1]); 177 break; 178 case EVT_END_ELEMENT: 179 res = playback_end_element(&h, atts[0]); 180 break; 181 default: 182 res = STATUS_CORRUPTED; 183 break; 184 } 185 186 // Check result 187 if (res != STATUS_OK) 188 break; 189 } 190 191 return res; 192 } 193 execute()194 status_t XMLPlaybackNode::execute() 195 { 196 return playback(); 197 } 198 start_element(XMLNode ** child,const LSPString * name,const LSPString * const * atts)199 status_t XMLPlaybackNode::start_element(XMLNode **child, const LSPString *name, const LSPString * const *atts) 200 { 201 // Allocate event 202 status_t res; 203 xml_event_t *evt = add_event(EVT_START_ELEMENT); 204 if (evt == NULL) 205 return STATUS_NO_MEM; 206 207 // Clone element name 208 if ((res = evt->add_param(name)) != STATUS_OK) 209 return res; 210 211 // Clone tag attributes 212 for ( ; *atts != NULL; ++atts) 213 { 214 // Clone attribute 215 if ((res = evt->add_param(*atts)) != STATUS_OK) 216 return res; 217 } 218 219 // Add terminator 220 if (!evt->vData.add(NULL)) 221 return STATUS_NO_MEM; 222 223 // Increment level, set child to this 224 *child = this; 225 226 return STATUS_OK; 227 } 228 end_element(const LSPString * name)229 status_t XMLPlaybackNode::end_element(const LSPString *name) 230 { 231 // Allocate event and add parameter 232 xml_event_t *evt = add_event(EVT_END_ELEMENT); 233 return (evt != NULL) ? evt->add_param(name) : STATUS_NO_MEM; 234 } 235 236 } /* namespace lsp */ 237