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