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 15 : TypeManager::TypeManager(): manager_(new unoidl::Manager) {}
33 :
34 30 : TypeManager::~TypeManager() {}
35 :
36 31 : void TypeManager::loadProvider(OUString const & uri, bool primary) {
37 : rtl::Reference< unoidl::Provider > prov(
38 31 : unoidl::loadProvider(manager_, uri));
39 31 : manager_->addProvider(prov);
40 31 : if (primary) {
41 16 : primaryProviders_.push_back(prov);
42 31 : }
43 31 : }
44 :
45 16124 : bool TypeManager::foundAtPrimaryProvider(OUString const & name) const {
46 16124 : if (name.isEmpty()) {
47 15 : return !primaryProviders_.empty();
48 : }
49 51279 : for (std::vector< rtl::Reference< unoidl::Provider > >::const_iterator i(
50 16109 : primaryProviders_.begin());
51 34186 : i != primaryProviders_.end(); ++i)
52 : {
53 16133 : if ((*i)->findEntity(name).is()) {
54 15149 : return true;
55 : }
56 : }
57 960 : if (!manager_->findEntity(name).is()) {
58 0 : throw CannotDumpException("Unknown entity '" + name + "'");
59 : }
60 960 : return false;
61 : }
62 :
63 379558 : codemaker::UnoType::Sort TypeManager::getSort(
64 : OUString const & name, rtl::Reference< unoidl::Entity > * entity,
65 : rtl::Reference< unoidl::MapCursor > * cursor) const
66 : {
67 379558 : if (name.isEmpty()) {
68 15 : if (cursor != 0) {
69 15 : *cursor = manager_->createCursor("");
70 : }
71 15 : return codemaker::UnoType::SORT_MODULE;
72 : }
73 379543 : if (name == "void") {
74 23593 : return codemaker::UnoType::SORT_VOID;
75 : }
76 355950 : if (name == "boolean") {
77 17106 : return codemaker::UnoType::SORT_BOOLEAN;
78 : }
79 338844 : if (name == "byte") {
80 2617 : return codemaker::UnoType::SORT_BYTE;
81 : }
82 336227 : if (name == "short") {
83 11298 : return codemaker::UnoType::SORT_SHORT;
84 : }
85 324929 : if (name == "unsigned short") {
86 923 : return codemaker::UnoType::SORT_UNSIGNED_SHORT;
87 : }
88 324006 : if (name == "long") {
89 29180 : return codemaker::UnoType::SORT_LONG;
90 : }
91 294826 : if (name == "unsigned long") {
92 793 : return codemaker::UnoType::SORT_UNSIGNED_LONG;
93 : }
94 294033 : if (name == "hyper") {
95 1265 : return codemaker::UnoType::SORT_HYPER;
96 : }
97 292768 : if (name == "unsigned hyper") {
98 131 : return codemaker::UnoType::SORT_UNSIGNED_HYPER;
99 : }
100 292637 : if (name == "float") {
101 864 : return codemaker::UnoType::SORT_FLOAT;
102 : }
103 291773 : if (name == "double") {
104 5940 : return codemaker::UnoType::SORT_DOUBLE;
105 : }
106 285833 : if (name == "char") {
107 586 : return codemaker::UnoType::SORT_CHAR;
108 : }
109 285247 : if (name == "string") {
110 41902 : return codemaker::UnoType::SORT_STRING;
111 : }
112 243345 : if (name == "type") {
113 810 : return codemaker::UnoType::SORT_TYPE;
114 : }
115 242535 : if (name == "any") {
116 12449 : return codemaker::UnoType::SORT_ANY;
117 : }
118 230086 : if (name.startsWith("[")) {
119 3349 : return codemaker::UnoType::SORT_SEQUENCE_TYPE;
120 : }
121 226737 : if (name.indexOf('<') != -1) {
122 397 : return codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE;
123 : }
124 226340 : rtl::Reference< unoidl::Entity > ent(manager_->findEntity(name));
125 226340 : if (!ent.is()) {
126 0 : throw CannotDumpException("Unknown entity '" + name + "'");
127 : }
128 226340 : if (entity != 0) {
129 113347 : *entity = ent;
130 : }
131 226340 : switch (ent->getSort()) {
132 : case unoidl::Entity::SORT_MODULE:
133 454 : if (cursor != 0) {
134 454 : *cursor = manager_->createCursor(name);
135 : }
136 454 : return codemaker::UnoType::SORT_MODULE;
137 : case unoidl::Entity::SORT_ENUM_TYPE:
138 10665 : return codemaker::UnoType::SORT_ENUM_TYPE;
139 : case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
140 34703 : return codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE;
141 : case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
142 722 : return codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE;
143 : case unoidl::Entity::SORT_EXCEPTION_TYPE:
144 46987 : return codemaker::UnoType::SORT_EXCEPTION_TYPE;
145 : case unoidl::Entity::SORT_INTERFACE_TYPE:
146 119968 : return codemaker::UnoType::SORT_INTERFACE_TYPE;
147 : case unoidl::Entity::SORT_TYPEDEF:
148 2267 : return codemaker::UnoType::SORT_TYPEDEF;
149 : case unoidl::Entity::SORT_CONSTANT_GROUP:
150 4959 : return codemaker::UnoType::SORT_CONSTANT_GROUP;
151 : case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
152 2061 : return codemaker::UnoType::SORT_SINGLE_INTERFACE_BASED_SERVICE;
153 : case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
154 3096 : return codemaker::UnoType::SORT_ACCUMULATION_BASED_SERVICE;
155 : case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
156 457 : return codemaker::UnoType::SORT_INTERFACE_BASED_SINGLETON;
157 : case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
158 1 : return codemaker::UnoType::SORT_SERVICE_BASED_SINGLETON;
159 : default:
160 0 : for (;;) { std::abort(); } // this cannot happen
161 226340 : }
162 : }
163 :
164 32963 : 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 32963 : std::vector< OString > args;
171 65926 : OUString n = b2u(codemaker::UnoType::decompose(u2b(name), &k, &args));
172 : for (;;) {
173 33289 : rtl::Reference< unoidl::Entity > ent;
174 33289 : codemaker::UnoType::Sort s = getSort(n, &ent);
175 66578 : if (args.empty()
176 33289 : != (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 33289 : switch (s) {
183 : case codemaker::UnoType::SORT_TYPEDEF:
184 331 : if (resolveTypedefs) {
185 652 : n = dynamic_cast< unoidl::TypedefEntity * >(ent.get())->
186 326 : getType();
187 750 : while (n.startsWith("[]")) {
188 98 : ++k; //TODO: overflow
189 98 : n = n.copy(std::strlen("[]"));
190 : }
191 326 : 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 32764 : if (nucleus != 0) {
214 32764 : *nucleus = n;
215 : }
216 32764 : if (rank != 0) {
217 32745 : *rank = k;
218 : }
219 32764 : if (arguments != 0) {
220 27947 : arguments->clear();
221 : }
222 32764 : if (entity != 0) {
223 1755 : *entity = ent;
224 : }
225 32764 : return s;
226 : case codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
227 398 : if (args.size()
228 : != (dynamic_cast<
229 199 : unoidl::PolymorphicStructTypeTemplateEntity * >(ent.get())->
230 199 : getTypeParameters().size()))
231 : {
232 : throw CannotDumpException(
233 0 : "bad number of template arguments for \"" + n
234 0 : + "\" resolved from \"" + name + "\"");
235 : }
236 199 : if (nucleus != 0) {
237 199 : *nucleus = n;
238 : }
239 199 : if (rank != 0) {
240 199 : *rank = k;
241 : }
242 199 : if (arguments != 0) {
243 192 : arguments->clear();
244 1314 : for (std::vector< OString >::iterator i(args.begin());
245 876 : i != args.end(); ++i)
246 : {
247 246 : arguments->push_back(b2u(*i));
248 : }
249 : }
250 199 : if (entity != 0) {
251 2 : *entity = ent;
252 : }
253 : return
254 199 : 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 33289 : }
264 : }
265 :
266 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|