/*JSON{ "type" : "method", "class" : "Object", "name" : "removeListener", "generate" : "jswrap_object_removeListener", "params" : [ ["event","JsVar","The name of the event, for instance 'data'"], ["listener","JsVar","The listener to remove"] ] } Removes the specified event listener. ``` function foo(d) { console.log(d); } Serial1.on("data", foo); Serial1.removeListener("data", foo); ``` */ void jswrap_object_removeListener(JsVar *parent, JsVar *event, JsVar *callback) { if (!jsvHasChildren(parent)) { jsWarn("Parent must be an object - not a String, Integer, etc."); return; } if (jsvIsString(event)) { // remove the whole child containing listeners JsVar *eventName = jsvVarPrintf(JS_EVENT_PREFIX"%s",event); if (!eventName) return; // no memory JsVar *eventListName = jsvFindChildFromVar(parent, eventName, true); jsvUnLock(eventName); JsVar *eventList = jsvSkipName(eventListName); if (eventList) { if (eventList == callback) { // there's no array, it was a single item jsvRemoveChild(parent, eventListName); } else if (jsvIsArray(eventList)) { // it's an array, search for the index JsVar *idx = jsvGetArrayIndexOf(eventList, callback, true); if (idx) { jsvRemoveChild(eventList, idx); jsvUnLock(idx); } } jsvUnLock(eventList); } jsvUnLock(eventListName); } else { jsWarn("First argument to EventEmitter.removeListener(..) must be a string"); return; } }
/*JSON{ "type":"method", "class": "Array", "name" : "contains", "description" : "Return true if this array contains the given value", "generate" : "jswrap_array_contains", "params" : [ [ "value", "JsVar", "The value to check for"] ], "return" : ["bool", "Whether value is in the array or not"] }*/ bool jswrap_array_contains(JsVar *parent, JsVar *value) { // ArrayIndexOf will return 0 if not found JsVar *arrElement = jsvGetArrayIndexOf(parent, value, false/*not exact*/); bool contains = arrElement!=0; jsvUnLock(arrElement); return contains; }
/*JSON{ "type":"method", "class": "Array", "name" : "indexOf", "description" : "Return the index of the value in the array, or -1", "generate" : "jswrap_array_indexOf", "params" : [ [ "value", "JsVar", "The value to check for"] ], "return" : ["JsVar", "the index of the value in the array, or undefined"] }*/ JsVar *jswrap_array_indexOf(JsVar *parent, JsVar *value) { JsVar *idxName = jsvGetArrayIndexOf(parent, value, false/*not exact*/); // but this is the name - we must turn it into a var if (idxName == 0) return 0; // not found! JsVar *idx = jsvCopyNameOnly(idxName, false/* no children */, false/* Make sure this is not a name*/); jsvUnLock(idxName); return idx; }
/*JSON{ "type":"function", "name" : "edit", "description" : ["Fill the console with the contents of the given function, so you can edit it.", "NOTE: This is a convenience function - it will not edit 'inner functions'. For that, you must edit the 'outer function' and re-execute it."], "generate" : "jswrap_interface_edit", "params" : [ [ "funcName", "JsVar", "The name of the function to edit (either a string or just the unquoted name)"] ] }*/ void jswrap_interface_edit(JsVar *funcName) { JsVar *func = 0; if (jsvIsString(funcName)) { funcName = jsvLockAgain(funcName); func = jsvSkipNameAndUnLock(jsvFindChildFromVar(execInfo.root, funcName, 0)); } else { func = funcName; funcName = jsvGetPathTo(execInfo.root, func, 2); } if (jsvIsString(funcName)) { if (jsvIsFunction(func)) { JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false); JsVar *inRoot = jsvGetArrayIndexOf(execInfo.root, func, true); bool normalDecl = scopeVar==0 && inRoot!=0; jsvUnLock(inRoot); jsvUnLock(scopeVar); JsVar *newLine = jsvNewFromEmptyString(); if (newLine) { // could be out of memory /* normalDecl: * * function foo() { ... } * * NOT normalDecl: * * foo.replaceWith(function() { ... }); * */ JsVar *funcData = jsvAsString(func, false); if (normalDecl) { jsvAppendString(newLine, "function "); jsvAppendStringVarComplete(newLine, funcName); jsvAppendStringVar(newLine, funcData, 9, JSVAPPENDSTRINGVAR_MAXLENGTH); } else { jsvAppendStringVarComplete(newLine, funcName); jsvAppendString(newLine, ".replaceWith("); jsvAppendStringVarComplete(newLine, funcData); jsvAppendString(newLine, ");"); } jsvUnLock(funcData); jsiReplaceInputLine(newLine); jsvUnLock(newLine); } } else { jsError("Edit should be called with the name of a function"); } } else { jsError("Edit should be called with edit(funcName) or edit('funcName')"); } jsvUnLock(func); jsvUnLock(funcName); }
void serverClose(JsNetwork *net, JsVar *server) { JsVar *arr = socketGetArray(HTTP_ARRAY_HTTP_SERVERS,false); if (arr) { // close socket _socketConnectionKill(net, server); // remove from array JsVar *idx = jsvGetArrayIndexOf(arr, server, true); if (idx) { jsvRemoveChild(arr, idx); jsvUnLock(idx); } else jsWarn("Server not found!"); jsvUnLock(arr); } }
/*JSON{ "type":"staticmethod", "class" : "E", "name" : "openFile", "generate" : "jswrap_E_openFile", "description" : [ "Open a file" ], "params" : [ [ "path", "JsVar", "the path to the file to open." ], [ "mode", "JsVar", "The mode to use when opening the file. Valid values for mode are 'r' for read, 'w' for write new, 'w+' for write existing, and 'a' for append. If not specified, the default is 'r'."] ], "return" : ["JsVar", "A File object"] }*/ JsVar *jswrap_E_openFile(JsVar* path, JsVar* mode) { FRESULT res = FR_INVALID_NAME; JsFile file; file.fileVar = 0; FileMode fMode = FM_NONE; if (jsfsInit()) { JsVar *arr = fsGetArray(true); if (!arr) return 0; // out of memory char pathStr[JS_DIR_BUF_SIZE] = ""; char modeStr[3] = "r"; if (!jsvIsUndefined(path)) { jsvGetString(path, pathStr, JS_DIR_BUF_SIZE); if (!jsvIsUndefined(mode)) jsvGetString(mode, modeStr, 3); #ifndef LINUX BYTE ff_mode = 0; bool append = false; #endif if(strcmp(modeStr,"r") == 0) { fMode = FM_READ; #ifndef LINUX ff_mode = FA_READ | FA_OPEN_EXISTING; #endif } else if(strcmp(modeStr,"a") == 0) { fMode = FM_WRITE; #ifndef LINUX ff_mode = FA_WRITE | FA_OPEN_ALWAYS; append = true; #endif } else if(strcmp(modeStr,"w") == 0) { fMode = FM_WRITE; #ifndef LINUX ff_mode = FA_WRITE | FA_CREATE_ALWAYS; #endif } else if(strcmp(modeStr,"w+") == 0) { fMode = FM_READ_WRITE; #ifndef LINUX ff_mode = FA_WRITE | FA_OPEN_ALWAYS; #endif } if(fMode != FM_NONE && allocateJsFile(&file, fMode, FT_FILE)) { #ifndef LINUX if ((res=f_open(&file.data.handle, pathStr, ff_mode)) == FR_OK) { if (append) f_lseek(&file.data.handle, file.data.handle.fsize); // move to end of file #else file.data.handle = fopen(pathStr, modeStr); if (file.data.handle) { res=FR_OK; #endif file.data.state = FS_OPEN; fileSetVar(&file); // add to list of open files jsvArrayPush(arr, file.fileVar); jsvUnLock(arr); } else { // File open failed jsvUnLock(file.fileVar); file.fileVar = 0; } if(res != FR_OK) jsfsReportError("Could not open file", res); } } else { jsError("Path is undefined"); } } return file.fileVar; } /*JSON{ "type" : "method", "class" : "File", "name" : "close", "generate_full" : "jswrap_file_close(parent)", "description" : [ "Close an open file."] }*/ void jswrap_file_close(JsVar* parent) { if (jsfsInit()) { JsFile file; if (fileGetFromVar(&file, parent) && file.data.state == FS_OPEN) { #ifndef LINUX f_close(&file.data.handle); #else fclose(file.data.handle); file.data.handle = 0; #endif file.data.state = FS_CLOSED; fileSetVar(&file); // TODO: could try and free the memory used by file.data ? JsVar *arr = fsGetArray(false); if (arr) { JsVar *idx = jsvGetArrayIndexOf(arr, file.fileVar, true); if (idx) { jsvRemoveChild(arr, idx); jsvUnLock(idx); } jsvUnLock(arr); } } } } /*JSON{ "type" : "method", "class" : "File", "name" : "write", "generate" : "jswrap_file_write", "description" : [ "write data to a file"], "params" : [ ["buffer", "JsVar", "A string containing the bytes to write"] ], "return" : [ "int32", "the number of bytes written" ] }*/ size_t jswrap_file_write(JsVar* parent, JsVar* buffer) { FRESULT res = 0; size_t bytesWritten = 0; if (jsfsInit()) { JsFile file; if (fileGetFromVar(&file, parent)) { if(file.data.mode == FM_WRITE || file.data.mode == FM_READ_WRITE) { JsvIterator it; jsvIteratorNew(&it, buffer); char buf[32]; while (jsvIteratorHasElement(&it)) { // pull in a buffer's worth of data size_t n = 0; while (jsvIteratorHasElement(&it) && n<sizeof(buf)) { buf[n++] = (char)jsvIteratorGetIntegerValue(&it); jsvIteratorNext(&it); } // write it out size_t written = 0; #ifndef LINUX res = f_write(&file.data.handle, &buf, n, &written); #else written = fwrite(&buf, 1, n, file.data.handle); #endif bytesWritten += written; if(written == 0) res = FR_DISK_ERR; if (res) break; } jsvIteratorFree(&it); // finally, sync - just in case there's a reset or something #ifndef LINUX f_sync(&file.data.handle); #else fflush(file.data.handle); #endif } fileSetVar(&file); } } if (res) { jsfsReportError("Unable to write file", res); } return bytesWritten; }