// Size returns the number of elements in the list l. This is equivalent to the // Python "len(l)". func (l *List) Size() int64 { ret := C.PyList_Size(c(l)) if ret < 0 { panic(exception()) } return int64(ret) }
// decodeMapping translates a Python object to a Go map. func decodeMapping(pyMapping *C.PyObject) (mapping map[interface{}]interface{}, err error) { mapping = make(map[interface{}]interface{}) pyItems := C.Mapping_Items(pyMapping) if pyItems == nil { err = getError() return } length := int(C.PyList_Size(pyItems)) for i := 0; i < length; i++ { pyPair := C.PyList_GetItem(pyItems, C.Py_ssize_t(i)) var ( key interface{} value interface{} ) if key, err = decode(C.PyTuple_GetItem(pyPair, 0)); err != nil { return } if value, err = decode(C.PyTuple_GetItem(pyPair, 1)); err != nil { return } mapping[key] = value } return }
func pyObjToInterface(o *C.PyObject) interface{} { if C.myPyString_Check(o) != 0 { return C.GoStringN(C.PyString_AsString(o), C.int(C.PyString_Size(o))) } else if C.myPyInt_Check(o) != 0 { return int64(C.PyInt_AsLong(o)) } else if C.myPyDict_Check(o) != 0 { v := make(map[interface{}]interface{}) items := C.PyDict_Items(o) for i := 0; i < int(C.PyList_Size(items)); i++ { item := C.PyList_GetItem(items, C.Py_ssize_t(i)) key := C.PyTuple_GetItem(item, 0) value := C.PyTuple_GetItem(item, 1) v[pyObjToInterface(key)] = pyObjToInterface(value) } C.Py_DecRef(items) return v } return nil }
//export createThreadCallback func createThreadCallback(pid *C.pthread_t) { runtime.LockOSThread() defer runtime.UnlockOSThread() _gstate := C.start_thread() _cb, _r, _w, _ok := callbacks.Get(pid) defer callbacks.Delete(pid) if !_ok { panic(fmt.Errorf("failed to found thread callback for `%v`", pid)) } // TODO: add special headers for WSGI. _environ := GenerateEnviron(_r) _response := C.run_wsgi_application(_environ) // parse header for i := 0; i < int(C.PyList_Size(_response.headers)); i++ { _h := C.PyList_GetItem(_response.headers, C.Py_ssize_t(i)) _k := C.PyTuple_GetItem(_h, C.Py_ssize_t(0)) _v := C.PyTuple_GetItem(_h, C.Py_ssize_t(1)) _w.Header().Set( PyString_AsString(_k), PyString_AsString(_v), ) } _body := C.GoString(_response.body) if len(_body) < 1 { panic(fmt.Errorf("failed to import python wsgi module.")) } C.end_thread(_gstate) // write body _w.WriteHeader(int(_response.status)) _w.Write([]byte(_body)) _cb() }
func wsgi_callback(r *http.Request, w http.ResponseWriter) { _environ := upgrade_header_to_wsgi(r) _body_request, _ := ioutil.ReadAll(r.Body) _body_c := C.CString(string(_body_request)) defer C.free(unsafe.Pointer(_body_c)) _response := C.run_wsgi_application(_body_c, _environ) defer func() { C.Py_DecRef(_response.body) C.Py_DecRef(_response.headers) C.Py_DecRef(_response.error) }() if _response.headers == nil || int(_response.status) == 0 { w.WriteHeader(500) log_wsgi.Error("failed to run python wsgi module.") return } // parse header for i := 0; i < int(C.PyList_Size(_response.headers)); i++ { _h := C.PyList_GetItem(_response.headers, C.Py_ssize_t(i)) _k := C.PyTuple_GetItem(_h, C.Py_ssize_t(0)) _v := C.PyTuple_GetItem(_h, C.Py_ssize_t(1)) w.Header().Set( PyString_AsString(_k), PyString_AsString(_v), ) } // write body w.WriteHeader(int(_response.status)) if _response.body == nil { return } write_response_body(w, _response.body) }
// Py_ssize_t PyList_Size(PyObject *list) // Return the length of the list object in list; this is equivalent to len(list) on a list object. // // Changed in version 2.5: This function returned an int. This might require changes in your code for properly supporting 64-bit systems. func PyList_Size(self *PyObject) int { return int(C.PyList_Size(topy(self))) }