2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU 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.
11 * CasparCG 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 General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Niklas P Andersson, niklas.p.andersson@svt.se
23 #include "descriptor.h"
24 #include <boost\property_tree\ptree.hpp>
27 namespace caspar { namespace psd {
29 class descriptor::context::scoped_holder
31 descriptor::context::ptr_type ctx_;
33 explicit scoped_holder(const std::wstring& key, descriptor::context::ptr_type ctx) : ctx_(ctx)
35 Ptree *parent = ctx_->stack.back();
36 Ptree *child = &parent->push_back(std::make_pair(key, Ptree()))->second;
37 ctx_->stack.push_back(child);
41 ctx_->stack.pop_back();
45 descriptor::descriptor() : context_(std::make_shared<context>())
47 context_->stack.push_back(&context_->root);
49 descriptor::descriptor(const std::wstring& key, context::ptr_type context) : context_(context)
51 Ptree *parent = context_->stack.back();
52 Ptree *child = &parent->push_back(std::make_pair(key, Ptree()))->second;
53 context->stack.push_back(child);
55 descriptor::~descriptor()
57 context_->stack.pop_back();
60 bool descriptor::populate(BEFileInputStream& stream)
66 stream.read_unicode_string();
67 stream.read_id_string();
68 unsigned long element_count = stream.read_long();
69 for(int element_index = 0; element_index < element_count; ++element_index)
71 std::wstring key = stream.read_id_string();
72 read_value(key, stream);
75 catch(std::exception& ex)
83 void descriptor::read_value(const std::wstring& key, BEFileInputStream& stream)
85 unsigned int type = stream.read_long();
91 descriptor desc(key, context_);
92 desc.populate(stream);
98 context_->stack.back()->put(key, stream.read_double());
104 context_->stack.back()->put(key, stream.read_unicode_string());
110 context_->stack.back()->put(stream.read_id_string(), stream.read_id_string());
116 context_->stack.back()->put(key, static_cast<long>(stream.read_long()));
122 context_->stack.back()->put(key, stream.read_byte());
128 context::scoped_holder list(key, context_);
129 unsigned long count = stream.read_long();
130 for(int i = 0; i < count; ++i)
132 read_value(L"li", stream);
139 unsigned long rawdata_length = stream.read_long();
140 std::vector<char> rawdata(rawdata_length);
141 stream.read(rawdata.data(), rawdata_length);
143 std::wstring data_str(rawdata.begin(), rawdata.end());
144 context_->stack.back()->put(key, data_str);
150 context::scoped_holder list(key, context_);
151 unsigned long unit = stream.read_long();
152 std::string type(reinterpret_cast<char*>(&unit), 4);
153 std::wstring wtype(type.rbegin(), type.rend());
154 context_->stack.back()->put(wtype, stream.read_double());
164 //descriptor type not supported yet
165 throw PSDFileFormatException();