/* * %CopyrightBegin% * * Copyright Ericsson AB 2008-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * %CopyrightEnd% */ #include "wxe_return.h" #define INLINE wxeReturn::wxeReturn (ErlDrvTermData _port, ErlDrvTermData _caller, bool _isResult) { port = _port; caller = _caller; isResult = _isResult; rtb = buff; rt_max = RT_BUFF_SZ; rt_n = 0; if (isResult) { addAtom("_wxe_result_"); } } //clear everything so we can re-use if we want void wxeReturn::reset() { rt_n = 0; temp_float.empty(); } wxeReturn::~wxeReturn () { if(rtb != buff) driver_free(rtb); } int wxeReturn::send() { if ((rt_n == 2 && isResult) || rt_n == 0) return 1; // not a call bail out if (isResult) { addTupleCount(2); } int res = erl_drv_send_term(port, caller, rtb, rt_n); #ifdef DEBUG if(res == -1) { fprintf(stderr, "Failed to send return or event msg\r\n"); } #endif reset(); return res; } INLINE unsigned int wxeReturn::size() { return rt_n; } INLINE void wxeReturn::ensureFloatCount(size_t n) { temp_float.Alloc(n); } INLINE void wxeReturn::do_add(ErlDrvTermData val) { if(rt_n >= rt_max) { // realloc rt_max += RT_BUFF_SZ; if(rtb == buff) { rtb = (ErlDrvTermData *) driver_alloc(rt_max * sizeof(ErlDrvTermData)); for(int i = 0; i < RT_BUFF_SZ; i++) rtb[i] = buff[i]; } else { rtb = (ErlDrvTermData *) driver_realloc(rtb, rt_max * sizeof(ErlDrvTermData)); } } rtb[rt_n++] = val; } INLINE void wxeReturn::add(ErlDrvTermData type, ErlDrvTermData data) { do_add(type); do_add(data); } INLINE void wxeReturn::addRef(const unsigned int ref, const char* className) { addAtom("wx_ref"); addUint(ref); addAtom(className); do_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) { do_add(ERL_DRV_BUF2BINARY); do_add((ErlDrvTermData)buf); do_add((ErlDrvTermData)size); } INLINE void wxeReturn::addExt2Term(wxeErlTerm *term) { if(term) { do_add(ERL_DRV_EXT2TERM); do_add((ErlDrvTermData)term->bin); do_add((ErlDrvTermData)term->size); } else { do_add(ERL_DRV_NIL); } } INLINE void wxeReturn::addExt2Term(wxETreeItemData *val) { if(val) { do_add(ERL_DRV_EXT2TERM); do_add((ErlDrvTermData)(val->bin)); do_add((ErlDrvTermData)(val->size)); } else do_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) { do_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(wxArrayDouble val) { unsigned int len = val.GetCount(); temp_float.Alloc(len); for (unsigned int i = 0; i< len; i++) { addFloat(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); }