Exemplo n.º 1
0
void httpServerResponseData(JsVar *httpServerResponseVar, JsVar *data) {
  // Append data to sendData
  JsVar *sendData = jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_SEND_DATA, 0);
  if (!sendData) {
    // no sendData, so no headers - add them!
    JsVar *sendHeaders = jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_HEADERS, 0);
    if (sendHeaders) {
      sendData = jsvNewFromEmptyString();
      jsvAppendPrintf(sendData, "HTTP/1.0 %d OK\r\nServer: Espruino "JS_VERSION"\r\n", jsvGetIntegerAndUnLock(jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_CODE, 0)));
      httpAppendHeaders(sendData, sendHeaders);
      jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_HEADERS, 0);
      jsvUnLock(sendHeaders);
      // finally add ending newline
      jsvAppendString(sendData, "\r\n");
    } else {
      // we have already sent headers
      sendData = jsvNewFromEmptyString();
    }
    jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_SEND_DATA, sendData);
  }
  if (sendData && !jsvIsUndefined(data)) {
    JsVar *s = jsvAsString(data, false);
    if (s) jsvAppendStringVarComplete(sendData,s);
    jsvUnLock(s);
  }
  jsvUnLock(sendData);
}
Exemplo n.º 2
0
// returns 0 on success and a (negative) error number on failure
int socketSendData(JsNetwork *net, JsVar *connection, int sckt, JsVar **sendData) {
    char *buf = alloca(net->chunkSize); // allocate on stack

    assert(!jsvIsEmptyString(*sendData));

    size_t bufLen = httpStringGet(*sendData, buf, net->chunkSize);
    int num = netSend(net, sckt, buf, bufLen);
    if (num < 0) return num; // an error occurred
    // Now cut what we managed to send off the beginning of sendData
    if (num > 0) {
        JsVar *newSendData = 0;
        if (num < (int)jsvGetStringLength(*sendData)) {
            // we didn't send all of it... cut out what we did send
            newSendData = jsvNewFromStringVar(*sendData, (size_t)num, JSVAPPENDSTRINGVAR_MAXLENGTH);
        } else {
            // we sent all of it! Issue a drain event, unless we want to close, then we shouldn't
            // callback for more data
            bool wantClose = jsvGetBoolAndUnLock(jsvObjectGetChild(connection,HTTP_NAME_CLOSE,0));
            if (!wantClose) {
                jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_DRAIN, &connection, 1);
            }
            newSendData = jsvNewFromEmptyString();
        }
        jsvUnLock(*sendData);
        *sendData = newSendData;
    }

    return 0;
}
Exemplo n.º 3
0
/*JSON{ "type":"method", "class": "String", "name" : "split",
         "description" : "Return an array made by splitting this string up by the separator. eg. ```'1,2,3'.split(',')==[1,2,3]```",
         "generate" : "jswrap_string_split",
         "params" : [ [ "separator", "JsVar", "The start character index"] ],
         "return" : ["JsVar", "Part of this string from start for len characters"]
}*/
JsVar *jswrap_string_split(JsVar *parent, JsVar *split) {
  JsVar *array;
  int last, idx, arraylen=0;
  int splitlen =  (int)jsvGetStringLength(split);
  int l = (int)jsvGetStringLength(parent) - splitlen;
  last = 0;

  array = jsvNewWithFlags(JSV_ARRAY);
  if (!array) return 0; // out of memory

  for (idx=0;idx<=l;idx++) {
    if (idx==l || jsvCompareString(parent, split, idx, 0, true)==0) {
      JsVar *part = jsvNewFromEmptyString();
      if (!part) break; // out of memory
      JsVar *idxvar = jsvMakeIntoVariableName(jsvNewFromInteger(arraylen++), part);
      if (idxvar) { // could be out of memory
        if (idx==l) idx=l+splitlen; // if the last element, do to the end of the string
        jsvAppendStringVar(part, parent, last, idx-last);
        jsvAddName(array, idxvar);
        last = idx+splitlen;
        jsvUnLock(idxvar);
      }
      jsvUnLock(part);
    }
  }
  return array;
}
Exemplo n.º 4
0
JsVar *jslNewStringFromLexer(JslCharPos *charFrom, size_t charTo) {
  // Original method - just copy it verbatim
  size_t maxLength = charTo + 1 - jsvStringIteratorGetIndex(&charFrom->it);
  assert(maxLength>0); // will fail if 0
  // Try and create a flat string first
  JsVar *var = 0;
  if (maxLength > JSV_FLAT_STRING_BREAK_EVEN) {
    var = jsvNewFlatStringOfLength((unsigned int)maxLength);
    if (var) {
      // Flat string
      char *flatPtr = jsvGetFlatStringPointer(var);
      *(flatPtr++) = charFrom->currCh;
      JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
      while (jsvStringIteratorHasChar(&it) && (--maxLength>0)) {
        *(flatPtr++) = jsvStringIteratorGetChar(&it);
        jsvStringIteratorNext(&it);
      }
      jsvStringIteratorFree(&it);
      return var;
    }
  }
  // Non-flat string...
  var = jsvNewFromEmptyString();
  if (!var) { // out of memory
    return 0;
  }

  //jsvAppendStringVar(var, lex->sourceVar, charFrom->it->index, (int)(charTo-charFrom));
  JsVar *block = jsvLockAgain(var);
  block->varData.str[0] = charFrom->currCh;
  size_t blockChars = 1;

  size_t l = maxLength;
  // now start appending
  JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
  while (jsvStringIteratorHasChar(&it) && (--maxLength>0)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (blockChars >= jsvGetMaxCharactersInVar(block)) {
      jsvSetCharactersInVar(block, blockChars);
      JsVar *next = jsvNewWithFlags(JSV_STRING_EXT_0);
      if (!next) break; // out of memory
      // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
      jsvSetLastChild(block, jsvGetRef(next));
      jsvUnLock(block);
      block = next;
      blockChars=0; // it's new, so empty
    }
    block->varData.str[blockChars++] = ch;
    jsvStringIteratorNext(&it);
  }
  jsvSetCharactersInVar(block, blockChars);
  jsvUnLock(block);
  // Just make sure we only assert if there's a bug here. If we just ran out of memory or at end of string it's ok
  assert((l == jsvGetStringLength(var)) || (jsErrorFlags&JSERR_MEMORY) || !jsvStringIteratorHasChar(&it));
  jsvStringIteratorFree(&it);


  return var;
}
Exemplo n.º 5
0
/*JSON{ "type":"method", "class": "String", "name" : "charAt",
         "description" : "Return a single character at the given position in the String.",
         "generate" : "jswrap_string_charAt",
         "params" : [ [ "pos", "int", "The character number in the string. Negative values return characters from end of string (-1 = last char)"] ],
         "return" : ["JsVar", "The character in the string"]
}*/
JsVar *jswrap_string_charAt(JsVar *parent, JsVarInt idx) {
  // We do this so we can handle '/0' in a string
  JsVar *r = jsvNewFromEmptyString();
  if (r) { // out of mem?
    char ch = jsvGetCharInString(parent, (int)idx);
    jsvAppendStringBuf(r, &ch, 1);
  }
  return r;
}
Exemplo n.º 6
0
/*JSON{ "type":"staticmethod", "class": "String", "name" : "fromCharCode",
         "description" : "Return the character represented by the given character code.",
         "generate" : "jswrap_string_fromCharCode",
         "params" : [ [ "code", "int", "The character code to create a character from (range 0-255)"] ],
         "return" : ["JsVar", "The character"]
}*/
JsVar *jswrap_string_fromCharCode(JsVarInt code) {
  // We do this so we can handle '/0' in a string
  JsVar *r = jsvNewFromEmptyString();
  if (r) { // out of mem?
    char ch = code;
    jsvAppendStringBuf(r, &ch, 1);
  }
  return r;
}
Exemplo n.º 7
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "repeat",
  "ifndef" : "SAVE_ON_FLASH",
  "generate" : "jswrap_string_repeat",
  "params" : [
    ["count","int","An integer with the amount of times to repeat this String"]
  ],
  "return" : ["JsVar","A string containing repetitions of this string"],
  "return_object" : "String"
}
Repeat this string the given number of times.
*/
JsVar *jswrap_string_repeat(JsVar *parent, int count) {
  if (count<0) {
    jsExceptionHere(JSET_ERROR, "Invalid count value");
    return 0;
  }
  JsVar *result = jsvNewFromEmptyString();
  while (count-- && !jspIsInterrupted())
    jsvAppendStringVarComplete(result, parent);
  return result;
}
Exemplo n.º 8
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "substr",
  "generate" : "jswrap_string_substr",
  "params" : [
    ["start","int","The start character index"],
    ["len","JsVar","The number of characters"]
  ],
  "return" : ["JsVar","Part of this string from start for len characters"]
}*/
JsVar *jswrap_string_substr(JsVar *parent, JsVarInt pStart, JsVar *vLen) {
  JsVar *res;
  JsVarInt pLen = jsvIsUndefined(vLen) ? JSVAPPENDSTRINGVAR_MAXLENGTH : (int)jsvGetInteger(vLen);
  if (pLen<0) pLen = 0;
  if (pStart<0) pStart += (JsVarInt)jsvGetStringLength(parent);
  if (pStart<0) pStart = 0;
  res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory
  jsvAppendStringVar(res, parent, (size_t)pStart, (size_t)pLen);
  return res;
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "slice",
  "generate" : "jswrap_string_slice",
  "params" : [
    ["start","int","The start character index, if negative it is from the end of the string"],
    ["end","JsVar","The end character index, if negative it is from the end of the string, and if omitted it is the end of the string"]
  ],
  "return" : ["JsVar","Part of this string from start for len characters"]
}*/
JsVar *jswrap_string_slice(JsVar *parent, JsVarInt pStart, JsVar *vEnd) {
  JsVar *res;
  JsVarInt pEnd = jsvIsUndefined(vEnd) ? JSVAPPENDSTRINGVAR_MAXLENGTH : (int)jsvGetInteger(vEnd);
  if (pStart<0) pStart += (JsVarInt)jsvGetStringLength(parent);
  if (pEnd<0) pEnd += (JsVarInt)jsvGetStringLength(parent);
  if (pStart<0) pStart = 0;
  if (pEnd<0) pEnd = 0;
  res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory
  if (pEnd>pStart)
    jsvAppendStringVar(res, parent, (size_t)pStart, (size_t)(pEnd-pStart));
  return res;
}
Exemplo n.º 11
0
/*JSON{  "type" : "method", "class" : "File", "name" : "read",
         "generate" : "jswrap_file_read",
         "description" : [ "Read data in a file in byte size chunks"],
         "params" : [ ["length", "int32", "is an integer specifying the number of bytes to read."] ],
         "return" : [ "JsVar", "A string containing the characters that were read" ]
}*/
JsVar *jswrap_file_read(JsVar* parent, int length) {
  JsVar *buffer = 0;
  JsvStringIterator it;
  FRESULT res = 0;
  size_t bytesRead = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data.mode == FM_READ || file.data.mode == FM_READ_WRITE) {
        char buf[32];
        size_t actual = 0;

        while (bytesRead < (size_t)length) {
          size_t requested = (size_t)length - bytesRead;
          if (requested > sizeof( buf ))
            requested = sizeof( buf );
          actual = 0;
    #ifndef LINUX
          res = f_read(&file.data.handle, buf, requested, &actual);
          if(res) break;
    #else
          actual = fread(buf, 1, requested, file.data.handle);
    #endif
          if (actual>0) {
            if (!buffer) {
              buffer = jsvNewFromEmptyString();
              if (!buffer) return 0; // out of memory
              jsvStringIteratorNew(&it, buffer, 0);
            }
            size_t i;
            for (i=0;i<actual;i++)
              jsvStringIteratorAppend(&it, buf[i]);
          }
          bytesRead += actual;
          if(actual != requested) break;
        }
        fileSetVar(&file);
      }
    }
  }
  if (res) jsfsReportError("Unable to read file", res);

  if (buffer)
    jsvStringIteratorFree(&it);

  // automatically close this file if we're at the end of it
  if (bytesRead!=(size_t)length)
    jswrap_file_close(parent);

  return buffer;
}
Exemplo n.º 12
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "charAt",
  "generate" : "jswrap_string_charAt",
  "params" : [
    ["pos","int","The character number in the string. Negative values return characters from end of string (-1 = last char)"]
  ],
  "return" : ["JsVar","The character in the string"]
}
Return a single character at the given position in the String.
*/
JsVar *jswrap_string_charAt(JsVar *parent, JsVarInt idx) {
  // We do this so we can handle '/0' in a string
  JsVar *r = jsvNewFromEmptyString();
  if (r && jsvIsString(parent) && idx>=0) {
    JsvStringIterator it;
    jsvStringIteratorNew(&it, parent, (size_t)idx);
    if (jsvStringIteratorHasChar(&it)) {
      char ch = jsvStringIteratorGetChar(&it);
      jsvAppendStringBuf(r, &ch, 1);
    }
    jsvStringIteratorFree(&it);
  }
  return r;
}
Exemplo n.º 13
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "substring",
  "generate" : "jswrap_string_substring",
  "params" : [
    ["start","int","The start character index"],
    ["end","JsVar","The end character index"]
  ],
  "return" : ["JsVar","The part of this string between start and end"]
}*/
JsVar *jswrap_string_substring(JsVar *parent, JsVarInt pStart, JsVar *vEnd) {
  JsVar *res;
  JsVarInt pEnd = jsvIsUndefined(vEnd) ? JSVAPPENDSTRINGVAR_MAXLENGTH : (int)jsvGetInteger(vEnd);
  if (pStart<0) pStart=0;
  if (pEnd<0) pEnd=0;
  if (pEnd<pStart) {
    JsVarInt l = pStart;
    pStart = pEnd;
    pEnd = l;
  }
  res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory
  jsvAppendStringVar(res, parent, (size_t)pStart, (size_t)(pEnd-pStart));
  return res;
}
Exemplo n.º 14
0
/*JSON{
  "type" : "function",
  "name" : "getSerial",
  "generate" : "jswrap_interface_getSerial",
  "return" : ["JsVar","The board's serial number"]
}
Get the serial number of this board
 */
JsVar *jswrap_interface_getSerial() {
  char buf[8];
  unsigned char serial[32];
  int i, serialSize = jshGetSerialNumber(serial, sizeof(serial));

  JsVar *str = jsvNewFromEmptyString();
  if (!str) return 0;

  for (i=0;i<serialSize;i++) {
    if ((i&3)==0 && i) jsvAppendString(str, "-");
    itostr(serial[i] | 0x100, buf, 16);
    jsvAppendString(str, &buf[1]);
  }
  return str;
}
Exemplo n.º 15
0
/*JSON{
  "type" : "staticmethod",
  "class" : "String",
  "name" : "fromCharCode",
  "generate" : "jswrap_string_fromCharCode",
  "params" : [
    ["code","JsVarArray","One or more character codes to create a string from (range 0-255)."]
  ],
  "return" : ["JsVar","The character"]
}
Return the character(s) represented by the given character code(s).
*/
JsVar *jswrap_string_fromCharCode(JsVar *arr) {
  assert(jsvIsArray(arr));

  JsVar *r = jsvNewFromEmptyString();
  if (!r) return 0;

  JsvObjectIterator it;
  jsvObjectIteratorNew(&it, arr);
  while (jsvObjectIteratorHasValue(&it)) {
    char ch = (char)jsvGetIntegerAndUnLock(jsvObjectIteratorGetValue(&it));
    jsvAppendStringBuf(r, &ch, 1);
    jsvObjectIteratorNext(&it);
  }
  jsvObjectIteratorFree(&it);

  return r;
}
Exemplo n.º 16
0
static void jslLexRegex() {
  lex->tokenValue = jsvNewFromEmptyString();
  if (!lex->tokenValue) {
    lex->tk = LEX_EOF;
    return;
  }
  JsvStringIterator it;
  jsvStringIteratorNew(&it, lex->tokenValue, 0);
  jsvStringIteratorAppend(&it, '/');
  // strings...
  jslGetNextCh();
  while (lex->currCh && lex->currCh!='/') {
    if (lex->currCh == '\\') {
      jsvStringIteratorAppend(&it, lex->currCh);
      jslGetNextCh();
    } else if (lex->currCh=='\n') {
      /* Was a newline - this is now allowed
       * unless we're a template string */
      break;
    }
    jsvStringIteratorAppend(&it, lex->currCh);
    jslGetNextCh();
  }
  lex->tk = LEX_REGEX;
  if (lex->currCh!='/') {
    lex->tk++; // +1 gets you to 'unfinished X'
  } else {
    jsvStringIteratorAppend(&it, '/');
    jslGetNextCh();
    // regex modifiers
    while (lex->currCh=='g' ||
        lex->currCh=='i' ||
        lex->currCh=='m' ||
        lex->currCh=='y' ||
        lex->currCh=='u') {
      jslTokenAppendChar(lex->currCh);
      jsvStringIteratorAppend(&it, lex->currCh);
      jslGetNextCh();
    }
  }
  jsvStringIteratorFree(&it);
}
Exemplo n.º 17
0
bool _http_send(SOCKET sckt, JsVar **sendData) {
  char buf[64];

  int a=1;
  int len = (int)jsvGetStringLength(*sendData);
  if (len>0) {
    size_t bufLen = httpStringGet(*sendData, buf, sizeof(buf));
    a = (int)send(sckt,buf,bufLen, MSG_NOSIGNAL);
    JsVar *newSendData = 0;
    if (a!=len) {
      newSendData = jsvNewFromEmptyString();
      jsvAppendStringVar(newSendData, *sendData, a, JSVAPPENDSTRINGVAR_MAXLENGTH);
    }
    jsvUnLock(*sendData);
    *sendData = newSendData;
  }
  if (a<=0) {
    httpError("Socket error while sending");
    return false;
  } return true;
}
Exemplo n.º 18
0
/*JSON{
  "type" : "staticmethod",
  "class" : "JSON",
  "name" : "stringify",
  "generate" : "jswrap_json_stringify",
  "params" : [
    ["data","JsVar","The data to be converted to a JSON string"],
    ["replacer","JsVar","This value is ignored"],
    ["space","JsVar","The number of spaces to use for padding, a string, or null/undefined for no whitespace "]
  ],
  "return" : ["JsVar","A JSON string"]
}
Convert the given object into a JSON string which can subsequently be parsed with JSON.parse or eval.

**Note:** This differs from JavaScript's standard `JSON.stringify` in that:

* The `replacer` argument is ignored
* Typed arrays like `new Uint8Array(5)` will be dumped as if they were arrays, not as if they were objects (since it is more compact)
 */
JsVar *jswrap_json_stringify(JsVar *v, JsVar *replacer, JsVar *space) {
  NOT_USED(replacer);
  JSONFlags flags = JSON_IGNORE_FUNCTIONS|JSON_NO_UNDEFINED|JSON_ARRAYBUFFER_AS_ARRAY;
  JsVar *result = jsvNewFromEmptyString();
  if (result) {// could be out of memory
    char whitespace[11] = "";
    if (jsvIsUndefined(space) || jsvIsNull(space)) {
      // nothing
    } else if (jsvIsNumeric(space)) {
      unsigned int s = (unsigned int)jsvGetInteger(space);
      if (s>10) s=10;
      whitespace[s] = 0;
      while (s) whitespace[--s]=' ';
    } else {
      jsvGetString(space, whitespace, sizeof(whitespace));
    }
    if (strlen(whitespace)) flags |= JSON_ALL_NEWLINES|JSON_PRETTY;
    jsfGetJSONWhitespace(v, result, flags, whitespace);
  }
  return result;
}
/*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", "JsVarName", "The name of the function to edit (either a string or just the unquoted name)"] ]
}*/
void jswrap_interface_edit(JsVar *funcName) {
  if (jsvIsString(funcName)) {
    JsVar *func = 0;
    if (jsvIsName(funcName))
      func = jsvSkipName(funcName);
    else
      func = jsvSkipNameAndUnLock(jsvFindChildFromVar(jsiGetParser()->root, funcName, 0));
    if (jsvIsFunction(func)) {
      JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false);
      JsVarRef scope = jsvGetRef(scopeVar);
      jsvUnLock(scopeVar);
      JsVar *newLine = jsvNewFromEmptyString();
      if (newLine) { // could be out of memory
        jsvAppendStringVarComplete(newLine, funcName);
        if (scope) {
          // If we have a scope, it's an internal function so we will need to write different code
          jsvAppendString(newLine, ".replaceWith(");
        } else {
          jsvAppendString(newLine, " = ");
        }
        JsVar *funcData = jsvAsString(func, false);
        if (funcData)
          jsvAppendStringVarComplete(newLine, funcData);
        jsvUnLock(funcData);
        if (scope) {
          jsvAppendString(newLine, ");");
        } else {
          jsvAppendString(newLine, ";");
        }
        jsiReplaceInputLine(newLine);
        jsvUnLock(newLine);
      }
    } else {
      jsError("Edit should be called with the name of a function");
    }
    jsvUnLock(func);
  } else {
    jsError("Edit should be called with edit(funcName) or edit('funcName')");
  }
}
Exemplo n.º 20
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "toUpperCase",
  "generate_full" : "jswrap_string_toUpperLowerCase(parent, true)",
  "params" : [

  ],
  "return" : ["JsVar","The uppercase version of this string"]
}*/
JsVar *jswrap_string_toUpperLowerCase(JsVar *parent, bool upper) {
  JsVar *res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory
  JsVar *parentStr = jsvAsString(parent);

  JsvStringIterator itsrc, itdst;
  jsvStringIteratorNew(&itsrc, parentStr, 0);
  jsvStringIteratorNew(&itdst, res, 0);

  while (jsvStringIteratorHasChar(&itsrc)) {
    char ch = jsvStringIteratorGetChar(&itsrc);
    ch = upper ? jsvStringCharToUpper(ch) : jsvStringCharToLower(ch);
    jsvStringIteratorAppend(&itdst, ch);
    jsvStringIteratorNext(&itsrc);
  }

  jsvStringIteratorFree(&itsrc);
  jsvStringIteratorFree(&itdst);
  jsvUnLock(parentStr);

  return res;
}
Exemplo n.º 21
0
// Return a string containing 'chars' bytes. If chars<=0 the string will be all available data
JsVar *jswrap_stream_read(JsVar *parent, JsVarInt chars) {
  if (!jsvIsObject(parent)) return 0;
  JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0);
  JsVar *data = 0;
  if (jsvIsString(buf)) {
    size_t len = jsvGetStringLength(buf);
    if (chars <= 0 || (size_t)chars>=len) {
      // return the whole buffer and remove it
      data = buf;
      buf = 0;
      jsvRemoveNamedChild(parent, STREAM_BUFFER_NAME);
    } else {
      // return just part of the buffer, and shorten it accordingly
      data = jsvNewFromStringVar(buf, 0, (size_t)chars);
      JsVar *newBuf = jsvNewFromStringVar(buf, (size_t)chars, JSVAPPENDSTRINGVAR_MAXLENGTH);
      jsvUnLock(jsvObjectSetChild(parent, STREAM_BUFFER_NAME, newBuf));
    }
  } else
    data = jsvNewFromEmptyString();
  jsvUnLock(buf);
  return data;
}
Exemplo n.º 22
0
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "readFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "wrap_fat_readFile",
         "description" : [ "Read all data from a file and return as a string" ],
         "params" : [ [ "path", "JsVar", "The path of the file to read" ] ],
         "return" : [ "JsVar", "A string containing the contents of the file" ]
}*/
JsVar *wrap_fat_readFile(JsVar *path) {
  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);

  JsVar *result = jsvNewFromEmptyString();
  if (!result) return 0; // out of memory

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    FIL file;
    if ((res=f_open(&file, pathStr, FA_READ)) == FR_OK) {
#else
    FILE *file = fopen(pathStr, "r");
    if (file) {
#endif
      // re-use pathStr buffer
      size_t bytesRead = JS_DIR_BUF_SIZE;
      while (res==FR_OK && bytesRead==JS_DIR_BUF_SIZE) {
#ifndef LINUX
        res = f_read (&file, pathStr, JS_DIR_BUF_SIZE, &bytesRead);
#else
        bytesRead = fread(pathStr,1,JS_DIR_BUF_SIZE,file);
#endif
        jsvAppendStringBuf(result, pathStr, (int)bytesRead);
      }
#ifndef LINUX
      f_close(&file);
#else
      fclose(file);
#endif
    }
  }

  if (res) jsfsReportError("Unable to read file", res);
  return result;
}
Exemplo n.º 23
0
JsVar *jslNewFromLexer(struct JsLex *lex, JslCharPos *charFrom, size_t charTo) {
  // Create a var
  JsVar *var = jsvNewFromEmptyString();
  if (!var) { // out of memory
    return 0;
  }

  //jsvAppendStringVar(var, lex->sourceVar, charFrom->it->index, (int)(charTo-charFrom));
  size_t maxLength = charTo - jsvStringIteratorGetIndex(&charFrom->it);
  JsVar *block = jsvLockAgain(var);
  block->varData.str[0] = charFrom->currCh;
  size_t blockChars = 1;

  // now start appending
  JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
  while (jsvStringIteratorHasChar(&it) && (maxLength-->0)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (blockChars >= jsvGetMaxCharactersInVar(block)) {
      jsvSetCharactersInVar(block, blockChars);
      JsVar *next = jsvNewWithFlags(JSV_STRING_EXT);
      if (!next) break; // out of memory
      // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
      block->lastChild = jsvGetRef(next);
      jsvUnLock(block);
      block = next;
      blockChars=0; // it's new, so empty
    }
    block->varData.str[blockChars++] = ch;
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);
  jsvSetCharactersInVar(block, blockChars);
  jsvUnLock(block);

  return var;
}
Exemplo n.º 24
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "toUpperCase",
  "generate_full" : "jswrap_string_toUpperLowerCase(parent, true)",
  "params" : [
    
  ],
  "return" : ["JsVar","The uppercase version of this string"]
}*/
JsVar *jswrap_string_toUpperLowerCase(JsVar *parent, bool upper) {
  JsVar *res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory

  JsvStringIterator itsrc, itdst;
  jsvStringIteratorNew(&itsrc, parent, 0);
  jsvStringIteratorNew(&itdst, res, 0);

  while (jsvStringIteratorHasChar(&itsrc)) {
    char ch = jsvStringIteratorGetChar(&itsrc);
    if (upper) {
      if (ch >= 97 && ch <= 122) ch = (char)(ch - 32);
    } else {
      if (ch >= 65 && ch <= 90) ch = (char)(ch + 32); // A-Z
    }
    jsvStringIteratorAppend(&itdst, ch);
    jsvStringIteratorNext(&itsrc);
  }

  jsvStringIteratorFree(&itsrc);
  jsvStringIteratorFree(&itdst);

  return res;
}
Exemplo n.º 25
0
/*JSON{
  "type" : "method",
  "class" : "Function",
  "name" : "bind",
  "generate" : "jswrap_function_bind",
  "params" : [
    ["this","JsVar","The value to use as the 'this' argument when executing the function"],
    ["params","JsVarArray","Optional Default parameters that are prepended to the call"]
  ],
  "return" : ["JsVar","The 'bound' function"]
}
This executes the function with the supplied 'this' argument and parameters
 */
JsVar *jswrap_function_bind(JsVar *parent, JsVar *thisArg, JsVar *argsArray) {
  if (!jsvIsFunction(parent)) {
    jsExceptionHere(JSET_TYPEERROR, "Function.bind expects to be called on function, got %t", parent);
    return 0;
  }
  JsVar *fn;
  if (jsvIsNativeFunction(parent))
    fn = jsvNewNativeFunction(parent->varData.native.ptr, parent->varData.native.argTypes);
  else
    fn = jsvNewWithFlags(jsvIsFunctionReturn(parent) ? JSV_FUNCTION_RETURN : JSV_FUNCTION);
  if (!fn) return 0;

  // Old function info
  JsvObjectIterator fnIt;
  jsvObjectIteratorNew(&fnIt, parent);
  // add previously bound arguments
  while (jsvObjectIteratorHasValue(&fnIt)) {
    JsVar *param = jsvObjectIteratorGetKey(&fnIt);
    JsVar *defaultValue = jsvObjectIteratorGetValue(&fnIt);
    bool wasBound = jsvIsFunctionParameter(param) && defaultValue;
    if (wasBound) {
      JsVar *newParam = jsvCopy(param);
      if (newParam) { // could be out of memory
        jsvAddName(fn, newParam);
        jsvUnLock(newParam);
      }
    }
    jsvUnLock2(param, defaultValue);
    if (!wasBound) break;
    jsvObjectIteratorNext(&fnIt);
  }

  // add bound arguments
  JsvObjectIterator argIt;
  jsvObjectIteratorNew(&argIt, argsArray);
  while (jsvObjectIteratorHasValue(&argIt)) {
    JsVar *defaultValue = jsvObjectIteratorGetValue(&argIt);
    bool addedParam = false;
    while (!addedParam && jsvObjectIteratorHasValue(&fnIt)) {
      JsVar *param = jsvObjectIteratorGetKey(&fnIt);
      if (!jsvIsFunctionParameter(param)) {
        jsvUnLock(param);
        break;
      }
      JsVar *newParam = jsvCopyNameOnly(param, false,  true);
      jsvSetValueOfName(newParam, defaultValue);
      jsvAddName(fn, newParam);
      addedParam = true;
      jsvUnLock2(param, newParam);
      jsvObjectIteratorNext(&fnIt);
    }

    if (!addedParam) {
      JsVar *paramName = jsvNewFromEmptyString();
      if (paramName) {
        jsvMakeFunctionParameter(paramName); // force this to be called a function parameter
        jsvSetValueOfName(paramName, defaultValue);
        jsvAddName(fn, paramName);
        jsvUnLock(paramName);
      }
    }
    jsvUnLock(defaultValue);
    jsvObjectIteratorNext(&argIt);
  }
  jsvObjectIteratorFree(&argIt);

  // Copy the rest of the old function's info
  while (jsvObjectIteratorHasValue(&fnIt)) {
    JsVar *param = jsvObjectIteratorGetKey(&fnIt);
    JsVar *newParam = jsvCopyNameOnly(param, true, true);
    if (newParam) { // could be out of memory
      jsvAddName(fn, newParam);
      jsvUnLock(newParam);
    }
    jsvUnLock(param);
    jsvObjectIteratorNext(&fnIt);
  }
  jsvObjectIteratorFree(&fnIt);
  // Add 'this'
  jsvObjectSetChild(fn, JSPARSE_FUNCTION_THIS_NAME, thisArg); // no unlock needed

  return fn;
}
Exemplo n.º 26
0
/*JSON{
  "type" : "staticmethod",
  "class" : "JSON",
  "name" : "stringify",
  "generate" : "jswrap_json_stringify",
  "params" : [
    ["data","JsVar","The data to be converted to a JSON string"]
  ],
  "return" : ["JsVar","A JSON string"]
}
Convert the given object into a JSON string which can subsequently be parsed with JSON.parse or eval
*/
JsVar *jswrap_json_stringify(JsVar *v) {
  JsVar *result = jsvNewFromEmptyString();
  if (result) // could be out of memory
    jsfGetJSON(v, result, JSON_IGNORE_FUNCTIONS|JSON_NO_UNDEFINED);
  return result;
}
Exemplo n.º 27
0
/*JSON{
  "type" : "constructor",
  "class" : "String",
  "name" : "String",
  "generate" : "jswrap_string_constructor",
  "params" : [
    ["str","JsVar","A value to turn into a string. If undefined or not supplied, an empty String is created."]
  ],
  "return" : ["JsVar","A String"]
}
Create a new String
*/
JsVar *jswrap_string_constructor(JsVar *a) {
  if (!a) return jsvNewFromEmptyString(); // no argument - return an empty string
  return jsvAsString(a, false);
}
Exemplo n.º 28
0
/*JSON{
  "type" : "staticmethod",
  "class" : "url",
  "name" : "parse",
  "generate" : "jswrap_url_parse",
  "params" : [
    ["urlStr","JsVar","A URL to be parsed"],
    ["parseQuery","bool","Whether to parse the query string into an object not (default = false)"]
  ],
  "return" : ["JsVar","An object containing options for ```http.request``` or ```http.get```. Contains `method`, `host`, `path`, `pathname`, `search`, `port` and `query`"]
}
A utility function to split a URL into parts

This is useful in web servers for instance when handling a request.

For instance `url.parse("/a?b=c&d=e",true)` returns `{"method":"GET","host":"","path":"/a?b=c&d=e","pathname":"/a","search":"?b=c&d=e","port":80,"query":{"b":"c","d":"e"}}`
*/
JsVar *jswrap_url_parse(JsVar *url, bool parseQuery) {
  if (!jsvIsString(url)) return 0;
  JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
  if (!obj) return 0; // out of memory

  // scan string to try and pick stuff out
  JsvStringIterator it;
  jsvStringIteratorNew(&it, url, 0);
  int slashes = 0;
  int colons = 0;
  int addrStart = -1;
  int portStart = -1;
  int pathStart = -1;
  int searchStart = -1;
  int charIdx = 0;
  int portNumber = 0;
  while (jsvStringIteratorHasChar(&it)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (ch == '/') {
      slashes++;
      if (pathStart<0) pathStart = charIdx;
      if (colons==1 && slashes==2 && addrStart<0) {
        addrStart = charIdx;
        pathStart = -1;
        searchStart = -1;
      }
    }
    if (ch == ':') {
      colons++;
      if (addrStart>=0 && pathStart<0)
        portStart = charIdx;
    }

    if (portStart>=0 && charIdx>portStart && pathStart<0 && ch >= '0' && ch <= '9') {
      portNumber = portNumber*10 + (ch-'0');
    }

    if (ch == '?' && pathStart>=0) {
      searchStart = charIdx;
    }

    jsvStringIteratorNext(&it);
    charIdx++;
  }
  jsvStringIteratorFree(&it);
  // try and sort stuff out
  if (pathStart<0) pathStart = charIdx;
  if (pathStart<0) pathStart = charIdx;
  int addrEnd = (portStart>=0) ? portStart : pathStart;
  // pull out details
  if (addrStart>0)
    jsvObjectSetChildAndUnLock(obj, "protocol", jsvNewFromStringVar(url, 0, (size_t)addrStart-1));
  jsvObjectSetChildAndUnLock(obj, "method", jsvNewFromString("GET"));
  jsvObjectSetChildAndUnLock(obj, "host", jsvNewFromStringVar(url, (size_t)(addrStart+1), (size_t)(addrEnd-(addrStart+1))));

  JsVar *v;

  v = jsvNewFromStringVar(url, (size_t)pathStart, JSVAPPENDSTRINGVAR_MAXLENGTH);
  if (jsvGetStringLength(v)==0) jsvAppendString(v, "/");
  jsvObjectSetChildAndUnLock(obj, "path", v);

  v = jsvNewFromStringVar(url, (size_t)pathStart, (size_t)((searchStart>=0)?(searchStart-pathStart):JSVAPPENDSTRINGVAR_MAXLENGTH));
  if (jsvGetStringLength(v)==0) jsvAppendString(v, "/");
  jsvObjectSetChildAndUnLock(obj, "pathname", v);

  jsvObjectSetChildAndUnLock(obj, "search", (searchStart>=0)?jsvNewFromStringVar(url, (size_t)searchStart, JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull());

  jsvObjectSetChildAndUnLock(obj, "port", (portNumber<=0 || portNumber>65535) ? jsvNewWithFlags(JSV_NULL) : jsvNewFromInteger(portNumber));

  JsVar *query = (searchStart>=0)?jsvNewFromStringVar(url, (size_t)(searchStart+1), JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull();
  if (parseQuery && !jsvIsNull(query)) {
    JsVar *queryStr = query;
    jsvStringIteratorNew(&it, query, 0);
    query = jsvNewWithFlags(JSV_OBJECT);

    JsVar *key = jsvNewFromEmptyString();
    JsVar *val = jsvNewFromEmptyString();
    bool hadEquals = false;

    while (jsvStringIteratorHasChar(&it)) {
      char ch = jsvStringIteratorGetChar(&it);
      if (ch=='&') {
        if (jsvGetStringLength(key)>0 || jsvGetStringLength(val)>0) {
          key = jsvAsArrayIndexAndUnLock(key); // make sure "0" gets made into 0
          jsvMakeIntoVariableName(key, val);
          jsvAddName(query, key);
          jsvUnLock2(key, val);
          key = jsvNewFromEmptyString();
          val = jsvNewFromEmptyString();
          hadEquals = false;
        }
      } else if (!hadEquals && ch=='=') {
        hadEquals = true;
      } else {
        // decode percent escape chars
        if (ch=='%') {
          jsvStringIteratorNext(&it);
          ch = jsvStringIteratorGetChar(&it);
          jsvStringIteratorNext(&it);
          ch = (char)((chtod(ch)<<4) | chtod(jsvStringIteratorGetChar(&it)));
        }

        if (hadEquals) jsvAppendCharacter(val, ch);
        else jsvAppendCharacter(key, ch);
      }
      jsvStringIteratorNext(&it);
      charIdx++;
    }
    jsvStringIteratorFree(&it);
    jsvUnLock(queryStr);

    if (jsvGetStringLength(key)>0 || jsvGetStringLength(val)>0) {
      key = jsvAsArrayIndexAndUnLock(key); // make sure "0" gets made into 0
      jsvMakeIntoVariableName(key, val);
      jsvAddName(query, key);
    }
    jsvUnLock2(key, val);
  }
  jsvObjectSetChildAndUnLock(obj, "query", query);

  return obj;
}
Exemplo n.º 29
0
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "readFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "wrap_fat_readFile",
         "description" : [ "Read all data from a file and return as a string" ],
         "params" : [ [ "path", "JsVar", "The path of the file to read" ] ],
         "return" : [ "JsVar", "A string containing the contents of the file (or undefined if the file doesn't exist)" ]
}*/
JsVar *wrap_fat_readFile(JsVar *path) {
  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);

  JsVar *result = 0; // undefined unless we read the file

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    FIL file;
    if ((res=f_open(&file, pathStr, FA_READ)) == FR_OK) {
#else
    FILE *file = fopen(pathStr, "r");
    if (file) {
#endif
      result = jsvNewFromEmptyString();
      if (result) { // out of memory?
        // re-use pathStr buffer
        size_t bytesRead = JS_DIR_BUF_SIZE;
        while (res==FR_OK && bytesRead==JS_DIR_BUF_SIZE) {
#ifndef LINUX
          res = f_read (&file, pathStr, JS_DIR_BUF_SIZE, &bytesRead);
#else
          bytesRead = fread(pathStr,1,JS_DIR_BUF_SIZE,file);
#endif
          if (!jsvAppendStringBuf(result, pathStr, (int)bytesRead))
            break; // was out of memory
        }
      }
#ifndef LINUX
      f_close(&file);
#else
      fclose(file);
#endif
    }
  }

  if (res) jsfsReportError("Unable to read file", res);
  return result;
}

  /*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "unlink",
           "generate" : "wrap_fat_unlink",
           "description" : [ "Delete the given file", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
           "params" : [ [ "path", "JsVar", "The path of the file to delete" ] ],
           "return" : [ "bool", "True on success, or false on failure" ]
  }*/
  /*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "unlinkSync", "ifndef" : "SAVE_ON_FLASH",
           "generate" : "wrap_fat_unlink",
           "description" : [ "Delete the given file" ],
           "params" : [ [ "path", "JsVar", "The path of the file to delete" ] ],
           "return" : [ "bool", "True on success, or false on failure" ]
  }*/
bool wrap_fat_unlink(JsVar *path) {
    char pathStr[JS_DIR_BUF_SIZE] = "";
    if (!jsvIsUndefined(path))
      jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);

#ifndef LINUX
    FRESULT res = 0;
    if (jsfsInit()) {
      f_unlink(pathStr);
    }
#else
    FRESULT res = remove(pathStr);
#endif

    if (res) {
      jsfsReportError("Unable to delete file", res);
      return false;
    }
    return true;
  }
Exemplo n.º 30
0
/*JSON{
  "type" : "method",
  "class" : "File",
  "name" : "read",
  "generate" : "jswrap_file_read",
  "params" : [
    ["length","int32","is an integer specifying the number of bytes to read."]
  ],
  "return" : ["JsVar","A string containing the characters that were read"]
}
Read data in a file in byte size chunks
*/
JsVar *jswrap_file_read(JsVar* parent, int length) {
  if (length<0) length=0;
  JsVar *buffer = 0;
  JsvStringIterator it;
  FRESULT res = 0;
  size_t bytesRead = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data->mode == FM_READ || file.data->mode == FM_READ_WRITE) {
        size_t actual = 0;
#ifndef LINUX
        // if we're able to load this into a flat string, do it!
        size_t len = f_size(&file.data->handle)-f_tell(&file.data->handle);
        if ( len == 0 ) { // file all read
          return 0; // if called from a pipe signal end callback
        }
        if (len > (size_t)length) len = (size_t)length;
        buffer = jsvNewFlatStringOfLength(len);
        if (buffer) {
          res = f_read(&file.data->handle, jsvGetFlatStringPointer(buffer), len, &actual);
          if (res) jsfsReportError("Unable to read file", res);
          return buffer;
        }
#endif
        char buf[32];

        while (bytesRead < (size_t)length) {
          size_t requested = (size_t)length - bytesRead;
          if (requested > sizeof( buf ))
            requested = sizeof( buf );
          actual = 0;
    #ifndef LINUX
          res = f_read(&file.data->handle, buf, requested, &actual);
          if(res) break;
    #else
          actual = fread(buf, 1, requested, file.data->handle);
    #endif
          if (actual>0) {
            if (!buffer) {
              buffer = jsvNewFromEmptyString();
              if (!buffer) return 0; // out of memory
              jsvStringIteratorNew(&it, buffer, 0);
            }
            size_t i;
            for (i=0;i<actual;i++)
              jsvStringIteratorAppend(&it, buf[i]);
          }
          bytesRead += actual;
          if(actual != requested) break;
        }
      }
    }
  }
  if (res) jsfsReportError("Unable to read file", res);

  if (buffer)
    jsvStringIteratorFree(&it);

  return buffer;
}