/* * %CopyrightBegin% * * Copyright Ericsson AB 2008-2010. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * %CopyrightEnd% */ #include "wxe_return.h" // see http://docs.wxwidgets.org/stable/wx_wxarray.html#arraymacros // this is a magic incantation which must be done! #include WX_DEFINE_OBJARRAY(wxErlDrvTermDataArray); #define INLINE wxeReturn::wxeReturn (ErlDrvPort _port, ErlDrvTermData _caller, bool _isResult) { port = _port; caller = _caller; isResult = _isResult; if (isResult) { addAtom("_wxe_result_"); } } wxeReturn::~wxeReturn () { //depending on which version of wxArray we use, we may have to clear it ourselves. } int wxeReturn::send() { if ((rt.GetCount() == 2 && isResult) || rt.GetCount() == 0) return 1; // not a call bail out if (isResult) { addTupleCount(2); } // rt to array unsigned int rtLength = rt.GetCount(); //signed int size_t size = sizeof(ErlDrvTermData)*(rtLength); ErlDrvTermData* rtData = (ErlDrvTermData *) driver_alloc(size); for (unsigned int i=0; i < rtLength; i++) { rtData[i] = rt[i]; } int res = driver_send_term(port, caller, rtData, rtLength); driver_free(rtData); #ifdef DEBUG if(res == -1) { wxString msg; msg.Printf(wxT("Failed to send return or event msg")); send_msg("internal_error", &msg); } #endif reset(); return res; } //clear everything so we can re-use if we want void wxeReturn::reset() { rt.empty(); temp_float.empty(); } INLINE unsigned int wxeReturn::size() { return rt.GetCount(); } INLINE void wxeReturn::add(ErlDrvTermData type, ErlDrvTermData data) { rt.Add(type); rt.Add(data); } // INLINE // void wxeReturn::addRef(const void *ptr, const char* className) { // unsigned int ref_idx = wxe_app->getRef((void *)ptr, memEnv); // addRef(ref_idx, className); // } INLINE void wxeReturn::addRef(const unsigned int ref, const char* className) { addAtom("wx_ref"); addUint(ref); addAtom(className); rt.Add(ERL_DRV_NIL); addTupleCount(4); } INLINE void wxeReturn::addAtom(const char* atomName) { add(ERL_DRV_ATOM, driver_mk_atom((char *)atomName)); } INLINE void wxeReturn::addBinary(const char* buf, const size_t size) { rt.Add(ERL_DRV_BUF2BINARY); rt.Add((ErlDrvTermData)buf); rt.Add((ErlDrvTermData)size); } INLINE void wxeReturn::addExt2Term(wxeErlTerm *term) { if(term) { rt.Add(ERL_DRV_EXT2TERM); rt.Add((ErlDrvTermData)term->bin); rt.Add((ErlDrvTermData)term->size); } else { rt.Add(ERL_DRV_NIL); } } INLINE void wxeReturn::addExt2Term(wxETreeItemData *val) { if(val) { rt.Add(ERL_DRV_EXT2TERM); rt.Add((ErlDrvTermData)(val->bin)); rt.Add((ErlDrvTermData)(val->size)); } else rt.Add(ERL_DRV_NIL); } INLINE void wxeReturn::addUint(unsigned int n) { add(ERL_DRV_UINT, (ErlDrvTermData)n); } INLINE void wxeReturn::addInt(int n) { add(ERL_DRV_INT, (ErlDrvTermData)n); } INLINE void wxeReturn::addFloat(double f) { // Erlang expects a pointer to double... // Hmm is temp_float moved if reallocated // the pointer may be wrong. // Harryhuk - use a list instead? temp_float.Add(f); add(ERL_DRV_FLOAT, (ErlDrvTermData)&temp_float.Last()); } INLINE void wxeReturn::addTupleCount(unsigned int n) { add(ERL_DRV_TUPLE, (ErlDrvTermData)n); } INLINE void wxeReturn::endList(unsigned int n) { rt.Add(ERL_DRV_NIL); add(ERL_DRV_LIST, (ErlDrvTermData)(n+1)); } INLINE void wxeReturn::addBool(int val) { if (val) { addAtom("true"); } else { addAtom("false"); } } INLINE void wxeReturn::add(const wxString s) { int strLen = s.Len(); wxCharBuffer resultCB = s.mb_str(utfConverter); int * resultPtr = (int *) resultCB.data(); for (int i = 0; i < strLen; i++, resultPtr++) { addInt(*resultPtr); } endList(strLen); } INLINE void wxeReturn::add(const wxString* s) { add(*s); } INLINE void wxeReturn::add(wxArrayString val) { unsigned int len = val.GetCount(); for (unsigned int i = 0; i< len; i++) { add(val[i]); } endList(len); } INLINE void wxeReturn::add(wxArrayInt val) { unsigned int len = val.GetCount(); for (unsigned int i = 0; i< len; i++) { addInt(val[i]); } endList(len); } INLINE void wxeReturn::add(wxUIntPtr *val) { add(ERL_DRV_UINT, (ErlDrvTermData) val); } INLINE void wxeReturn::add(wxPoint pt) { addInt(pt.x); addInt(pt.y); addTupleCount(2); } INLINE void wxeReturn::add(wxPoint2DDouble pt) { addFloat(pt.m_x); addFloat(pt.m_y); addTupleCount(2); } INLINE void wxeReturn::add(wxSize size) { addInt(size.GetWidth()); addInt(size.GetHeight()); addTupleCount(2); } INLINE void wxeReturn::add(wxRect rect) { addInt(rect.x); addInt(rect.y); addInt(rect.width); addInt(rect.height); addTupleCount(4); } INLINE void wxeReturn::add(wxColour colour) { addInt(colour.Red()); addInt(colour.Green()); addInt(colour.Blue()); addInt(colour.Alpha()); addTupleCount(4); } INLINE void wxeReturn::add(wxDateTime dateTime) { addDate(dateTime); addTime(dateTime); addTupleCount(2); } INLINE void wxeReturn::addDate(wxDateTime dateTime) { addInt(dateTime.GetYear()); addInt(dateTime.GetMonth()+1); // c++ month is zero based addInt(dateTime.GetDay()); addTupleCount(3); } INLINE void wxeReturn::addTime(wxDateTime dateTime) { addInt(dateTime.GetHour()); addInt(dateTime.GetMinute()); addInt(dateTime.GetSecond()); addTupleCount(3); } INLINE void wxeReturn::add(wxRect2DDouble rect2D) { addFloat(rect2D.m_x); addFloat(rect2D.m_y); addFloat(rect2D.m_width); addFloat(rect2D.m_height); addTupleCount(4); } INLINE void wxeReturn::add(wxGridCellCoords val) { addInt(val.GetRow()); addInt(val.GetCol()); addTupleCount(2); } INLINE void wxeReturn::add(wxGBPosition val) { addInt(val.GetRow()); addInt(val.GetCol()); addTupleCount(2); } INLINE void wxeReturn::add(wxGBSpan val) { addInt(val.GetRowspan()); addInt(val.GetColspan()); addTupleCount(2); } INLINE void wxeReturn::add(wxMouseState val) { addAtom("wxMouseState"); // TODO not int? addUint(val.GetX()); addUint(val.GetY()); addBool(val.LeftDown()); addBool(val.MiddleDown()); addBool(val.RightDown()); addBool(val.ControlDown()); addBool(val.ShiftDown()); addBool(val.AltDown()); addBool(val.MetaDown()); addBool(val.CmdDown()); addTupleCount(11); } INLINE void wxeReturn::add(const wxHtmlLinkInfo *val) { addAtom("wxHtmlLinkInfo"); add(val->GetHref()); add(val->GetTarget()); addTupleCount(3); } INLINE void wxeReturn::add(const wxHtmlLinkInfo &val) { addAtom("wxHtmlLinkInfo"); add(val.GetHref()); add(val.GetTarget()); addTupleCount(3); }