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 #include "pyuno_impl.hxx" 25 26 #include <time.h> 27 #include <osl/thread.h> 28 29 #include <typelib/typedescription.hxx> 30 31 #include <rtl/strbuf.hxx> 32 #include <rtl/ustrbuf.hxx> 33 #include <osl/time.h> 34 35 #include <com/sun/star/beans/XMaterialHolder.hpp> 36 37 using rtl::OUStringToOString; 38 using rtl::OUString; 39 using rtl::OString; 40 using rtl::OStringBuffer; 41 using rtl::OUStringBuffer; 42 43 44 using com::sun::star::uno::TypeDescription; 45 using com::sun::star::uno::Sequence; 46 using com::sun::star::uno::Reference; 47 using com::sun::star::uno::XInterface; 48 using com::sun::star::uno::Any; 49 using com::sun::star::uno::Type; 50 using com::sun::star::uno::UNO_QUERY; 51 using com::sun::star::uno::TypeClass; 52 using com::sun::star::uno::RuntimeException; 53 using com::sun::star::uno::XComponentContext; 54 using com::sun::star::lang::XSingleServiceFactory; 55 using com::sun::star::script::XTypeConverter; 56 using com::sun::star::beans::XMaterialHolder; 57 58 #define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) 59 namespace pyuno 60 { 61 PyRef ustring2PyUnicode( const OUString & str ) 62 { 63 PyRef ret; 64 65 #if Py_UNICODE_SIZE == 2 66 // YD force conversion since python/2 uses wchar_t 67 ret = PyRef( PyUnicode_FromUnicode( (const Py_UNICODE*)str.getStr(), str.getLength() ), SAL_NO_ACQUIRE ); 68 #else 69 OString sUtf8(OUStringToOString(str, RTL_TEXTENCODING_UTF8)); 70 ret = PyRef( PyUnicode_DecodeUTF8( sUtf8.getStr(), sUtf8.getLength(), NULL) , SAL_NO_ACQUIRE ); 71 #endif 72 return ret; 73 } 74 75 PyRef ustring2PyString( const OUString &str ) 76 { 77 OString o = OUStringToOString( str, osl_getThreadTextEncoding() ); 78 return PyRef( PyBytes_FromString( o.getStr() ), SAL_NO_ACQUIRE ); 79 } 80 81 OUString pyString2ustring( PyObject *pystr ) 82 { 83 OUString ret; 84 if( PyUnicode_Check( pystr ) ) 85 { 86 #if Py_UNICODE_SIZE == 2 87 ret = OUString( (sal_Unicode * ) PyUnicode_AS_UNICODE( pystr ) ); 88 #else 89 #if PY_VERSION_HEX >= 0x03030000 90 Py_ssize_t size; 91 char *pUtf8 = PyUnicode_AsUTF8AndSize(pystr, &size); 92 ret = OUString(pUtf8, size, RTL_TEXTENCODING_UTF8); 93 #else 94 PyObject* pUtf8 = PyUnicode_AsUTF8String(pystr); 95 ret = OUString(PyBytes_AsString(pUtf8), PyBytes_Size(pUtf8), RTL_TEXTENCODING_UTF8); 96 Py_DECREF(pUtf8); 97 #endif 98 #endif 99 } 100 else 101 { 102 char *name = PyBytes_AsString(pystr ); 103 ret = OUString( name, strlen(name), osl_getThreadTextEncoding() ); 104 } 105 return ret; 106 } 107 108 PyRef getObjectFromUnoModule( const Runtime &runtime, const char * func ) 109 throw ( RuntimeException ) 110 { 111 PyRef object(PyDict_GetItemString( runtime.getImpl()->cargo->getUnoModule().get(), (char*)func ) ); 112 if( !object.is() ) 113 { 114 OUStringBuffer buf; 115 buf.appendAscii( "couldn't find core function " ); 116 buf.appendAscii( func ); 117 throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >()); 118 } 119 return object; 120 } 121 122 123 //------------------------------------------------------------------------------------ 124 // Logging 125 //------------------------------------------------------------------------------------ 126 127 bool isLog( RuntimeCargo * cargo, sal_Int32 loglevel ) 128 { 129 return cargo && cargo->logFile && loglevel <= cargo->logLevel; 130 } 131 132 void log( RuntimeCargo * cargo, sal_Int32 level, const rtl::OUString &logString ) 133 { 134 log( cargo, level, OUStringToOString( logString, osl_getThreadTextEncoding() ).getStr() ); 135 } 136 137 void log( RuntimeCargo * cargo, sal_Int32 level, const char *str ) 138 { 139 if( isLog( cargo, level ) ) 140 { 141 static const char *strLevel[] = { "NONE", "CALL", "ARGS" }; 142 143 TimeValue systemTime; 144 TimeValue localTime; 145 oslDateTime localDateTime; 146 147 osl_getSystemTime( &systemTime ); 148 osl_getLocalTimeFromSystemTime( &systemTime, &localTime ); 149 osl_getDateTimeFromTimeValue( &localTime, &localDateTime ); 150 151 fprintf( cargo->logFile, 152 "%4i-%02i-%02i %02i:%02i:%02i,%03lu [%s,tid %ld]: %s\n", 153 localDateTime.Year, 154 localDateTime.Month, 155 localDateTime.Day, 156 localDateTime.Hours, 157 localDateTime.Minutes, 158 localDateTime.Seconds, 159 sal::static_int_cast< unsigned long >( 160 localDateTime.NanoSeconds/1000000), 161 strLevel[level], 162 sal::static_int_cast< long >( 163 (sal_Int32) osl_getThreadIdentifier( 0)), 164 str ); 165 } 166 } 167 168 namespace { 169 170 void appendPointer(rtl::OUStringBuffer & buffer, void * pointer) { 171 buffer.append( 172 sal::static_int_cast< sal_Int64 >( 173 reinterpret_cast< sal_IntPtr >(pointer)), 174 16); 175 } 176 177 } 178 179 void logException( RuntimeCargo *cargo, const char *intro, 180 void * ptr, const rtl::OUString &aFunctionName, 181 const void * data, const com::sun::star::uno::Type & type ) 182 { 183 if( isLog( cargo, LogLevel::CALL ) ) 184 { 185 rtl::OUStringBuffer buf( 128 ); 186 buf.appendAscii( intro ); 187 appendPointer(buf, ptr); 188 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("].") ); 189 buf.append( aFunctionName ); 190 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) ); 191 buf.append( 192 val2str( data, type.getTypeLibType(), VAL2STR_MODE_SHALLOW ) ); 193 log( cargo,LogLevel::CALL, buf.makeStringAndClear() ); 194 } 195 196 } 197 198 void logReply( 199 RuntimeCargo *cargo, 200 const char *intro, 201 void * ptr, 202 const rtl::OUString & aFunctionName, 203 const Any &returnValue, 204 const Sequence< Any > & aParams ) 205 { 206 rtl::OUStringBuffer buf( 128 ); 207 buf.appendAscii( intro ); 208 appendPointer(buf, ptr); 209 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("].") ); 210 buf.append( aFunctionName ); 211 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("()=") ); 212 if( isLog( cargo, LogLevel::ARGS ) ) 213 { 214 buf.append( 215 val2str( returnValue.getValue(), returnValue.getValueTypeRef(), VAL2STR_MODE_SHALLOW) ); 216 for( int i = 0; i < aParams.getLength() ; i ++ ) 217 { 218 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", " ) ); 219 buf.append( 220 val2str( aParams[i].getValue(), aParams[i].getValueTypeRef(), VAL2STR_MODE_SHALLOW) ); 221 } 222 } 223 log( cargo,LogLevel::CALL, buf.makeStringAndClear() ); 224 225 } 226 227 void logCall( RuntimeCargo *cargo, const char *intro, 228 void * ptr, const rtl::OUString & aFunctionName, 229 const Sequence< Any > & aParams ) 230 { 231 rtl::OUStringBuffer buf( 128 ); 232 buf.appendAscii( intro ); 233 appendPointer(buf, ptr); 234 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("].") ); 235 buf.append( aFunctionName ); 236 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("(") ); 237 if( isLog( cargo, LogLevel::ARGS ) ) 238 { 239 for( int i = 0; i < aParams.getLength() ; i ++ ) 240 { 241 if( i > 0 ) 242 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", " ) ); 243 buf.append( 244 val2str( aParams[i].getValue(), aParams[i].getValueTypeRef(), VAL2STR_MODE_SHALLOW) ); 245 } 246 } 247 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") ); 248 log( cargo,LogLevel::CALL, buf.makeStringAndClear() ); 249 } 250 251 252 } 253