Example #1
0
/*JSON{
  "type" : "constructor",
  "class" : "Number",
  "name" : "Number",
  "generate" : "jswrap_number_constructor",
  "params" : [
    ["value","JsVarArray","A single value to be converted to a number"]
  ],
  "return" : ["JsVar","A Number object"]
}
Creates a number
 */
JsVar *jswrap_number_constructor(JsVar *args) {
  if (jsvGetArrayLength(args)==0) return jsvNewFromInteger(0);
  JsVar *val = jsvGetArrayItem(args, 0);
  JsVar *result = 0;

  if (jsvIsArray(val)) {
    JsVarInt l = jsvGetArrayLength(val);
    if (l==0) result = jsvNewFromInteger(0);
    else if (l==1) {
      JsVar *n = jsvGetArrayItem(val, 0);
      if (jsvIsString(n) && jsvIsEmptyString(n)) result = jsvNewFromInteger(0);
      else if (!jsvIsBoolean(n)) result=jsvAsNumber(n);
      jsvUnLock(n);
    } // else NaN
  } else if (jsvIsUndefined(val) || jsvIsObject(val))
    result = 0;
  else {
    if (jsvIsString(val) && jsvIsEmptyString(val)) {
      result = jsvNewFromInteger(0);
    } else
      result = jsvAsNumber(val);
  }
  jsvUnLock(val);
  if (result) return result;
  return jsvNewFromFloat(NAN);
}
Example #2
0
/** Push data into a stream. To be used by Espruino (not a user).
 * This either calls the on('data') handler if it exists, or it
 * puts the data in a buffer. This MAY CLAIM the string that is
 * passed in.
 *
 * This will return true on success, or false if the buffer is
 * full. Setting force=true will attempt to fill the buffer as
 * full as possible, and will raise an error flag if data is lost.
 */
bool jswrap_stream_pushData(JsVar *parent, JsVar *dataString, bool force) {
  assert(jsvIsObject(parent));
  assert(jsvIsString(dataString));
  bool ok = true;

  JsVar *callback = jsvFindChildFromString(parent, STREAM_CALLBACK_NAME, false);
  if (callback) {
    if (!jsiExecuteEventCallback(parent, callback, dataString, 0)) {
      jsError("Error processing Serial data handler - removing it.");
      jsErrorFlags |= JSERR_CALLBACK;
      jsvRemoveNamedChild(parent, STREAM_CALLBACK_NAME);
    }
    jsvUnLock(callback);
  } else {
    // No callback - try and add buffer
    JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0);
    if (!jsvIsString(buf)) {
      // no buffer, just set this one up
      jsvObjectSetChild(parent, STREAM_BUFFER_NAME, dataString);
    } else {
      // append (if there is room!)
      size_t bufLen = jsvGetStringLength(buf);
      size_t dataLen = jsvGetStringLength(dataString);
      if (bufLen + dataLen > STREAM_MAX_BUFFER_SIZE) {
        if (force) jsErrorFlags |= JSERR_BUFFER_FULL;
        // jsWarn("String buffer overflowed maximum size (%d)", STREAM_MAX_BUFFER_SIZE);
        ok = false;
      }
      if ((ok || force) && (bufLen < STREAM_MAX_BUFFER_SIZE))
        jsvAppendStringVar(buf, dataString, 0, STREAM_MAX_BUFFER_SIZE-bufLen);
      jsvUnLock(buf);
    }
  }
  return ok;
}
Example #3
0
/*JSON{
  "type" : "method",
  "class" : "ArrayBufferView",
  "name" : "set",
  "generate" : "jswrap_arraybufferview_set",
  "params" : [
    ["arr","JsVar","Floating point index to access"],
    ["offset","int32","The offset in this array at which to write the values (optional)"]
  ]
}
Copy the contents of `array` into this one, mapping `this[x+offset]=array[x];`
*/
void jswrap_arraybufferview_set(JsVar *parent, JsVar *arr, int offset) {
  if (!(jsvIsString(arr) || jsvIsArray(arr) || jsvIsArrayBuffer(arr))) {
    jsExceptionHere(JSET_ERROR, "Expecting first argument to be an array, not %t", arr);
    return;
  }
  JsvIterator itsrc;
  jsvIteratorNew(&itsrc, arr);
  JsvArrayBufferIterator itdst;
  jsvArrayBufferIteratorNew(&itdst, parent, (size_t)offset);

  bool useInts = !JSV_ARRAYBUFFER_IS_FLOAT(itdst.type) || jsvIsString(arr);

  while (jsvIteratorHasElement(&itsrc) && jsvArrayBufferIteratorHasElement(&itdst)) {
    if (useInts) {
      jsvArrayBufferIteratorSetIntegerValue(&itdst, jsvIteratorGetIntegerValue(&itsrc));
    } else {
      JsVar *value = jsvIteratorGetValue(&itsrc);
      jsvArrayBufferIteratorSetValue(&itdst, value);
      jsvUnLock(value);
    }
    jsvArrayBufferIteratorNext(&itdst);
    jsvIteratorNext(&itsrc);
  }
  jsvArrayBufferIteratorFree(&itdst);
  jsvIteratorFree(&itsrc);
}
Example #4
0
// This is for Object.keys and Object.
JsVar *jswrap_object_keys_or_property_names(JsVar *obj, bool includeNonEnumerable) {
  // strings are iterable, but we shouldn't try and show keys for them
  if (jsvIsIterable(obj) && !jsvIsString(obj)) {
    JsvIsInternalChecker checkerFunction = jsvGetInternalFunctionCheckerFor(obj);

    JsVar *arr = jsvNewWithFlags(JSV_ARRAY);
    if (!arr) return 0;
    JsvIterator it;
    jsvIteratorNew(&it, obj);
    while (jsvIteratorHasElement(&it)) {
      JsVar *key = jsvIteratorGetKey(&it);
      if (!(checkerFunction && checkerFunction(key)) || (jsvIsStringEqual(key, JSPARSE_CONSTRUCTOR_VAR))) {
        /* Not sure why constructor is included in getOwnPropertyNames, but
         * not in for (i in ...) but it is, so we must explicitly override the
         * check in jsvIsInternalObjectKey! */
        JsVar *name = jsvAsArrayIndexAndUnLock(jsvCopyNameOnly(key, false, false));
        if (name) {
          jsvArrayPushAndUnLock(arr, name);
        }
      }
      jsvUnLock(key);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);

    /* Search our built-in symbol table
       Assume that ALL builtins are non-enumerable. This isn't great but
       seems to work quite well right now! */
    if (includeNonEnumerable) {
      const JswSymList *symbols = 0;

      JsVar *protoOwner = jspGetPrototypeOwner(obj);
      if (protoOwner) {
        symbols = jswGetSymbolListForObjectProto(protoOwner);
        jsvUnLock(protoOwner);
      } else if (!jsvIsObject(obj)) {
        // get symbols, but only if we're not doing it on a basic object
        symbols = jswGetSymbolListForObject(obj);
      }

      if (symbols) {
        unsigned int i;
        for (i=0;i<symbols->symbolCount;i++)
          jsvArrayAddString(arr, &symbols->symbolChars[symbols->symbols[i].strOffset]);
      }

      if (jsvIsArray(obj) || jsvIsString(obj)) {
        jsvArrayAddString(arr, "length");
      }
    }

    return arr;
  } else {
    jsWarn("Object.keys called on non-object");
    return 0;
  }
}
Example #5
0
/*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);
}
Example #6
0
/*JSON{
  "type"     : "staticmethod",
  "class"    : "ESP8266WiFi",
  "name"     : "beAccessPoint",
  "generate" : "jswrap_ESP8266WiFi_beAccessPoint",
  "params"   : [
    ["jsv_ssid", "JsVar", "The network SSID"],
    ["jsv_password", "JsVar", "The password to allow stations to connect to the access point"]
  ]
}*/
void jswrap_ESP8266WiFi_beAccessPoint(
    JsVar *jsv_ssid,    //!< The network identity that the access point will advertize itself as.
    JsVar *jsv_password //!< The password a station will need to connect to the access point.
  ) {
  os_printf("> jswrap_ESP8266WiFi_beAccessPoint\n");
  // Validate that the SSID and password are somewhat useful.
  if (jsv_ssid == NULL || !jsvIsString(jsv_ssid)) {
      jsExceptionHere(JSET_ERROR, "No SSID.");
    return;
  }

  // Build our SoftAP configuration details
  struct softap_config softApConfig;
  memset(&softApConfig, 0, sizeof(softApConfig));

  // If no password has been supplied, then be open.  Otherwise, use WPA2 and the
  // password supplied.  Also check that the password is at least 8 characters long.
  if (jsv_password == NULL || !jsvIsString(jsv_password)) {
    softApConfig.authmode = AUTH_OPEN;
  } else {
    if (jsvGetStringLength(jsv_password) < 8) {
      jsExceptionHere(JSET_ERROR, "Password must be 8 characters or more in length.");
      return;
    }
    softApConfig.authmode = AUTH_WPA2_PSK;
    int len = jsvGetString(jsv_password, (char *)softApConfig.password, sizeof(softApConfig.password)-1);
    softApConfig.password[len]='\0';
  }

  int len = jsvGetString(jsv_ssid, (char *)softApConfig.ssid, sizeof(softApConfig.ssid)-1);
  softApConfig.ssid[len]='\0';

  // Define that we are in Soft AP mode.
  os_printf("Wifi: switching to soft-AP mode, authmode=%d\n", softApConfig.authmode);
  wifi_set_opmode_current(SOFTAP_MODE);

  softApConfig.ssid_len       = 0; // Null terminated SSID
  softApConfig.ssid_hidden    = 0; // Not hidden.
  softApConfig.max_connection = 4; // Maximum number of connections.

  // Set the WiFi configuration.
  int rc = wifi_softap_set_config_current(&softApConfig);
  // We should really check that becoming an access point works, however as of SDK 1.4, we
  // are finding that if we are currently connected to an access point and we switch to being
  // an access point, it works ... but returns 1 indicating an error.
  /*
  if (rc != 1) {
      os_printf(" - Error returned from wifi_softap_set_config_current=%d\n", rc);
      jsExceptionHere(JSET_ERROR, "Error setting ESP8266 softap config.");
  }
  */
  os_printf("< jswrap_ESP8266WiFi_beAccessPoint\n");
}
Example #7
0
/*JSON{
  "type" : "method",
  "class" : "Object",
  "name" : "on",
  "generate" : "jswrap_object_on",
  "params" : [
    ["event","JsVar","The name of the event, for instance 'data'"],
    ["listener","JsVar","The listener to call when this event is received"]
  ]
}
Register an event listener for this object, for instance ```http.on('data', function(d) {...})```. See Node.js's EventEmitter.
 */
void jswrap_object_on(JsVar *parent, JsVar *event, JsVar *listener) {
  if (!jsvHasChildren(parent)) {
    jsWarn("Parent must be an object - not a String, Integer, etc.");
    return;
  }
  if (!jsvIsString(event)) {
    jsWarn("First argument to EventEmitter.on(..) must be a string");
    return;
  }
  if (!jsvIsFunction(listener) && !jsvIsString(listener)) {
    jsWarn("Second argument to EventEmitter.on(..) must be a function or a String (containing code)");
    return;
  }

  JsVar *eventName = jsvVarPrintf(JS_EVENT_PREFIX"%s",event);
  if (!eventName) return; // no memory

  JsVar *eventList = jsvFindChildFromVar(parent, eventName, true);
  jsvUnLock(eventName);
  JsVar *eventListeners = jsvSkipName(eventList);
  if (jsvIsUndefined(eventListeners)) {
    // just add
    jsvSetValueOfName(eventList, listener);
  } else {
    if (jsvIsArray(eventListeners)) {
      // we already have an array, just add to it
      jsvArrayPush(eventListeners, listener);
    } else {
      // not an array - we need to make it an array
      JsVar *arr = jsvNewEmptyArray();
      jsvArrayPush(arr, eventListeners);
      jsvArrayPush(arr, listener);
      jsvSetValueOfName(eventList, arr);
      jsvUnLock(arr);
    }
  }
  jsvUnLock2(eventListeners, eventList);
  /* Special case if we're a data listener and data has already arrived then
   * we queue an event immediately. */
  if (jsvIsStringEqual(event, "data")) {
    JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0);
    if (jsvIsString(buf)) {
      jsiQueueObjectCallbacks(parent, STREAM_CALLBACK_NAME, &buf, 1);
      jsvRemoveNamedChild(parent, STREAM_BUFFER_NAME);
    }
    jsvUnLock(buf);
  }
}
Example #8
0
/*JSON{
  "type" : "function",
  "name" : "setTimeout",
  "generate" : "jswrap_interface_setTimeout",
  "params" : [
    ["function","JsVar","A Function or String to be executed"],
    ["timeout","float","The time until the function will be executed"],
    ["args","JsVarArray","Optional arguments to pass to the function when executed"]
  ],
  "return" : ["JsVar","An ID that can be passed to clearTimeout"]
}
Call the function (or evaluate the string) specified ONCE after the timeout in milliseconds.

For instance:

```
setTimeout(function () {
  console.log("Hello World");
}, 1000);
// or
setTimeout('console.log("Hello World");', 1000);
// both print 'Hello World' after a second
```

You can also specify extra arguments that will be sent to the function when it is executed. For example:

```
setTimeout(function (a,b) {
  console.log(a+" "+b);
}, 1000, "Hello", "World");
// prints 'Hello World' after 1 second
```

If you want to stop the function from being called, pass the number that
was returned by `setTimeout` into the `clearInterval` function.

 **Note:** If `setDeepSleep(true)` has been called and the interval is greater than 5 seconds, Espruino may execute the interval up to 1 second late. This is because Espruino can only wake from deep sleep every second - and waking early would cause Espruino to waste power while it waited for the correct time.
 */
JsVar *_jswrap_interface_setTimeoutOrInterval(JsVar *func, JsVarFloat interval, JsVar *args, bool isTimeout) {
  // NOTE: The 5 sec delay mentioned in the description is handled by jshSleep
  JsVar *itemIndex = 0;
  if (!jsvIsFunction(func) && !jsvIsString(func)) {
    jsExceptionHere(JSET_ERROR, "Function or String not supplied!");
  } else {
    // Create a new timer
    JsVar *timerPtr = jsvNewWithFlags(JSV_OBJECT);
    if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL;
    JsSysTime intervalInt = jshGetTimeFromMilliseconds(interval);
    jsvObjectSetChildAndUnLock(timerPtr, "time", jsvNewFromLongInteger((jshGetSystemTime() - jsiLastIdleTime) + intervalInt));
    if (!isTimeout) {
      jsvObjectSetChildAndUnLock(timerPtr, "interval", jsvNewFromLongInteger(intervalInt));
    }
    jsvObjectSetChild(timerPtr, "callback", func); // intentionally no unlock
    if (jsvGetArrayLength(args))
      jsvObjectSetChild(timerPtr, "args", args); // intentionally no unlock

    // Add to array
    itemIndex = jsvNewFromInteger(jsiTimerAdd(timerPtr));
    jsvUnLock(timerPtr);
    jsiTimersChanged(); // mark timers as changed
  }
  return itemIndex;
}
Example #9
0
/*JSON{ "type":"method", "class": "Serial", "name" : "setup",
         "description" : ["Setup this Serial port with the given baud rate and options.",
                          "If not specified in options, the default pins are used (usually the lowest numbered pins on the lowest port that supports this peripheral)"],
         "generate" : "jswrap_serial_setup",
         "params" : [ [ "baudrate", "JsVar", "The baud rate - the default is 9600"],
                      [ "options", "JsVar", ["An optional structure containing extra information on initialising the serial port.",
                                             "```{rx:pin,tx:pin,bytesize:8,parity:null/'none'/'o'/'odd'/'e'/'even',stopbits:1}```",
                                             "You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `UART`/`USART` markers.",
                                             "Note that even after changing the RX and TX pins, if you have called setup before then the previous RX and TX pins will still be connected to the Serial port as well - until you set them to something else using digitalWrite" ] ] ]
}*/
void jswrap_serial_setup(JsVar *parent, JsVar *baud, JsVar *options) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_USART(device)) return;

  JshUSARTInfo inf;
  jshUSARTInitInfo(&inf);

  if (!jsvIsUndefined(baud)) {
    int b = (int)jsvGetInteger(baud);
    if (b<=100 || b > 10000000)
      jsExceptionHere(JSET_ERROR, "Invalid baud rate specified");
    else
      inf.baudRate = b;
  }


  if (jsvIsObject(options)) {
    inf.pinRX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "rx", 0));
    inf.pinTX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "tx", 0));    

    JsVar *v;
    v = jsvObjectGetChild(options, "bytesize", 0);
    if (jsvIsInt(v)) 
      inf.bytesize = (unsigned char)jsvGetInteger(v);
    jsvUnLock(v);
    
    inf.parity = 0;
    v = jsvObjectGetChild(options, "parity", 0);
    if(jsvIsString(v)) {
      if(jsvIsStringEqual(v, "o") || jsvIsStringEqual(v, "odd"))
        inf.parity = 1;
      else if(jsvIsStringEqual(v, "e") || jsvIsStringEqual(v, "even"))
        inf.parity = 2;
    } else if(jsvIsInt(v)) {
      inf.parity = (unsigned char)jsvGetInteger(v);
    }
    jsvUnLock(v);
    if (inf.parity>2) {
      jsExceptionHere(JSET_ERROR, "Invalid parity %d", inf.parity);
      return;
    }

    v = jsvObjectGetChild(options, "stopbits", 0);
    if (jsvIsInt(v)) 
      inf.stopbits = (unsigned char)jsvGetInteger(v);
    jsvUnLock(v);
  }

  jshUSARTSetup(device, &inf);
  // Set baud rate in object, so we can initialise it on startup
  if (inf.baudRate != DEFAULT_BAUD_RATE) {
    jsvUnLock(jsvObjectSetChild(parent, USART_BAUDRATE_NAME, jsvNewFromInteger(inf.baudRate)));
  } else
    jsvRemoveNamedChild(parent, USART_BAUDRATE_NAME);
  // Do the same for options
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}
Example #10
0
/*JSON{
  "type" : "method",
  "class" : "Object",
  "name" : "emit",
  "generate" : "jswrap_object_emit",
  "params" : [
    ["event","JsVar","The name of the event, for instance 'data'"],
    ["args","JsVarArray","Optional arguments"]
  ]
}
Call the event listeners for this object, for instance ```http.emit('data', 'Foo')```. See Node.js's EventEmitter.
*/
void jswrap_object_emit(JsVar *parent, JsVar *event, JsVar *argArray) {
  if (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper object - not a String, Integer, etc.");
      return;
    }
  if (!jsvIsString(event)) {
    jsWarn("First argument to EventEmitter.emit(..) must be a string");
    return;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);

  // extract data
  const int MAX_ARGS = 4;
  JsVar *args[MAX_ARGS];
  int n = 0;
  JsvObjectIterator it;
  jsvObjectIteratorNew(&it, argArray);
  while (jsvObjectIteratorHasValue(&it)) {
    if (n>=MAX_ARGS) {
      jsWarn("Too many arguments");
      break;
    }
    args[n++] = jsvObjectIteratorGetValue(&it);
    jsvObjectIteratorNext(&it);
  }
  jsvObjectIteratorFree(&it);


  jsiQueueObjectCallbacks(parent, eventName, args, n);
  // unlock
  while (n--)
    jsvUnLock(args[n]);
}
Example #11
0
/*JSON{
  "type" : "method",
  "class" : "OneWire",
  "name" : "select",
  "generate" : "jswrap_onewire_select",
  "params" : [
    ["rom","JsVar","The device to select (get this using `OneWire.search()`)"]
  ]
}
Select a ROM - always performs a reset first
 */
void jswrap_onewire_select(JsVar *parent, JsVar *rom) {
  Pin pin = onewire_getpin(parent);
  if (!jshIsPinValid(pin)) return;
  if (!jsvIsString(rom) || jsvGetStringLength(rom)!=16) {
    jsExceptionHere(JSET_TYPEERROR, "Invalid OneWire device address %q", rom);
    return;
  }

  // perform a reset
  OneWireReset(pin);

  // decode the address
  unsigned long long romdata = 0;
  JsvStringIterator it;
  jsvStringIteratorNew(&it, rom, 0);
  int i;
  for (i=0;i<8;i++) {
    char b[3];
    b[0] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[1] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[2] = 0;
    romdata = romdata | (((unsigned long long)stringToIntWithRadix(b,16,NULL,NULL)) << (i*8));

  }
  jsvStringIteratorFree(&it);

  // finally write data out
  OneWireWrite(pin, 8, 0x55);
  OneWireWrite(pin, 64, romdata);
}
Example #12
0
/*JSON{
  "type" : "method",
  "class" : "Object",
  "name" : "emit",
  "generate" : "jswrap_object_emit",
  "params" : [
    ["event","JsVar","The name of the event, for instance 'data'"],
    ["args","JsVarArray","Optional arguments"]
  ]
}
Call the event listeners for this object, for instance ```http.emit('data', 'Foo')```. See Node.js's EventEmitter.
 */
void jswrap_object_emit(JsVar *parent, JsVar *event, JsVar *argArray) {
  if (!jsvHasChildren(parent)) {
    jsWarn("Parent must be an object - not a String, Integer, etc.");
    return;
  }
  if (!jsvIsString(event)) {
    jsWarn("First argument to EventEmitter.emit(..) must be a string");
    return;
  }
  char eventName[16];
  if (!jswrap_object_get_event_name(eventName, event)) return;

  // extract data
  const unsigned int MAX_ARGS = 4;
  JsVar *args[MAX_ARGS];
  unsigned int n = 0;
  JsvObjectIterator it;
  jsvObjectIteratorNew(&it, argArray);
  while (jsvObjectIteratorHasValue(&it)) {
    if (n>=MAX_ARGS) {
      jsWarn("Too many arguments");
      break;
    }
    args[n++] = jsvObjectIteratorGetValue(&it);
    jsvObjectIteratorNext(&it);
  }
  jsvObjectIteratorFree(&it);


  jsiQueueObjectCallbacks(parent, eventName, args, (int)n);
  // unlock
  jsvUnLockMany(n, args);
}
Example #13
0
/*JSON{
  "type" : "constructor",
  "class" : "Date",
  "name" : "Date",
  "generate" : "jswrap_date_constructor",
  "params" : [
    ["args","JsVarArray","Either nothing (current time), one numeric argument (milliseconds since 1970), a date string (see `Date.parse`), or [year, month, day, hour, minute, second, millisecond] "]
  ],
  "return" : ["JsVar","A Date object"],
  "return_object" : "Date"
}
Creates a date object
*/
JsVar *jswrap_date_constructor(JsVar *args) {
  JsVarFloat time = 0;

  if (jsvGetArrayLength(args)==0) {
    time = jswrap_date_now();
  } else if (jsvGetArrayLength(args)==1) {
    JsVar *arg = jsvGetArrayItem(args, 0);
    if (jsvIsNumeric(arg))
      time = jsvGetFloat(arg);
    else if (jsvIsString(arg))
      time = jswrap_date_parse(arg);
    else
      jsWarn("Variables of type %t are not supported in date constructor", arg);
    jsvUnLock(arg);
  } else {
    CalendarDate date;
    date.year = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 0));
    date.month = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 1));
    date.day = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 2));
    TimeInDay td;
    td.daysSinceEpoch = fromCalenderDate(&date);
    td.hour = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 3));
    td.min = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 4));
    td.sec = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 5));
    td.ms = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 6));
    td.zone = 0;
    time = fromTimeInDay(&td);
  }

  return jswrap_date_from_milliseconds(time);
}
Example #14
0
/*JSON{
  "type" : "method",
  "ifndef" : "SAVE_ON_FLASH",
  "class" : "RegExp",
  "name" : "exec",
  "params" : [
    ["str","JsVar","A string to match on"]
  ],
  "generate" : "jswrap_regexp_exec",
  "return" : ["JsVar","A result array, or null"]
}
Test this regex on a string - returns a result array on success, or `null` otherwise.


`/Wo/.exec("Hello World")` will return:

```
[
 "Wo",
 "index": 6,
 "input": "Hello World"
]
```

Or with groups `/W(o)rld/.exec("Hello World")` returns:

```
[
 "World",
 "o", "index": 6,
 "input": "Hello World"
]
```

 */
JsVar *jswrap_regexp_exec(JsVar *parent, JsVar *arg) {
  JsVar *str = jsvAsString(arg);
  JsVarInt lastIndex = jsvGetIntegerAndUnLock(jsvObjectGetChild(parent, "lastIndex", 0));
  JsVar *regex = jsvObjectGetChild(parent, "source", 0);
  if (!jsvIsString(regex)) {
    jsvUnLock2(str,regex);
    return 0;
  }
  size_t regexLen = jsvGetStringLength(regex);
  char *regexPtr = (char *)alloca(regexLen+1);
  if (!regexPtr) {
    jsvUnLock2(str,regex);
    return 0;
  }
  jsvGetString(regex, regexPtr, regexLen+1);
  jsvUnLock(regex);
  JsVar *rmatch = match(regexPtr, str, (size_t)lastIndex, jswrap_regexp_hasFlag(parent,'i'));
  jsvUnLock(str);
  if (!rmatch) {
    rmatch = jsvNewWithFlags(JSV_NULL);
    lastIndex = 0;
  } else {
    // if it's global, set lastIndex
    if (jswrap_regexp_hasFlag(parent,'g')) {
      JsVar *matchStr = jsvGetArrayItem(rmatch,0);
      lastIndex = jsvGetIntegerAndUnLock(jsvObjectGetChild(rmatch, "index", 0)) +
                  (JsVarInt)jsvGetStringLength(matchStr);
      jsvUnLock(matchStr);
    } else
      lastIndex = 0;
  }
  jsvObjectSetChildAndUnLock(parent, "lastIndex", jsvNewFromInteger(lastIndex));
  return rmatch;
}
Example #15
0
/*JSON{
  "type" : "constructor",
  "ifndef" : "SAVE_ON_FLASH",
  "class" : "RegExp",
  "name" : "RegExp",
  "generate" : "jswrap_regexp_constructor",
  "params" : [
    ["regex","JsVar","A regular expression as a string"],
    ["regex","JsVar","Flags for the regular expression as a string"]
  ],
  "return" : ["JsVar","A RegExp object"],
  "return_object" : "RegExp"
}
Creates a RegExp object, for handling Regular Expressions
 */
JsVar *jswrap_regexp_constructor(JsVar *str, JsVar *flags) {
  if (!jsvIsString(str)) {
    jsExceptionHere(JSET_TYPEERROR, "Expecting String as first argument, got %t", str);
    return 0;
  }
  JsVar *r = jspNewObject(0,"RegExp");
  jsvObjectSetChild(r, "source", str);
  if (!jsvIsUndefined(flags)) {
    if (!jsvIsString(flags))
      jsExceptionHere(JSET_TYPEERROR, "Expecting String as first argument, got %t", str);
    else
      jsvObjectSetChild(r, "flags", flags);
  }
  jsvObjectSetChildAndUnLock(r, "lastIndex", jsvNewFromInteger(0));
  return r;
}
Example #16
0
/*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;
  }
}
Example #17
0
/*JSON{
  "type" : "method",
  "class" : "Object",
  "name" : "removeAllListeners",
  "generate" : "jswrap_object_removeAllListeners",
  "params" : [
    ["event","JsVar","The name of the event, for instance 'data'"]
  ]
}
Removes all listeners, or those of the specified event.
 */
void jswrap_object_removeAllListeners(JsVar *parent, JsVar *event) {
  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 *eventList = jsvFindChildFromVar(parent, eventName, true);
    jsvUnLock(eventName);
    if (eventList) {
      jsvRemoveChild(parent, eventList);
      jsvUnLock(eventList);
    }
  } else if (jsvIsUndefined(event)) {
    // Eep. We must remove everything beginning with '#on' (JS_EVENT_PREFIX)
    JsvObjectIterator it;
    jsvObjectIteratorNew(&it, parent);
    while (jsvObjectIteratorHasValue(&it)) {
      JsVar *key = jsvObjectIteratorGetKey(&it);
      jsvObjectIteratorNext(&it);
      if (jsvIsStringEqualOrStartsWith(key, JS_EVENT_PREFIX, true)) {
        // begins with #on - we must kill it
        jsvRemoveChild(parent, key);
      }
      jsvUnLock(key);
    }
    jsvObjectIteratorFree(&it);
  } else {
    jsWarn("First argument to EventEmitter.removeAllListeners(..) must be a string, or undefined");
    return;
  }
}
Example #18
0
/*JSON{
  "type" : "method",
  "class" : "Object",
  "name" : "on",
  "generate" : "jswrap_object_on",
  "params" : [
    ["event","JsVar","The name of the event, for instance 'data'"],
    ["listener","JsVar","The listener to call when this event is received"]
  ]
}
Register an event listener for this object, for instance ```http.on('data', function(d) {...})```. See Node.js's EventEmitter.
*/
void jswrap_object_on(JsVar *parent, JsVar *event, JsVar *listener) {
  if (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper object - not a String, Integer, etc.");
      return;
    }
  if (!jsvIsString(event)) {
      jsWarn("First argument to EventEmitter.on(..) must be a string");
      return;
    }
  if (!jsvIsFunction(listener) && !jsvIsString(listener)) {
    jsWarn("Second argument to EventEmitter.on(..) must be a function or a String (containing code)");
    return;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);

  JsVar *eventList = jsvFindChildFromString(parent, eventName, true);
  JsVar *eventListeners = jsvSkipName(eventList);
  if (jsvIsUndefined(eventListeners)) {
    // just add
    jsvSetValueOfName(eventList, listener);
  } else {
    if (jsvIsArray(eventListeners)) {
      // we already have an array, just add to it
      jsvArrayPush(eventListeners, listener);
    } else {
      // not an array - we need to make it an array
      JsVar *arr = jsvNewWithFlags(JSV_ARRAY);
      jsvArrayPush(arr, eventListeners);
      jsvArrayPush(arr, listener);
      jsvSetValueOfName(eventList, arr);
      jsvUnLock(arr);
    }
  }
  jsvUnLock(eventListeners);
  jsvUnLock(eventList);
  /* Special case if we're a data listener and data has already arrived then
   * we queue an event immediately. */
  if (jsvIsStringEqual(event, "data")) {
    JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0);
    if (jsvIsString(buf)) {
      jsiQueueObjectCallbacks(parent, "#ondata", &buf, 1);
      jsvRemoveNamedChild(parent, STREAM_BUFFER_NAME);
    }
    jsvUnLock(buf);
  }
}
Example #19
0
/*JSON{ "type":"function", "name" : "require",
         "description" : "Load the given module, and return the exported functions",
         "generate" : "jswrap_require",
         "params" : [ [ "moduleName", "JsVar", "A String containing the name of the given module"] ],
         "return" : ["JsVar", "The result of evaluating the string"]
}*/
JsVar *jswrap_require(JsVar *moduleName) {
  if (!jsvIsString(moduleName)) {
    jsWarn("Expecting a module name as a string, but got %t", moduleName);
    return 0;
  }
  // Search to see if we have already loaded this module

  JsVar *moduleList = jswrap_modules_getModuleList();
  if (!moduleList) return 0; // out of memory
  JsVar *moduleExportName = jsvFindChildFromVar(moduleList, moduleName, true);
  jsvUnLock(moduleList);
  if (!moduleExportName) return 0; // out of memory
  JsVar *moduleExport = jsvSkipName(moduleExportName);
  if (moduleExport) {
    // Found the module!
    jsvUnLock(moduleExportName);
    return moduleExport;
  }

  // Now check if it is built-in
  char moduleNameBuf[32];
  jsvGetString(moduleName, moduleNameBuf, sizeof(moduleNameBuf));
  if (jswIsBuiltInLibrary(moduleNameBuf)) {
    // create a 'fake' module that Espruino can use to map its built-in functions against
    moduleExport = jspNewBuiltin(moduleNameBuf);
  } else {
    // Now try and load it
    JsVar *fileContents = 0;
    //if (jsvIsStringEqual(moduleName,"http")) {}
    //if (jsvIsStringEqual(moduleName,"fs")) {}
  #ifdef USE_FILESYSTEM
    JsVar *modulePath = jsvNewFromString(
  #ifdef LINUX
        "node_modules/"
  #else
        "NODE_M~1/"
  #endif
        );
    if (!modulePath) { jsvUnLock(moduleExportName); return 0; } // out of memory
    jsvAppendStringVarComplete(modulePath, moduleName);
    jsvAppendString(modulePath,".js");
    fileContents = wrap_fat_readFile(modulePath);
    jsvUnLock(modulePath);
  #endif
    if (!fileContents || jsvIsStringEqual(fileContents,"")) {
      jsvUnLock(moduleExportName);
      jsvUnLock(fileContents);
      jsWarn("Module not found");
      return 0;
    }
    moduleExport = jspEvaluateModule(jsiGetParser(), fileContents);
    jsvUnLock(fileContents);
  }

  assert(moduleExport);
  jsvSetValueOfName(moduleExportName, moduleExport); // save in cache
  jsvUnLock(moduleExportName);
  return moduleExport;
}
Example #20
0
// Return how many bytes are available to read
JsVarInt jswrap_stream_available(JsVar *parent) {
  if (!jsvIsObject(parent)) return 0;
  JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0);
  JsVarInt chars = 0;
  if (jsvIsString(buf))
    chars = (JsVarInt)jsvGetStringLength(buf);
  jsvUnLock(buf);
  return chars;
}
Example #21
0
JsVar *jsvIteratorSetValue(JsvIterator *it, JsVar *value) {
  switch (it->type) {
  case JSVI_OBJECT : jsvObjectIteratorSetValue(&it->it.obj, value); break;
  case JSVI_STRING : jsvStringIteratorSetChar(&it->it.str, (char)(jsvIsString(value) ? value->varData.str[0] : (char)jsvGetInteger(value))); break;
  case JSVI_ARRAYBUFFER : jsvArrayBufferIteratorSetValueAndRewind(&it->it.buf, value); break;
  default: assert(0); break;
  }
  return value;
}
/*JSON{ "type":"method", "class": "Serial", "name" : "setup",
         "description" : "Setup this Serial port with the given baud rate and options",
         "generate" : "jswrap_serial_setup",
         "params" : [ [ "baudrate", "int", "The baud rate - the default is 9600"],
                      [ "options", "JsVar", ["An optional structure containing extra information on initialising the serial port.",
                                             "```{rx:pin,tx:pin}```",
                                             "Note that even after changing the RX and TX pins, if you have called setup before then the previous RX and TX pins will still be connected to the Serial port as well - until you set them to something else using digitalWrite" ] ] ]
}*/
void jswrap_serial_setup(JsVar *parent, JsVarInt baud, JsVar *options) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  JshUSARTInfo inf;
  jshUSARTInitInfo(&inf);

  if (baud>0) inf.baudRate = (int)baud;

  if (jsvIsObject(options)) {

    inf.pinRX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "rx", 0));
    inf.pinTX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "tx", 0));
    inf.bytesize = (unsigned char)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "bytesize", 0));

    JsVar *v;
    v = jsvObjectGetChild(options, "parity", 0);
    
    if(jsvIsNull(v)) {
      inf.parity = 0;
    }
    else if(jsvIsString(v)) {
      inf.parity = 0xFF;
      char s[8] = "";

      jsvGetString(v, s, sizeof(s) - 1);

      if(!strcmp(s, "o") || !strcmp(s, "odd")) {
        inf.parity = 1;
      }
      else if(!strcmp(s, "e") || !strcmp(s, "even")) {
        inf.parity = 2;
      }
    }
    else if(jsvIsInt(v)) {
      inf.parity = (unsigned char)jsvGetInteger(v);
    }

    jsvUnLock(v);

    v = jsvObjectGetChild(options, "stopbits", 0);
    inf.stopbits = (unsigned char)jsvGetInteger(v);
    jsvUnLock(v);
  }

  jshUSARTSetup(device, &inf);
  // Set baud rate in object, so we can initialise it on startup
  if (baud != DEFAULT_BAUD_RATE) {
    JsVar *baudVar = jsvNewFromInteger(baud);
    jsvUnLock(jsvSetNamedChild(parent, baudVar, USART_BAUDRATE_NAME));
    jsvUnLock(baudVar);
  } else
    jsvRemoveNamedChild(parent, USART_BAUDRATE_NAME);
  // Do the same for options
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}
Example #23
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "startsWith",
  "ifndef" : "SAVE_ON_FLASH",
  "generate" : "jswrap_string_startsWith",
  "params" : [
    ["searchString","JsVar","The string to search for"],
    ["position","int","The start character index (or 0 if not defined)"]
  ],
  "return" : ["bool","`true` if the given characters are found at the beginning of the string, otherwise, `false`."]
}
*/
bool jswrap_string_startsWith(JsVar *parent, JsVar *search, int position) {
  if (!jsvIsString(parent)) return false;
  JsVar *searchStr = jsvAsString(search);
  bool match = false;
  if (position >= 0 &&
      jsvGetStringLength(searchStr)+position <= jsvGetStringLength(parent))
   match = jsvCompareString(parent, searchStr, position,0,true)==0;
  jsvUnLock(searchStr);
  return match;
}
/*JSON{ "type":"property", "class": "Object", "name" : "length",
         "description" : "Find the length of the object",
         "generate" : "jswrap_object_length",
         "return" : ["JsVar", "The value of the string"]
}*/
JsVar *jswrap_object_length(JsVar *parent) {
  if (jsvIsArray(parent)) {
    return jsvNewFromInteger(jsvGetArrayLength(parent));
  } else if (jsvIsArrayBuffer(parent)) {
      return jsvNewFromInteger((JsVarInt)jsvGetArrayBufferLength(parent));
  } else if (jsvIsString(parent)) {
    return jsvNewFromInteger((JsVarInt)jsvGetStringLength(parent));
  }
  return 0;
}
Example #25
0
void jsfGetJSONWhitespace(JsVar *var, JsVar *result, JSONFlags flags, const char *whitespace) {
  assert(jsvIsString(result));
  JsvStringIterator it;
  jsvStringIteratorNew(&it, result, 0);
  jsvStringIteratorGotoEnd(&it);

  jsfGetJSONWithCallback(var, flags, whitespace, (vcbprintf_callback)&jsvStringIteratorPrintfCallback, &it);

  jsvStringIteratorFree(&it);
}
Example #26
0
/*JSON{ "type":"staticmethod",
         "class" : "Modules", "name" : "addCached",
         "description" : "Add the given module to the cache",
         "generate" : "jswrap_modules_addCached",
         "params" : [ [ "id", "JsVar", "The module name to add" ],
                      [  "sourcecode", "JsVar", "The module's sourcecode" ] ]
}*/
void jswrap_modules_addCached(JsVar *id, JsVar *sourceCode) {
  if (!jsvIsString(id) || !jsvIsString(sourceCode)) {
    jsError("Both arguments to addCached must be strings");
    return;
  }

  JsVar *moduleList = jswrap_modules_getModuleList();
  if (!moduleList) return; // out of memory

  JsVar *moduleExport = jspEvaluateModule(jsiGetParser(), sourceCode);
  if (!moduleExport) {
    jsWarn("Unable to load module");
  } else {
    JsVar *moduleName = jsvFindChildFromVar(moduleList, id, true);
    if (moduleName) jsvSetValueOfName(moduleName, moduleExport);
    jsvUnLock(moduleExport);
  }
  jsvUnLock(moduleList);

}
Example #27
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "match",
  "generate" : "jswrap_string_match",
  "params" : [
    ["subStr","JsVar","Substring or RegExp to match"]
  ],
  "return" : ["JsVar","This match array"]
}
Matches `subStr` occurrence in the string.
 */
JsVar *jswrap_string_match(JsVar *parent, JsVar *subStr) {
  if (!jsvIsString(parent)) return 0;
  if (jsvIsUndefined(subStr)) return 0;

#ifndef SAVE_ON_FLASH
  // Use RegExp if one is passed in
  if (jsvIsInstanceOf(subStr, "RegExp")) {
    jsvObjectSetChildAndUnLock(subStr, "lastIndex", jsvNewFromInteger(0));
    JsVar *match;
    match = jswrap_regexp_exec(subStr, parent);
    if (!jswrap_regexp_hasFlag(subStr,'g')) {
      return match;
    }

    // global
    JsVar *array = jsvNewEmptyArray();
    if (!array) return 0; // out of memory
    while (match && !jsvIsNull(match)) {
      // get info about match
      JsVar *matchStr = jsvGetArrayItem(match,0);
      JsVarInt idx = jsvGetIntegerAndUnLock(jsvObjectGetChild(match,"index",0));
      JsVarInt len = (JsVarInt)jsvGetStringLength(matchStr);
      int last = idx+len;
      jsvArrayPushAndUnLock(array, matchStr);
      // search again
      jsvUnLock(match);
      jsvObjectSetChildAndUnLock(subStr, "lastIndex", jsvNewFromInteger(last));
      match = jswrap_regexp_exec(subStr, parent);
    }
    jsvUnLock(match);
    jsvObjectSetChildAndUnLock(subStr, "lastIndex", jsvNewFromInteger(0));
    return array;
  }
#endif

  subStr = jsvAsString(subStr);

  int idx = jswrap_string_indexOf(parent, subStr, 0, false);
  if (idx>=0) {
      JsVar *array = jsvNewEmptyArray();
      if (!array) {
        jsvUnLock(subStr);
        return 0; // out of memory
      }

      jsvArrayPush(array, subStr);
      jsvObjectSetChildAndUnLock(array, "index", jsvNewFromInteger(idx));
      jsvObjectSetChildAndUnLock(array, "input", subStr);
      return array;
  }
  jsvUnLock(subStr);
  return NULL;
}
Example #28
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "endsWith",
  "ifndef" : "SAVE_ON_FLASH",
  "generate" : "jswrap_string_endsWith",
  "params" : [
    ["searchString","JsVar","The string to search for"],
    ["length","JsVar","The 'end' of the string - if left off the actual length of the string is used"]
  ],
  "return" : ["bool","`true` if the given characters are found at the end of the string, otherwise, `false`."]
}
*/
bool jswrap_string_endsWith(JsVar *parent, JsVar *search, JsVar *length) {
  if (!jsvIsString(parent)) return false;
  int position = jsvIsNumeric(length) ? jsvGetInteger(length) : (int)jsvGetStringLength(parent);
  JsVar *searchStr = jsvAsString(search);
  position -= jsvGetStringLength(searchStr);
  bool match = false;
  if (position >= 0 &&
      jsvGetStringLength(searchStr)+position <= jsvGetStringLength(parent))
    match = jsvCompareString(parent, searchStr, position,0,true)==0;
  jsvUnLock(searchStr);
  return match;
}
Example #29
0
/*JSON{ "type":"staticmethod",
         "class" : "WLAN", "name" : "connect",
         "generate" : "jswrap_wlan_connect",
         "description" : "Connect to a wireless network",
         "params" : [ [ "ap", "JsVar", "Access point name" ],
                      [ "key", "JsVar", "WPA2 key (or undefined for unsecured connection)" ] ],
         "return" : ["int", ""]
}*/
JsVarInt jswrap_wlan_connect(JsVar *vAP, JsVar *vKey) {
  char ap[32];
  char key[32];
  unsigned long security = WLAN_SEC_UNSEC;
  jsvGetString(vAP, ap, sizeof(ap));
  if (jsvIsString(vKey)) {
    security = WLAN_SEC_WPA2;
    jsvGetString(vKey, key, sizeof(key));
  }
  // might want to set wlan_ioctl_set_connection_policy
  return wlan_connect(security, ap, strlen(ap), NULL, key, strlen(key));
}
/*JSON{ "type":"method", "class": "Object", "name" : "emit",
         "description" : ["Call the event listeners for this object, for instance ```http.emit('data', 'Foo')```. See Node.js's EventEmitter."],
         "generate" : "jswrap_object_emit",
         "params" : [ [ "event", "JsVar", "The name of the event, for instance 'data'"],
                      [ "v1", "JsVar", "Optional argument 1"],
                      [ "v2", "JsVar", "Optional argument 2"]  ]
}*/
void jswrap_object_emit(JsVar *parent, JsVar *event, JsVar *v1, JsVar *v2) {
  if (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper object - not a String, Integer, etc.");
      return;
    }
  if (!jsvIsString(event)) {
    jsWarn("First argument to EventEmitter.emit(..) must be a string");
    return;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);
  jsiQueueObjectCallbacks(parent, eventName, v1, v2);
}