1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_codemaker.hxx" 26 27 #include "sal/config.h" 28 29 #include "codemaker/codemaker.hxx" 30 31 #include "codemaker/options.hxx" 32 #include "codemaker/typemanager.hxx" 33 #include "codemaker/unotype.hxx" 34 35 #include "osl/diagnose.h" 36 #include "registry/reader.hxx" 37 #include "registry/types.h" 38 #include "rtl/strbuf.h" 39 #include "rtl/string.h" 40 #include "rtl/string.hxx" 41 #include "rtl/ustring.hxx" 42 #include "sal/types.h" 43 44 #include <vector> 45 46 namespace { 47 48 void checkNoTypeArguments(std::vector< rtl::OString > const & arguments) { 49 if (!arguments.empty()) { 50 throw CannotDumpException( 51 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information"))); 52 //TODO 53 } 54 } 55 56 } 57 58 namespace codemaker { 59 60 rtl::OString convertString(rtl::OUString const & string) { 61 rtl::OString s; 62 if (!string.convertToString( 63 &s, RTL_TEXTENCODING_UTF8, 64 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR 65 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) 66 { 67 throw CannotDumpException( 68 rtl::OString( 69 RTL_CONSTASCII_STRINGPARAM( 70 "Failure converting string from UTF-16 to UTF-8"))); 71 } 72 return s; 73 } 74 75 rtl::OString errorMsg(rtl::OString const & desc, rtl::OString const & type) { 76 rtl::OStringBuffer msg(128); 77 msg.append(desc); 78 msg.append(type); 79 return msg.makeStringAndClear(); 80 } 81 82 codemaker::UnoType::Sort decomposeAndResolve( 83 TypeManager const & manager, rtl::OString const & type, 84 bool resolveTypedefs, bool allowVoid, bool allowExtraEntities, 85 RTTypeClass * typeClass, rtl::OString * name, sal_Int32 * rank, 86 std::vector< rtl::OString > * arguments) 87 { 88 OSL_ASSERT(typeClass != 0 && name != 0 && rank != 0 && arguments != 0); 89 *rank = 0; 90 for (rtl::OString t(type);;) { 91 sal_Int32 n = 0; 92 *name = codemaker::UnoType::decompose(t, &n, arguments); 93 if (n > SAL_MAX_INT32 - *rank) { 94 throw CannotDumpException( 95 errorMsg(rtl::OString( 96 RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), 97 type)); 98 //TODO 99 } 100 *rank += n; 101 if (n > 0) { 102 allowVoid = false; 103 allowExtraEntities = false; 104 } 105 codemaker::UnoType::Sort sort = codemaker::UnoType::getSort(*name); 106 switch (sort) { 107 case codemaker::UnoType::SORT_VOID: 108 if (!allowVoid) { 109 throw CannotDumpException( 110 errorMsg(rtl::OString( 111 RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), 112 type)); 113 //TODO 114 } 115 default: 116 checkNoTypeArguments(*arguments); 117 *typeClass = RT_TYPE_INVALID; 118 return sort; 119 120 case codemaker::UnoType::SORT_COMPLEX: 121 typereg::Reader reader(manager.getTypeReader(*name)); 122 *typeClass = reader.getTypeClass(); 123 switch (*typeClass) { 124 case RT_TYPE_ENUM: 125 case RT_TYPE_INTERFACE: 126 checkNoTypeArguments(*arguments); 127 return sort; 128 129 case RT_TYPE_STRUCT: 130 if (!(allowExtraEntities && arguments->empty()) 131 && (arguments->size() > SAL_MAX_UINT16 132 || (static_cast< sal_uInt16 >(arguments->size()) 133 != reader.getReferenceCount()))) 134 { 135 throw CannotDumpException( 136 errorMsg(rtl::OString( 137 RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), 138 type)); 139 //TODO 140 } 141 return sort; 142 143 case RT_TYPE_MODULE: 144 case RT_TYPE_EXCEPTION: 145 case RT_TYPE_SERVICE: 146 case RT_TYPE_SINGLETON: 147 case RT_TYPE_CONSTANTS: 148 if (!allowExtraEntities) { 149 throw CannotDumpException( 150 errorMsg(rtl::OString( 151 RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), 152 type)); 153 //TODO 154 } 155 checkNoTypeArguments(*arguments); 156 //TODO: check reader for consistency 157 return sort; 158 159 case RT_TYPE_TYPEDEF: 160 checkNoTypeArguments(*arguments); 161 if (reader.getSuperTypeCount() == 1 162 && reader.getFieldCount() == 0 163 && reader.getMethodCount() == 0 164 && reader.getReferenceCount() == 0) 165 { 166 if (resolveTypedefs) { 167 t = convertString(reader.getSuperTypeName(0)); 168 continue; 169 } else { 170 return sort; 171 } 172 } 173 default: 174 throw CannotDumpException( 175 errorMsg(rtl::OString( 176 RTL_CONSTASCII_STRINGPARAM("Bad type information: ")), 177 type)); 178 //TODO 179 } 180 } 181 } 182 } 183 184 } 185