Skip to content

Commit

Permalink
Added String.padStart/padEnd
Browse files Browse the repository at this point in the history
  • Loading branch information
gfwilliams committed Oct 8, 2020
1 parent 8bb747f commit 05c89c9
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 10 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Expand Up @@ -12,6 +12,7 @@
nRF52: CPU now sleeps when while UART/BLE data is waiting to be sent (fix #1938)
JSON.stringify now checks for potential stack overflow when stringifying (fix #1940)
Check for Stack overflow when Garbage Collecting giant linked list (fix #1765)
Added String.padStart/padEnd

2v07 : Graphics.asImage() now contains buffer when bpp != 8 (fix #1863)
nRF52 SDK15: Fix NRF.setScan/findDevices/etc
Expand Down
80 changes: 70 additions & 10 deletions src/jswrap_string.c
Expand Up @@ -329,7 +329,7 @@ JsVar *jswrap_string_replace(JsVar *parent, JsVar *subStr, JsVar *newSubStr) {
JsVarInt idx = jsvGetIntegerAndUnLock(jsvObjectGetChild(match,"index",0));
JsVarInt len = (JsVarInt)jsvGetStringLength(matchStr);
// do the replacement
jsvStringIteratorAppendString(&dst, str, lastIndex, (idx-lastIndex)); // the string before the match
jsvStringIteratorAppendString(&dst, str, (size_t)lastIndex, (idx-lastIndex)); // the string before the match
if (jsvIsFunction(replace)) {
unsigned int argCount = 0;
JsVar *args[13];
Expand Down Expand Up @@ -376,7 +376,7 @@ JsVar *jswrap_string_replace(JsVar *parent, JsVar *subStr, JsVar *newSubStr) {
match = jswrap_regexp_exec(subStr, str);
}
}
jsvStringIteratorAppendString(&dst, str, lastIndex, JSVAPPENDSTRINGVAR_MAXLENGTH); // append the rest of the string
jsvStringIteratorAppendString(&dst, str, (size_t)lastIndex, JSVAPPENDSTRINGVAR_MAXLENGTH); // append the rest of the string
jsvStringIteratorFree(&dst);
jsvUnLock3(match,replace,str);
// reset lastIndex if global
Expand Down Expand Up @@ -508,15 +508,15 @@ JsVar *jswrap_string_split(JsVar *parent, JsVar *split) {
#ifndef SAVE_ON_FLASH
// Use RegExp if one is passed in
if (jsvIsInstanceOf(split, "RegExp")) {
unsigned int last = 0;
int last = 0;
JsVar *match;
jsvObjectSetChildAndUnLock(split, "lastIndex", jsvNewFromInteger(0));
match = jswrap_regexp_exec(split, parent);
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 len = (int)jsvGetStringLength(matchStr);
jsvUnLock(matchStr);
// do the replacement
jsvArrayPushAndUnLock(array, jsvNewFromStringVar(parent, (size_t)last, (size_t)(idx-last)));
Expand All @@ -529,7 +529,7 @@ JsVar *jswrap_string_split(JsVar *parent, JsVar *split) {
jsvUnLock(match);
jsvObjectSetChildAndUnLock(split, "lastIndex", jsvNewFromInteger(0));
// add remaining string after last match
if (last<=jsvGetStringLength(parent))
if (last <= (int)jsvGetStringLength(parent))
jsvArrayPushAndUnLock(array, jsvNewFromStringVar(parent, (size_t)last, JSVAPPENDSTRINGVAR_MAXLENGTH));
return array;
}
Expand Down Expand Up @@ -657,8 +657,8 @@ bool jswrap_string_startsWith(JsVar *parent, JsVar *search, int position) {
JsVar *searchStr = jsvAsString(search);
bool match = false;
if (position >= 0 &&
jsvGetStringLength(searchStr)+position <= jsvGetStringLength(parent))
match = jsvCompareString(parent, searchStr, position,0,true)==0;
(int)jsvGetStringLength(searchStr)+position <= (int)jsvGetStringLength(parent))
match = jsvCompareString(parent, searchStr, (size_t)position,0,true)==0;
jsvUnLock(searchStr);
return match;
}
Expand All @@ -680,11 +680,11 @@ 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);
position -= (int)jsvGetStringLength(searchStr);
bool match = false;
if (position >= 0 &&
jsvGetStringLength(searchStr)+position <= jsvGetStringLength(parent))
match = jsvCompareString(parent, searchStr, position,0,true)==0;
(int)jsvGetStringLength(searchStr)+position <= (int)jsvGetStringLength(parent))
match = jsvCompareString(parent, searchStr, (size_t)position,0,true)==0;
jsvUnLock(searchStr);
return match;
}
Expand Down Expand Up @@ -728,3 +728,63 @@ JsVar *jswrap_string_repeat(JsVar *parent, int count) {
jsvAppendStringVarComplete(result, parent);
return result;
}

/*JSON{
"type" : "method",
"class" : "String",
"name" : "padStart",
"ifndef" : "SAVE_ON_FLASH",
"generate_full" : "jswrap_string_padX(parent, targetLength, padString, true)",
"params" : [
["targetLength","int","The length to pad this string to"],
["padString","JsVar","[optional] The string to pad with, default is `' '`"]
],
"return" : ["JsVar","A string containing this string padded to the correct length"],
"return_object" : "String"
}
Pad this string at the beginnind to the required number of characters
```
"Hello".padStart(10) == " Hello"
"123".padStart(10,".-") == ".-.-.-.123"
```
*/
/*JSON{
"type" : "method",
"class" : "String",
"name" : "padEnd",
"ifndef" : "SAVE_ON_FLASH",
"generate_full" : "jswrap_string_padX(parent, targetLength, padString, false)",
"params" : [
["targetLength","int","The length to pad this string to"],
["padString","JsVar","[optional] The string to pad with, default is `' '`"]
],
"return" : ["JsVar","A string containing this string padded to the correct length"],
"return_object" : "String"
}
Pad this string at the end to the required number of characters
```
"Hello".padEnd(10) == "Hello "
"123".padEnd(10,".-") == "123.-.-.-."
```
*/
JsVar *jswrap_string_padX(JsVar *str, int targetLength, JsVar *padString, bool padStart) {
if (!jsvIsString(str) || (int)jsvGetStringLength(str)>=targetLength)
return jsvLockAgain(str);

int padChars = targetLength - (int)jsvGetStringLength(str);

JsVar *result = padStart ? jsvNewFromEmptyString() : jsvNewFromStringVar(str,0,JSVAPPENDSTRINGVAR_MAXLENGTH);
if (!result) return 0;

padString = padString ? jsvAsString(padString) : jsvNewFromString(" ");
int padLength = (int)jsvGetStringLength(padString);
while (padChars > 0) {
jsvAppendStringVar(result, padString, 0, (size_t)((padLength > padChars) ? padChars : padLength));
padChars -= padLength;
}
if (padStart) jsvAppendStringVarComplete(result, str);
jsvUnLock(padString);
return result;
}
1 change: 1 addition & 0 deletions src/jswrap_string.h
Expand Up @@ -29,3 +29,4 @@ JsVar *jswrap_string_trim(JsVar *parent);
bool jswrap_string_startsWith(JsVar *parent, JsVar *search, int position);
bool jswrap_string_endsWith(JsVar *parent, JsVar *search, JsVar *length);
JsVar *jswrap_string_repeat(JsVar *parent, int count);
JsVar *jswrap_string_padX(JsVar *str, int targetLength, JsVar *padString, bool padStart);
18 changes: 18 additions & 0 deletions tests/test_string_pad.js
@@ -0,0 +1,18 @@
function test(a,b) {
var ea = eval(a);
if (JSON.stringify(ea)!=JSON.stringify(b)) {
console.log(JSON.stringify(a)+" should be "+JSON.stringify(b)+", got "+JSON.stringify(ea))
result = 0;
}
}

result = 1;
test("'abc'.padStart(10); "," abc");
test("'abc'.padStart(10, 'foo'); ","foofoofabc");
test("'abc'.padStart(6,'123465'); ","123abc");
test("'abc'.padStart(8, '0'); ","00000abc");
test("'abc'.padStart(1); ","abc");
test("'abc'.padEnd(10); ", "abc ");
test("'abc'.padEnd(10, 'foo'); ", "abcfoofoof");
test("'abc'.padEnd(6, '123456'); ", "abc123");
test("'abc'.padEnd(1); ", "abc");

0 comments on commit 05c89c9

Please sign in to comment.