1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_codemaker.hxx"
30 
31 #include "codemaker/dependencies.hxx"
32 
33 #include "codemaker/typemanager.hxx"
34 #include "codemaker/unotype.hxx"
35 
36 #include "osl/diagnose.h"
37 #include "registry/reader.hxx"
38 #include "rtl/string.hxx"
39 #include "rtl/textcvt.h"
40 #include "rtl/textenc.h"
41 #include "rtl/ustring.hxx"
42 #include "sal/types.h"
43 
44 #include <vector>
45 
46 using codemaker::Dependencies;
47 
48 namespace {
49 
50 struct Bad {};
51 
52 }
53 
54 Dependencies::Dependencies(
55     TypeManager const & manager, rtl::OString const & type):
56     m_voidDependency(false), m_booleanDependency(false),
57     m_byteDependency(false), m_shortDependency(false),
58     m_unsignedShortDependency(false), m_longDependency(false),
59     m_unsignedLongDependency(false), m_hyperDependency(false),
60     m_unsignedHyperDependency(false), m_floatDependency(false),
61     m_doubleDependency(false), m_charDependency(false),
62     m_stringDependency(false), m_typeDependency(false), m_anyDependency(false),
63     m_sequenceDependency(false)
64 {
65     typereg::Reader reader(manager.getTypeReader(type));
66     m_valid = reader.isValid();
67     if (m_valid) {
68         // Not everything is checked for consistency, just things that are cheap
69         // to test:
70         try {
71             RTTypeClass tc = reader.getTypeClass();
72             if (tc != RT_TYPE_SERVICE) {
73                 for (sal_Int16 i = 0; i < reader.getSuperTypeCount(); ++i) {
74                     insert(reader.getSuperTypeName(i), true);
75                 }
76             }
77             if (tc != RT_TYPE_ENUM) {
78                 {for (sal_Int16 i = 0; i < reader.getFieldCount(); ++i) {
79                     if ((reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE)
80                         == 0)
81                     {
82                         insert(reader.getFieldTypeName(i), false);
83                     }
84                 }}
85             }
86             for (sal_Int16 i = 0; i < reader.getMethodCount(); ++i) {
87                 insert(reader.getMethodReturnTypeName(i), false);
88                 for (sal_Int16 j = 0; j < reader.getMethodParameterCount(i);
89                       ++j)
90                 {
91                     if ((reader.getMethodParameterFlags(i, j) & RT_PARAM_REST)
92                         != 0)
93                     {
94                         m_sequenceDependency = true;
95                     }
96                     insert(reader.getMethodParameterTypeName(i, j), false);
97                 }
98                 for (sal_Int16 j = 0; j < reader.getMethodExceptionCount(i);
99                       ++j)
100                 {
101                     insert(reader.getMethodExceptionTypeName(i, j), false);
102                 }
103             }
104             for (sal_Int16 i = 0; i < reader.getReferenceCount(); ++i) {
105                 if (reader.getReferenceSort(i) != RT_REF_TYPE_PARAMETER) {
106                     insert(reader.getReferenceTypeName(i), false);
107                 }
108             }
109         } catch (Bad &) {
110             m_map.clear();
111             m_valid = false;
112             m_voidDependency = false;
113             m_booleanDependency = false;
114             m_byteDependency = false;
115             m_shortDependency = false;
116             m_unsignedShortDependency = false;
117             m_longDependency = false;
118             m_unsignedLongDependency = false;
119             m_hyperDependency = false;
120             m_unsignedHyperDependency = false;
121             m_floatDependency = false;
122             m_doubleDependency = false;
123             m_charDependency = false;
124             m_stringDependency = false;
125             m_typeDependency = false;
126             m_anyDependency = false;
127             m_sequenceDependency = false;
128         }
129     }
130 }
131 
132 Dependencies::~Dependencies()
133 {}
134 
135 void Dependencies::insert(rtl::OUString const & type, bool base) {
136     rtl::OString t;
137     if (!type.convertToString(
138             &t, RTL_TEXTENCODING_UTF8,
139             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
140              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
141     {
142         throw Bad();
143     }
144     insert(t, base);
145 }
146 
147 void Dependencies::insert(rtl::OString const & type, bool base) {
148     sal_Int32 rank;
149     std::vector< rtl::OString > args;
150     rtl::OString t(UnoType::decompose(type, &rank, &args));
151     if (rank > 0) {
152         m_sequenceDependency = true;
153     }
154     switch (UnoType::getSort(t)) {
155     case UnoType::SORT_VOID:
156         if (rank != 0 || !args.empty()) {
157             throw Bad();
158         }
159         m_voidDependency = true;
160         break;
161 
162     case UnoType::SORT_BOOLEAN:
163         if (!args.empty()) {
164             throw Bad();
165         }
166         m_booleanDependency = true;
167         break;
168 
169     case UnoType::SORT_BYTE:
170         if (!args.empty()) {
171             throw Bad();
172         }
173         m_byteDependency = true;
174         break;
175 
176     case UnoType::SORT_SHORT:
177         if (!args.empty()) {
178             throw Bad();
179         }
180         m_shortDependency = true;
181         break;
182 
183     case UnoType::SORT_UNSIGNED_SHORT:
184         if (!args.empty()) {
185             throw Bad();
186         }
187         m_unsignedShortDependency = true;
188         break;
189 
190     case UnoType::SORT_LONG:
191         if (!args.empty()) {
192             throw Bad();
193         }
194         m_longDependency = true;
195         break;
196 
197     case UnoType::SORT_UNSIGNED_LONG:
198         if (!args.empty()) {
199             throw Bad();
200         }
201         m_unsignedLongDependency = true;
202         break;
203 
204     case UnoType::SORT_HYPER:
205         if (!args.empty()) {
206             throw Bad();
207         }
208         m_hyperDependency = true;
209         break;
210 
211     case UnoType::SORT_UNSIGNED_HYPER:
212         if (!args.empty()) {
213             throw Bad();
214         }
215         m_unsignedHyperDependency = true;
216         break;
217 
218     case UnoType::SORT_FLOAT:
219         if (!args.empty()) {
220             throw Bad();
221         }
222         m_floatDependency = true;
223         break;
224 
225     case UnoType::SORT_DOUBLE:
226         if (!args.empty()) {
227             throw Bad();
228         }
229         m_doubleDependency = true;
230         break;
231 
232     case UnoType::SORT_CHAR:
233         if (!args.empty()) {
234             throw Bad();
235         }
236         m_charDependency = true;
237         break;
238 
239     case UnoType::SORT_STRING:
240         if (!args.empty()) {
241             throw Bad();
242         }
243         m_stringDependency = true;
244         break;
245 
246     case UnoType::SORT_TYPE:
247         if (!args.empty()) {
248             throw Bad();
249         }
250         m_typeDependency = true;
251         break;
252 
253     case UnoType::SORT_ANY:
254         if (!args.empty()) {
255             throw Bad();
256         }
257         m_anyDependency = true;
258         break;
259 
260     case UnoType::SORT_COMPLEX:
261         {
262             {for (std::vector< rtl::OString >::iterator i(args.begin());
263                   i != args.end(); ++i)
264             {
265                 insert(*i, false);
266             }}
267             Map::iterator i(m_map.find(t));
268             if (i == m_map.end()) {
269                 m_map.insert(
270                     Map::value_type(t, base ? KIND_BASE : KIND_NO_BASE));
271             } else if (base) {
272                 i->second = KIND_BASE;
273             }
274             break;
275         }
276 
277     default:
278         OSL_ASSERT(false);
279         break;
280     }
281 }
282