// called from root // To check up presence of data which have come from a network void as_xmlsock::advance(float delta_time) { assert(m_ns); if (m_ns->is_readable()) { gameswf::tu_string str; m_ns->read_line(&str, XML_MAXDATASIZE, XML_TIMEOUT); // If the connection has been gracefully closed, // the size of return value is zero if (str.size() == 0) { close(); as_value function; if (get_member("onClose", &function)) { as_environment env(get_player()); call_method(function, &env, as_value(), 0, env.get_top_index()); } } else { as_value function; if (get_member("onData", &function)) { as_environment env(get_player()); env.push(str); call_method(function, &env, as_value(), 1, env.get_top_index()); } } } }
as_object* as_function::construct(as_object& newobj, const as_environment& env, fn_call::Args& args) { const int swfversion = getSWFVersion(env); // Add a __constructor__ member to the new object visible from version 6. const int flags = PropFlags::dontEnum | PropFlags::onlySWF6Up; newobj.init_member(NSV::PROP_uuCONSTRUCTORuu, this, flags); if (swfversion < 7) { newobj.init_member(NSV::PROP_CONSTRUCTOR, this, PropFlags::dontEnum); } // Don't set a super so that it will be constructed only if required // by the function. fn_call fn(&newobj, env, args, 0, true); as_value ret; try { ret = call(fn); } catch (const GnashException& ex) { // Catching a std::exception here can mask all sorts of bad // behaviour, as (for instance) a poorly constructed string may // smash the stack, throw an exception, but not abort. // This is very effective at confusing debugging tools. // We only throw GnashExceptions. A std::bad_alloc may also be // reasonable, but anything else shouldn't be caught here. log_debug("Native function called as constructor threw exception: " "%s", ex.what()); // If a constructor throws an exception, throw it back to the // caller. This is the only way to signal that a constructor // did not return anything. throw; } // Some built-in constructors do things properly and operate on the // 'this' pointer. Others return a new object. This is to handle those // cases. if (isBuiltin() && ret.is_object()) { as_object* fakeobj = toObject(ret, getVM(env)); fakeobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this), flags); // Also for SWF5+ only? if (swfversion < 7) { fakeobj->init_member(NSV::PROP_CONSTRUCTOR, as_value(this), PropFlags::dontEnum); } return fakeobj; } return &newobj; }
as_value launcher_create_md5sum(const fn_call& fn) { GNASH_REPORT_FUNCTION; boost::intrusive_ptr<launcher_as_object> ptr = ensureType<launcher_as_object>(fn.this_ptr); if (fn.nargs > 0) { string filespec = fn.arg(0).to_string(); return as_value(ptr->obj.create_md5sum(filespec.c_str())); } return as_value(""); }
as_value dejagnu_fail(const fn_call& fn) { // GNASH_REPORT_FUNCTION; DejaGnu* ptr = ensure<ThisIsNative<DejaGnu> >(fn); if (fn.nargs > 0) { string text = fn.arg(0).to_string(); return as_value(ptr->fail(text.c_str())); } return as_value(); }
as_value dbus_ext_setsockname(const fn_call& fn) { GNASH_REPORT_FUNCTION; Dbus* ptr = ensure<ThisIsNative<Dbus> >(fn); if (fn.nargs > 0) { const std::string& text = fn.arg(0).to_string(); ptr->setSocketName(text.c_str()); return as_value(true); } return as_value(false); }
// this takes two arguments as_value gtkext_container_add(const fn_call& fn) { // GNASH_REPORT_FUNCTION; boost::intrusive_ptr<GtkExt> ptr = ensureType<GtkExt>(fn.this_ptr); if (fn.nargs > 0) { GtkExt *parent = dynamic_cast<GtkExt *>(fn.arg(0).to_object(*getGlobal(fn)).get()); GtkExt *child = dynamic_cast<GtkExt *>(fn.arg(1).to_object(*getGlobal(fn)).get()); gtk_container_add (GTK_CONTAINER (parent->getWindow()), child->getWindow()); return as_value(true); } return as_value(false); }
// Creates a new button with the label "Hello World". // GtkWidget *gtk_button_new_with_label (const gchar *label); as_value gtkext_button_new_with_label(const fn_call& fn) { // GNASH_REPORT_FUNCTION; boost::intrusive_ptr<GtkExt> ptr = ensureType<GtkExt>(fn.this_ptr); if (fn.nargs > 0) { string label = fn.arg(0).to_string(); GtkExt *obj = new GtkExt; obj->button_new_with_label(label.c_str()); return as_value(obj); } return as_value(); }
mydb::mydb(player* player) : sql_db(player), m_trace(false), m_db(NULL) { // methods builtin_member("connect", mydb_connect); builtin_member("disconnect", mydb_disconnect); builtin_member("open", mydb_open); builtin_member("run", mydb_run); builtin_member("commit", mydb_commit); builtin_member("auto_commit", as_value(as_value(), mydb_autocommit_setter)); builtin_member("trace", as_value(as_value(), mydb_trace_setter)); }
void as_object::add_property(const std::string& name, as_function& getter, as_function* setter) { const ObjectURI& uri = getURI(vm(), name); Property* prop = _members.getProperty(uri); if (prop) { const as_value& cacheVal = prop->getCache(); // Used to return the return value of addGetterSetter, but this // is always true. _members.addGetterSetter(uri, getter, setter, cacheVal); return; // NOTE: watch triggers not called when adding a new // getter-setter property } else { _members.addGetterSetter(uri, getter, setter, as_value()); // Nothing more to do if there are no triggers. if (!_trigs.get()) return; // check if we have a trigger, if so, invoke it // and set val to its return TriggerContainer::iterator trigIter = _trigs->find(uri); if (trigIter != _trigs->end()) { Trigger& trig = trigIter->second; log_debug("add_property: property %s is being watched", name); as_value v = trig.call(as_value(), as_value(), *this); // The trigger call could have deleted the property, // so we check for its existence again, and do NOT put // it back in if it was deleted prop = _members.getProperty(uri); if (!prop) { log_debug("Property %s deleted by trigger on create (getter-setter)", name); return; } prop->setCache(v); } return; } }
RIO* Handle::as_rio(NativeMethodEnvironment* env) { if(type_ != cRIO) { IO* io_obj = c_as<IO>(object()); int fd = (int)io_obj->descriptor()->to_native(); if(fd == -1) { rb_raise(rb_eIOError, "%s (%d)", strerror(errno), errno); } FILE* f = fdopen(fd, flags_modestr(io_obj->mode()->to_native())); if(!f) { std::cerr << "Error convert fd (" << fd << ") to lowlevel IO: " << strerror(errno) << " (" << errno << ")" << std::endl; rb_raise(rb_eTypeError, "unable to convert fd (%d) to lowlevel IO: %s (%d)", fd, strerror(errno), errno); } RIO* rf = new RIO; rf->handle = as_value(); rf->fd = fd; rf->f = f; // Disable all buffering so that it doesn't get out of sync with // the normal IO buffer. setvbuf(rf->f, 0, _IONBF, 0); type_ = cRIO; as_.rio = rf; } return as_.rio; }
as_value number_ctor(const fn_call& fn) { double val = 0; if (fn.nargs > 0) { val = toNumber(fn.arg(0), getVM(fn)); } if (!fn.isInstantiation()) { return as_value(val); } fn.this_ptr->setRelay(new Number_as(val)); return as_value(); }
/// Returns the keycode of the last key pressed. as_value key_get_code(const fn_call& fn) { movie_root& mr = getRoot(fn); const key::code code = mr.lastKeyEvent(); return as_value(key::codeMap[code][key::KEY]); }
void as_mcloader_loadclip(const fn_call& fn) { as_mcloader* mcl = cast_to<as_mcloader>(fn.this_ptr); assert(mcl); fn.result->set_bool(false); // on default if (fn.nargs == 2) { array<as_value> event_args; // for event handler args event_args.push_back(as_value()); // undefined tu_string infile = get_full_url(fn.get_player()->get_workdir(), fn.arg(0).to_string()); movie_definition* md = fn.get_player()->create_movie(infile.c_str()); if (md == NULL) { IF_VERBOSE_ACTION(log_msg("can't create movie from %s\n", fn.arg(0).to_string())); event_args.push_back("URLNotFound"); // 2-d param mcl->m_listeners.notify(event_id(event_id::ONLOAD_ERROR, &event_args)); return; } as_mcloader::loadable_movie lm; lm.m_def = cast_to<movie_def_impl>(md); lm.m_target = cast_to<character>(fn.env->find_target(fn.arg(1))); mcl->m_lm.push_back(lm); mcl->m_listeners.notify(event_id(event_id::ONLOAD_START, &event_args)); fn.result->set_bool(true); } }
static as_value dejagnu_ctor(const fn_call& fn) { as_object* obj = ensure<ValidThis>(fn); obj->setRelay(new DejaGnu()); return as_value(); }
as_value Property::getValue(const as_object& this_ptr) const { switch (_bound.which()) { case TYPE_VALUE: return boost::get<as_value>(_bound); case TYPE_GETTER_SETTER: { const GetterSetter& a = boost::get<const GetterSetter>(_bound); const as_environment env(getVM(this_ptr)); fn_call fn(const_cast<as_object*>(&this_ptr), env); if (_destructive) { const as_value& ret = a.get(fn); // The getter might have called the setter, and we // should not override. if (_destructive) { _bound = ret; _destructive = false; } return ret; } return a.get(fn); } } return as_value(); }
/// Return the ascii number of the last key pressed. as_value key_get_ascii(const fn_call& fn) { movie_root& mr = getRoot(fn); const key::code code = mr.lastKeyEvent(); return as_value(gnash::key::codeMap[code][key::ASCII]); }
// gtk_main takes no arguments. as_value gtkext_main(const fn_call& fn) { // GNASH_REPORT_FUNCTION; boost::intrusive_ptr<GtkExt> ptr = ensureType<GtkExt>(fn.this_ptr); gtk_main(); return as_value(); }
// AS2 static accessor. as_value camera_get(const fn_call& fn) { as_object* ptr = ensure<ValidThis>(fn); // Properties are attached to the prototype (not __proto__) when get() is // called. as_object* proto = ptr->getMember(NSV::PROP_PROTOTYPE).to_object(getGlobal(fn)); attachCameraProperties(*proto); // TODO: this should return the same object when the same device is // meant, not a new object each time. It will be necessary to query // the MediaHandler for this, and possibly to store the as_objects // somewhere. // media::MediaHandler* handler = media::MediaHandler::get(); if (!handler) { log_error(_("No MediaHandler exists! Cannot create a Camera object")); return as_value(); } media::VideoInput* input = handler->getVideoInput(0); if (!input) { // TODO: what should happen if the index is not available? return as_value(); } const size_t nargs = fn.nargs; if (nargs > 0) { log_debug("%s: the camera is automatically chosen from gnashrc", "Camera.get()"); } // Normally the VM would furnish us with a newly instantiated object, if // a constructor were used. But we're in a factory, so we have to build // one for ourselves. as_object* cam_obj = getGlobal(fn).createObject(); cam_obj->set_prototype(proto); attachCameraInterface(*cam_obj); attachCameraProperties(*cam_obj); cam_obj->setRelay(new Camera_as(input)); return as_value(cam_obj); }
as_value dejagnu_totals(const fn_call& fn) { DejaGnu* ptr = ensure<ThisIsNative<DejaGnu> >(fn); ptr->totals(); return as_value(true); }
// this callback takes no arguments as_value gtkext_window_new(const fn_call& fn) { // GNASH_REPORT_FUNCTION; boost::intrusive_ptr<GtkExt> ptr = ensureType<GtkExt>(fn.this_ptr); GtkExt *obj = new GtkExt; obj->window_new(); return as_value(obj); }
static as_value get(const fn_call& fn) { T* relay = ensure<ThisIsNative<T> >(fn); const boost::optional<U>& opt = (relay->*F)(); if (opt) return as_value(P()(*opt)); as_value null; null.set_null(); return null; }
static as_value gtkext_ctor(const fn_call& /*fn*/) { // GNASH_REPORT_FUNCTION; GtkExt *obj = new GtkExt(); attachInterface(obj); return as_value(obj); // will keep alive }
bool Method::addSlot(string_table::key name, Namespace* ns, boost::uint32_t slotId, Class* /*type*/) { string_table::key nsname = ns ? ns->getURI() : string_table::key(0); int flags = PropFlags::dontDelete; _prototype->init_member(ObjectURI(name, nsname), as_value(), flags, slotId); return true; }
static as_value launcher_ctor(const fn_call& /* fn */) { GNASH_REPORT_FUNCTION; launcher_as_object* obj = new launcher_as_object(); attachInterface(obj); return as_value(obj); // will keep alive // printf ("Hello World from %s !!!\n", __PRETTY_FUNCTION__); }
static as_value set(const fn_call& fn) { T* relay = ensure<ThisIsNative<T> >(fn); if (!fn.nargs) return as_value(); const as_value& arg = fn.arg(0); // Undefined doesn't do anything. if (arg.is_undefined() || arg.is_null()) { (relay->*F)(boost::optional<U>()); return as_value(); } // The function P takes care of converting the argument to the // required type. (relay->*F)(P(fn)(arg)); return as_value(); }
as_value gtkext_widget_show(const fn_call& fn) { // GNASH_REPORT_FUNCTION; boost::intrusive_ptr<GtkExt> ptr = ensureType<GtkExt>(fn.this_ptr); if (fn.nargs > 0) { GtkExt *window = dynamic_cast<GtkExt *>(fn.arg(0).to_object(*getGlobal(fn)).get()); gtk_widget_show(window->getWindow()); } return as_value(); }
// Sound([target:Object]) // Creates a new Sound object for a specified movie clip. void as_global_sound_ctor ( const fn_call &fn ) { gc_ptr<as_sound> snd = new as_sound ( fn.get_player() ); snd->m_target = fn.env->get_target(); // initial value if ( fn.nargs > 0 ) { assert ( fn.env ); snd->m_target = cast_to<character> ( fn.env->find_target ( fn.arg ( 0 ) ) ); } // methods snd->builtin_member ( "attachSound", sound_attach ); snd->builtin_member ( "start", sound_start ); snd->builtin_member ( "stop", sound_stop ); snd->builtin_member ( "setVolume", sound_volume ); snd->builtin_member ( "loadSound", sound_load ); snd->builtin_member ( "position", as_value ( get_position, as_value() ) ); fn.result->set_as_object ( snd.get_ptr() ); }
void attachNumberStaticInterface(as_object& o) { // constant flags const int cflags = as_object::DefaultFlags | PropFlags::readOnly; // Set __proto__ and constructor to constant. as_value null; null.set_null(); o.setPropFlags(null, 0, cflags); // Not quite the same as numeric_limits<double>::max() o.init_member("MAX_VALUE", 1.79769313486231e+308, cflags); // This is generally numeric_limits<double>::denorm_min(). o.init_member("MIN_VALUE", 4.94065645841247e-324, cflags); o.init_member("NaN", as_value(NaN), cflags); o.init_member("POSITIVE_INFINITY", as_value(std::numeric_limits<double>::infinity()), cflags); o.init_member("NEGATIVE_INFINITY", as_value(-std::numeric_limits<double>::infinity()), cflags); }
file::file(player* player, const tu_string& path, const tu_string& mode) : as_object(player), m_file(NULL) { // is path relative ? tu_string file_name = get_player()->get_workdir(); if (strstr(path.c_str(), ":") || *path.c_str() == '/') { file_name = ""; } file_name += path; m_file = new tu_file(file_name.c_str(), mode.c_str()); // methods builtin_member("read", file_read); builtin_member("write", file_write); builtin_member("eof", as_value(file_get_eof, as_value())); // readonly property builtin_member("error", as_value(file_get_error, as_value())); // readonly property }
RFile* Handle::as_rfile(NativeMethodEnvironment* env) { if(type_ != cRFile) { RFile* rfile = new RFile; rfile->handle = as_value(); rfile->fptr = as_rio(env); type_ = cRFile; as_.rfile = rfile; } return as_.rfile; }