""" This converter works with classes protected by a namespace with SWIG pointers (Python strings). To use it to wrap classes in a C++ namespace called "ft", use the following: class ft_converter(cpp_namespace_converter): namespace = 'ft::' """ from __future__ import absolute_import, print_function from weave import common_info from weave import base_info from weave.base_spec import base_converter cpp_support_template = \ """ static %(cpp_struct)s* convert_to_%(cpp_clean_struct)s(PyObject* py_obj,char* name) { %(cpp_struct)s *cpp_ptr = 0; char* str = PyString_AsString(py_obj); if (!str) handle_conversion_error(py_obj,"%(cpp_struct)s", name); // work on this error reporting... //std::cout << "in:" << name << " " py_obj << std::endl; if (SWIG_GetPtr(str,(void **) &cpp_ptr,"_%(cpp_struct)s_p")) { handle_conversion_error(py_obj,"%(cpp_struct)s", name); } //std::cout << "out:" << name << " " << str << std::endl; return cpp_ptr; } static %(cpp_struct)s* py_to_%(cpp_clean_struct)s(PyObject* py_obj,char* name) { %(cpp_struct)s *cpp_ptr; char* str = PyString_AsString(py_obj); if (!str) handle_conversion_error(py_obj,"%(cpp_struct)s", name); // work on this error reporting... if (SWIG_GetPtr(str,(void **) &cpp_ptr,"_%(cpp_struct)s_p")) { handle_conversion_error(py_obj,"%(cpp_struct)s", name); } return cpp_ptr; } std::string %(cpp_clean_struct)s_to_py( %(cpp_struct)s* cpp_ptr) { char ptr_string[%(ptr_string_len)s]; SWIG_MakePtr(ptr_string, cpp_ptr, "_%(cpp_struct)s_p"); return std::string(ptr_string); } """ class cpp_namespace_converter(base_converter): _build_information = [common_info.swig_info()] def __init__(self,class_name=None): self.type_name = 'unknown cpp_object' self.name = 'no name' if class_name: # customize support_code for whatever type I was handed. clean_name = class_name.replace('::','_') clean_name = clean_name.replace('<','_') clean_name = clean_name.replace('>','_') clean_name = clean_name.replace(' ','_') # should be enough for 64 bit machines str_len = len(clean_name) + 20 vals = {'cpp_struct': class_name, 'cpp_clean_struct': clean_name, 'ptr_string_len': str_len} specialized_support = cpp_support_template % vals custom = base_info.base_info() custom._support_code = [specialized_support] self._build_information = self._build_information + [custom] self.type_name = class_name def type_match(self,value): try: cpp_ident = value.split('_')[2] if self.namespace in cpp_ident: return 1 except: pass return 0 def type_spec(self,name,value): # factory ptr_fields = value.split('_') class_name = '_'.join(ptr_fields[2:-1]) new_spec = self.__class__(class_name) new_spec.name = name return new_spec def declaration_code(self,inline=0): type = self.type_name clean_type = type.replace('::','_') name = self.name var_name = self.retrieve_py_variable(inline) template = '%(type)s *%(name)s = '\ 'convert_to_%(clean_type)s(%(var_name)s,"%(name)s");\n' code = template % locals() return code def __repr__(self): msg = "(%s:: name: %s)" % (self.type_name,self.name) return msg def __cmp__(self,other): #only works for equal return cmp(self.name,other.name) or \ cmp(self.__class__, other.__class__) or \ cmp(self.type_name,other.type_name)