Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "sal/config.h"
21 :
22 : #include <cstdlib>
23 : #include <cstring>
24 : #include <vector>
25 :
26 : #include "codemaker/global.hxx"
27 : #include "codemaker/typemanager.hxx"
28 : #include "rtl/ref.hxx"
29 : #include "rtl/ustring.hxx"
30 : #include "unoidl/unoidl.hxx"
31 :
32 0 : TypeManager::TypeManager(): manager_(new unoidl::Manager) {}
33 :
34 0 : TypeManager::~TypeManager() {}
35 :
36 0 : void TypeManager::loadProvider(OUString const & uri, bool primary) {
37 : rtl::Reference< unoidl::Provider > prov(
38 0 : unoidl::loadProvider(manager_, uri));
39 0 : manager_->addProvider(prov);
40 0 : if (primary) {
41 0 : primaryProviders_.push_back(prov);
42 0 : }
43 0 : }
44 :
45 0 : bool TypeManager::foundAtPrimaryProvider(OUString const & name) const {
46 0 : if (name.isEmpty()) {
47 0 : return !primaryProviders_.empty();
48 : }
49 0 : for (std::vector< rtl::Reference< unoidl::Provider > >::const_iterator i(
50 0 : primaryProviders_.begin());
51 0 : i != primaryProviders_.end(); ++i)
52 : {
53 0 : if ((*i)->findEntity(name).is()) {
54 0 : return true;
55 : }
56 : }
57 0 : if (!manager_->findEntity(name).is()) {
58 0 : throw CannotDumpException("Unknown entity '" + name + "'");
59 : }
60 0 : return false;
61 : }
62 :
63 0 : codemaker::UnoType::Sort TypeManager::getSort(
64 : OUString const & name, rtl::Reference< unoidl::Entity > * entity,
65 : rtl::Reference< unoidl::MapCursor > * cursor) const
66 : {
67 0 : if (name.isEmpty()) {
68 0 : if (cursor != 0) {
69 0 : *cursor = manager_->createCursor("");
70 : }
71 0 : return codemaker::UnoType::SORT_MODULE;
72 : }
73 0 : if (name == "void") {
74 0 : return codemaker::UnoType::SORT_VOID;
75 : }
76 0 : if (name == "boolean") {
77 0 : return codemaker::UnoType::SORT_BOOLEAN;
78 : }
79 0 : if (name == "byte") {
80 0 : return codemaker::UnoType::SORT_BYTE;
81 : }
82 0 : if (name == "short") {
83 0 : return codemaker::UnoType::SORT_SHORT;
84 : }
85 0 : if (name == "unsigned short") {
86 0 : return codemaker::UnoType::SORT_UNSIGNED_SHORT;
87 : }
88 0 : if (name == "long") {
89 0 : return codemaker::UnoType::SORT_LONG;
90 : }
91 0 : if (name == "unsigned long") {
92 0 : return codemaker::UnoType::SORT_UNSIGNED_LONG;
93 : }
94 0 : if (name == "hyper") {
95 0 : return codemaker::UnoType::SORT_HYPER;
96 : }
97 0 : if (name == "unsigned hyper") {
98 0 : return codemaker::UnoType::SORT_UNSIGNED_HYPER;
99 : }
100 0 : if (name == "float") {
101 0 : return codemaker::UnoType::SORT_FLOAT;
102 : }
103 0 : if (name == "double") {
104 0 : return codemaker::UnoType::SORT_DOUBLE;
105 : }
106 0 : if (name == "char") {
107 0 : return codemaker::UnoType::SORT_CHAR;
108 : }
109 0 : if (name == "string") {
110 0 : return codemaker::UnoType::SORT_STRING;
111 : }
112 0 : if (name == "type") {
113 0 : return codemaker::UnoType::SORT_TYPE;
114 : }
115 0 : if (name == "any") {
116 0 : return codemaker::UnoType::SORT_ANY;
117 : }
118 0 : if (name.startsWith("[")) {
119 0 : return codemaker::UnoType::SORT_SEQUENCE_TYPE;
120 : }
121 0 : if (name.indexOf('<') != -1) {
122 0 : return codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE;
123 : }
124 0 : rtl::Reference< unoidl::Entity > ent(manager_->findEntity(name));
125 0 : if (!ent.is()) {
126 0 : throw CannotDumpException("Unknown entity '" + name + "'");
127 : }
128 0 : if (entity != 0) {
129 0 : *entity = ent;
130 : }
131 0 : switch (ent->getSort()) {
132 : case unoidl::Entity::SORT_MODULE:
133 0 : if (cursor != 0) {
134 0 : *cursor = manager_->createCursor(name);
135 : }
136 0 : return codemaker::UnoType::SORT_MODULE;
137 : case unoidl::Entity::SORT_ENUM_TYPE:
138 0 : return codemaker::UnoType::SORT_ENUM_TYPE;
139 : case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
140 0 : return codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE;
141 : case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
142 0 : return codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE;
143 : case unoidl::Entity::SORT_EXCEPTION_TYPE:
144 0 : return codemaker::UnoType::SORT_EXCEPTION_TYPE;
145 : case unoidl::Entity::SORT_INTERFACE_TYPE:
146 0 : return codemaker::UnoType::SORT_INTERFACE_TYPE;
147 : case unoidl::Entity::SORT_TYPEDEF:
148 0 : return codemaker::UnoType::SORT_TYPEDEF;
149 : case unoidl::Entity::SORT_CONSTANT_GROUP:
150 0 : return codemaker::UnoType::SORT_CONSTANT_GROUP;
151 : case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
152 0 : return codemaker::UnoType::SORT_SINGLE_INTERFACE_BASED_SERVICE;
153 : case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
154 0 : return codemaker::UnoType::SORT_ACCUMULATION_BASED_SERVICE;
155 : case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
156 0 : return codemaker::UnoType::SORT_INTERFACE_BASED_SINGLETON;
157 : case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
158 0 : return codemaker::UnoType::SORT_SERVICE_BASED_SINGLETON;
159 : default:
160 0 : for (;;) { std::abort(); } // this cannot happen
161 0 : }
162 : }
163 :
164 0 : codemaker::UnoType::Sort TypeManager::decompose(
165 : OUString const & name, bool resolveTypedefs, OUString * nucleus,
166 : sal_Int32 * rank, std::vector< OUString > * arguments,
167 : rtl::Reference< unoidl::Entity > * entity) const
168 : {
169 : sal_Int32 k;
170 0 : std::vector< OString > args;
171 0 : OUString n = b2u(codemaker::UnoType::decompose(u2b(name), &k, &args));
172 : for (;;) {
173 0 : rtl::Reference< unoidl::Entity > ent;
174 0 : codemaker::UnoType::Sort s = getSort(n, &ent);
175 0 : if (args.empty()
176 0 : != (s != codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE))
177 : {
178 : throw CannotDumpException(
179 0 : "template arguments mismatch for \"" + n
180 0 : + "\" resolved from \"" + name + "\"");
181 : }
182 0 : switch (s) {
183 : case codemaker::UnoType::SORT_TYPEDEF:
184 0 : if (resolveTypedefs) {
185 0 : n = dynamic_cast< unoidl::TypedefEntity * >(ent.get())->
186 0 : getType();
187 0 : while (n.startsWith("[]")) {
188 0 : ++k; //TODO: overflow
189 0 : n = n.copy(std::strlen("[]"));
190 : }
191 0 : break;
192 : }
193 : // fall through
194 : case codemaker::UnoType::SORT_VOID:
195 : case codemaker::UnoType::SORT_BOOLEAN:
196 : case codemaker::UnoType::SORT_BYTE:
197 : case codemaker::UnoType::SORT_SHORT:
198 : case codemaker::UnoType::SORT_UNSIGNED_SHORT:
199 : case codemaker::UnoType::SORT_LONG:
200 : case codemaker::UnoType::SORT_UNSIGNED_LONG:
201 : case codemaker::UnoType::SORT_HYPER:
202 : case codemaker::UnoType::SORT_UNSIGNED_HYPER:
203 : case codemaker::UnoType::SORT_FLOAT:
204 : case codemaker::UnoType::SORT_DOUBLE:
205 : case codemaker::UnoType::SORT_CHAR:
206 : case codemaker::UnoType::SORT_STRING:
207 : case codemaker::UnoType::SORT_TYPE:
208 : case codemaker::UnoType::SORT_ANY:
209 : case codemaker::UnoType::SORT_ENUM_TYPE:
210 : case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
211 : case codemaker::UnoType::SORT_EXCEPTION_TYPE:
212 : case codemaker::UnoType::SORT_INTERFACE_TYPE:
213 0 : if (nucleus != 0) {
214 0 : *nucleus = n;
215 : }
216 0 : if (rank != 0) {
217 0 : *rank = k;
218 : }
219 0 : if (arguments != 0) {
220 0 : arguments->clear();
221 : }
222 0 : if (entity != 0) {
223 0 : *entity = ent;
224 : }
225 0 : return s;
226 : case codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
227 0 : if (args.size()
228 : != (dynamic_cast<
229 0 : unoidl::PolymorphicStructTypeTemplateEntity * >(ent.get())->
230 0 : getTypeParameters().size()))
231 : {
232 : throw CannotDumpException(
233 0 : "bad number of template arguments for \"" + n
234 0 : + "\" resolved from \"" + name + "\"");
235 : }
236 0 : if (nucleus != 0) {
237 0 : *nucleus = n;
238 : }
239 0 : if (rank != 0) {
240 0 : *rank = k;
241 : }
242 0 : if (arguments != 0) {
243 0 : arguments->clear();
244 0 : for (std::vector< OString >::iterator i(args.begin());
245 0 : i != args.end(); ++i)
246 : {
247 0 : arguments->push_back(b2u(*i));
248 : }
249 : }
250 0 : if (entity != 0) {
251 0 : *entity = ent;
252 : }
253 : return
254 0 : codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE;
255 : case codemaker::UnoType::SORT_SEQUENCE_TYPE:
256 : assert(false); // this cannot happen
257 : // fall through
258 : default:
259 : throw CannotDumpException(
260 0 : "unexpected \"" + n + "\" resolved from \"" + name
261 0 : + ("\"in call to TypeManager::decompose"));
262 : }
263 0 : }
264 : }
265 :
266 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|