xref: /trunk/main/codemaker/source/codemaker/codemaker.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 "sal/config.h"
32 
33 #include "codemaker/codemaker.hxx"
34 
35 #include "codemaker/options.hxx"
36 #include "codemaker/typemanager.hxx"
37 #include "codemaker/unotype.hxx"
38 
39 #include "osl/diagnose.h"
40 #include "registry/reader.hxx"
41 #include "registry/types.h"
42 #include "rtl/strbuf.h"
43 #include "rtl/string.h"
44 #include "rtl/string.hxx"
45 #include "rtl/ustring.hxx"
46 #include "sal/types.h"
47 
48 #include <vector>
49 
50 namespace {
51 
52 void checkNoTypeArguments(std::vector< rtl::OString > const & arguments) {
53     if (!arguments.empty()) {
54         throw CannotDumpException(
55             rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
56             //TODO
57     }
58 }
59 
60 }
61 
62 namespace codemaker {
63 
64 rtl::OString convertString(rtl::OUString const & string) {
65     rtl::OString s;
66     if (!string.convertToString(
67             &s, RTL_TEXTENCODING_UTF8,
68             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
69              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
70     {
71         throw CannotDumpException(
72             rtl::OString(
73                 RTL_CONSTASCII_STRINGPARAM(
74                     "Failure converting string from UTF-16 to UTF-8")));
75     }
76     return s;
77 }
78 
79 rtl::OString errorMsg(rtl::OString const & desc, rtl::OString const & type) {
80     rtl::OStringBuffer msg(128);
81     msg.append(desc);
82     msg.append(type);
83     return msg.makeStringAndClear();
84 }
85 
86 codemaker::UnoType::Sort decomposeAndResolve(
87     TypeManager const & manager, rtl::OString const & type,
88     bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
89     RTTypeClass * typeClass, rtl::OString * name, sal_Int32 * rank,
90     std::vector< rtl::OString > * arguments)
91 {
92     OSL_ASSERT(typeClass != 0 && name != 0 && rank != 0 && arguments != 0);
93     *rank = 0;
94     for (rtl::OString t(type);;) {
95         sal_Int32 n = 0;
96         *name = codemaker::UnoType::decompose(t, &n, arguments);
97         if (n > SAL_MAX_INT32 - *rank) {
98             throw CannotDumpException(
99                 errorMsg(rtl::OString(
100                     RTL_CONSTASCII_STRINGPARAM("Bad type information: ")),
101                     type));
102             //TODO
103         }
104         *rank += n;
105         if (n > 0) {
106             allowVoid = false;
107             allowExtraEntities = false;
108         }
109         codemaker::UnoType::Sort sort = codemaker::UnoType::getSort(*name);
110         switch (sort) {
111         case codemaker::UnoType::SORT_VOID:
112             if (!allowVoid) {
113                 throw CannotDumpException(
114                     errorMsg(rtl::OString(
115                         RTL_CONSTASCII_STRINGPARAM("Bad type information: ")),
116                         type));
117                 //TODO
118             }
119         default:
120             checkNoTypeArguments(*arguments);
121             *typeClass = RT_TYPE_INVALID;
122             return sort;
123 
124         case codemaker::UnoType::SORT_COMPLEX:
125             typereg::Reader reader(manager.getTypeReader(*name));
126             *typeClass = reader.getTypeClass();
127             switch (*typeClass) {
128             case RT_TYPE_ENUM:
129             case RT_TYPE_INTERFACE:
130                 checkNoTypeArguments(*arguments);
131                 return sort;
132 
133             case RT_TYPE_STRUCT:
134                 if (!(allowExtraEntities && arguments->empty())
135                     && (arguments->size() > SAL_MAX_UINT16
136                         || (static_cast< sal_uInt16 >(arguments->size())
137                             != reader.getReferenceCount())))
138                 {
139                     throw CannotDumpException(
140                         errorMsg(rtl::OString(
141                             RTL_CONSTASCII_STRINGPARAM("Bad type information: ")),
142                             type));
143                     //TODO
144                 }
145                 return sort;
146 
147             case RT_TYPE_MODULE:
148             case RT_TYPE_EXCEPTION:
149             case RT_TYPE_SERVICE:
150             case RT_TYPE_SINGLETON:
151             case RT_TYPE_CONSTANTS:
152                 if (!allowExtraEntities) {
153                     throw CannotDumpException(
154                         errorMsg(rtl::OString(
155                             RTL_CONSTASCII_STRINGPARAM("Bad type information: ")),
156                             type));
157                     //TODO
158                 }
159                 checkNoTypeArguments(*arguments);
160                 //TODO: check reader for consistency
161                 return sort;
162 
163             case RT_TYPE_TYPEDEF:
164                 checkNoTypeArguments(*arguments);
165                 if (reader.getSuperTypeCount() == 1
166                     && reader.getFieldCount() == 0
167                     && reader.getMethodCount() == 0
168                     && reader.getReferenceCount() == 0)
169                 {
170                     if (resolveTypedefs) {
171                         t = convertString(reader.getSuperTypeName(0));
172                         continue;
173                     } else {
174                         return sort;
175                     }
176                 }
177             default:
178                 throw CannotDumpException(
179                     errorMsg(rtl::OString(
180                         RTL_CONSTASCII_STRINGPARAM("Bad type information: ")),
181                         type));
182                 //TODO
183             }
184         }
185     }
186 }
187 
188 }
189