# Copyright (c) 2013 CEF Python, see the Authors file. # All rights reserved. Licensed under BSD 3-clause license. # Project website: https://github.com/cztomczak/cefpython # CefListValue->SetXxxx() functions need first param to be be cast # to (int) because GetSize() returns size_t and generates a warning # when compiling on VS2008 for x64 platform. Issue reported here: # https://github.com/cztomczak/cefpython/issues/165 # Here in pyx you also need to convert Py_ssize_t returned by # enumerate(), to an int. include "cefpython.pyx" # ----------------------------------------------------------------------------- # CEF values to Python values # ----------------------------------------------------------------------------- cdef object CheckForCefPythonMessageHash(CefRefPtr[CefBrowser] cefBrowser, py_string pyString): # A javascript callback from the Renderer process is sent as a string. # TODO: this could be sent using CefBinaryNamedString in the future, # see this topic "Sending custom data types using process messaging": # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10881 cdef py_string cefPythonMessageHash = "####cefpython####" cdef JavascriptCallback jsCallback cdef py_string jsonData cdef object message if pyString.startswith(cefPythonMessageHash): jsonData = pyString[len(cefPythonMessageHash):] message = json.loads(jsonData) if message and type(message) == dict and ("what" in message) \ and message["what"] == "javascript-callback": jsCallback = CreateJavascriptCallback( message["callbackId"], cefBrowser, message["frameId"], message["functionName"]) return jsCallback return pyString cdef list CefListValueToPyList( CefRefPtr[CefBrowser] cefBrowser, CefRefPtr[CefListValue] cefListValue, int nestingLevel=0): assert cefListValue.get().IsValid(), "cefListValue is invalid" if nestingLevel > 8: raise Exception("CefListValueToPyList(): max nesting level (8)" " exceeded") cdef int index cdef int size = int(cefListValue.get().GetSize()) cdef cef_types.cef_value_type_t valueType cdef list ret = [] cdef CefRefPtr[CefBinaryValue] binaryValue cdef uint32 uint32_value cdef int64 int64_value cdef object originallyString for index in range(0, size): valueType = cefListValue.get().GetType(index) if valueType == cef_types.VTYPE_NULL: ret.append(None) elif valueType == cef_types.VTYPE_BOOL: ret.append(bool(cefListValue.get().GetBool(index))) elif valueType == cef_types.VTYPE_INT: ret.append(cefListValue.get().GetInt(index)) elif valueType == cef_types.VTYPE_DOUBLE: ret.append(cefListValue.get().GetDouble(index)) elif valueType == cef_types.VTYPE_STRING: originallyString = CefToPyString( cefListValue.get().GetString(index)) originallyString = CheckForCefPythonMessageHash(cefBrowser, originallyString) ret.append(originallyString) elif valueType == cef_types.VTYPE_DICTIONARY: ret.append(CefDictionaryValueToPyDict( cefBrowser, cefListValue.get().GetDictionary(index), nestingLevel + 1)) elif valueType == cef_types.VTYPE_LIST: ret.append(CefListValueToPyList( cefBrowser, cefListValue.get().GetList(index), nestingLevel + 1)) elif valueType == cef_types.VTYPE_BINARY: binaryValue = cefListValue.get().GetBinary(index) if binaryValue.get().GetSize() == sizeof(uint32_value): binaryValue.get().GetData( &uint32_value, sizeof(uint32_value), 0) ret.append(uint32_value) elif binaryValue.get().GetSize() == sizeof(int64_value): binaryValue.get().GetData( &int64_value, sizeof(int64_value), 0) ret.append(int64_value) else: raise Exception("Unknown binary value, size=%s" % \ binaryValue.get().GetSize()) else: raise Exception("Unknown value type=%s" % valueType) return ret cdef dict CefDictionaryValueToPyDict( CefRefPtr[CefBrowser] cefBrowser, CefRefPtr[CefDictionaryValue] cefDictionaryValue, int nestingLevel=0): assert cefDictionaryValue.get().IsValid(), "cefDictionaryValue is invalid" if nestingLevel > 8: raise Exception("CefDictionaryValueToPyDict(): max nesting level (8)" " exceeded") cdef cpp_vector[CefString] keyList cefDictionaryValue.get().GetKeys(keyList) cdef cef_types.cef_value_type_t valueType cdef dict ret = {} cdef cpp_vector[CefString].iterator iterator = keyList.begin() cdef CefString cefKey cdef py_string pyKey cdef CefRefPtr[CefBinaryValue] binaryValue cdef uint32 uint32_value cdef int64 int64_value cdef object originallyString while iterator != keyList.end(): cefKey = deref(iterator) pyKey = CefToPyString(cefKey) preinc(iterator) valueType = cefDictionaryValue.get().GetType(cefKey) if valueType == cef_types.VTYPE_NULL: ret[pyKey] = None elif valueType == cef_types.VTYPE_BOOL: ret[pyKey] = bool(cefDictionaryValue.get().GetBool(cefKey)) elif valueType == cef_types.VTYPE_INT: ret[pyKey] = cefDictionaryValue.get().GetInt(cefKey) elif valueType == cef_types.VTYPE_DOUBLE: ret[pyKey] = cefDictionaryValue.get().GetDouble(cefKey) elif valueType == cef_types.VTYPE_STRING: originallyString = CefToPyString( cefDictionaryValue.get().GetString(cefKey)) originallyString = CheckForCefPythonMessageHash(cefBrowser, originallyString) ret[pyKey] = originallyString elif valueType == cef_types.VTYPE_DICTIONARY: ret[pyKey] = CefDictionaryValueToPyDict( cefBrowser, cefDictionaryValue.get().GetDictionary(cefKey), nestingLevel + 1) elif valueType == cef_types.VTYPE_LIST: ret[pyKey] = CefListValueToPyList( cefBrowser, cefDictionaryValue.get().GetList(cefKey), nestingLevel + 1) elif valueType == cef_types.VTYPE_BINARY: binaryValue = cefDictionaryValue.get().GetBinary(cefKey) if binaryValue.get().GetSize() == sizeof(uint32_value): binaryValue.get().GetData( &uint32_value, sizeof(uint32_value), 0) ret[pyKey] = uint32_value elif binaryValue.get().GetSize() == sizeof(int64_value): binaryValue.get().GetData( &int64_value, sizeof(int64_value), 0) ret[pyKey] = int64_value else: raise Exception("Unknown binary value, size=%s" % \ binaryValue.get().GetSize()) else: raise Exception("Unknown value type = %s" % valueType) return ret # ----------------------------------------------------------------------------- # Python values to CEF values # ----------------------------------------------------------------------------- cdef CefRefPtr[CefListValue] PyListToCefListValue( int browserId, object frameId, list pyList, int nestingLevel=0) except *: if nestingLevel > 8: raise Exception("PyListToCefListValue(): max nesting level (8)" " exceeded") cdef type valueType cdef CefRefPtr[CefListValue] ret = CefListValue_Create() cdef CefRefPtr[CefBinaryValue] binaryValue cdef int index for index_size_t, value in enumerate(pyList): index = int(index_size_t) valueType = type(value) if valueType == type(None): ret.get().SetNull(index) elif valueType == bool: ret.get().SetBool(index, bool(value)) elif valueType == int: ret.get().SetInt(index, int(value)) elif valueType == long: # Int32 range is -2147483648..2147483647, we've increased the # minimum size by one as Cython was throwing a warning: # "unary minus operator applied to unsigned type, result still # unsigned". if -2147483647 SendProcessMessage(). if nestingLevel > 8: raise Exception("PyListToCefListValue(): max nesting level (8)" " exceeded") cdef type valueType cdef CefRefPtr[CefListValue] newCefListValue cdef int index for index_size_t, value in enumerate(pyList): index = int(index_size_t) valueType = type(value) if valueType == type(None): cefListValue.get().SetNull(index) elif valueType == bool: cefListValue.get().SetBool(index, bool(value)) elif valueType == int: cefListValue.get().SetInt(index, int(value)) elif valueType == long: # Int32 range is -2147483648..2147483647, we've increased the # minimum size by one as Cython was throwing a warning: # "unary minus operator applied to unsigned type, result still # unsigned". if -2147483647 8: raise Exception("PyDictToCefDictionaryValue(): max nesting level (8)" " exceeded") cdef type valueType cdef CefRefPtr[CefDictionaryValue] ret = CefDictionaryValue_Create() cdef CefString cefKey cdef object value for pyKey in pyDict: value = pyDict[pyKey] valueType = type(value) PyToCefString(pyKey, cefKey) if valueType == type(None): ret.get().SetNull(cefKey) elif valueType == bool: ret.get().SetBool(cefKey, bool(value)) elif valueType == int: ret.get().SetInt(cefKey, int(value)) elif valueType == long: # Int32 range is -2147483648..2147483647, we've increased the # minimum size by one as Cython was throwing a warning: # "unary minus operator applied to unsigned type, result still # unsigned". if -2147483647