Skip to content

Commit

Permalink
Handle strings by code point
Browse files Browse the repository at this point in the history
  • Loading branch information
gibson042 committed Oct 17, 2022
1 parent 0928621 commit 4868df4
Showing 1 changed file with 33 additions and 9 deletions.
42 changes: 33 additions & 9 deletions jmespath.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@
};
}

function compareStringsByCodePoints(a, b) {
var ia = 0;
var ib = 0;
while (true) {
// Offset each code point by 1, leaving 0 for end of string.
var aCodePoint = (a.codePointAt(ia) + 1) || 0;
var bCodePoint = (b.codePointAt(ib) + 1) || 0;
var result = aCodePoint - bCodePoint;
if (result) {
return result;
} else if (!aCodePoint) {
// Having reached the end of both strings, they must be equal.
return 0;
}
// Increment each index by the right amount.
ia += aCodePoint <= 0xFFFF ? 1 : 2;
ib += bCodePoint <= 0xFFFF ? 1 : 2;
}
}

// Type constants used to define functions.
var TYPE_NUMBER = 0;
var TYPE_ANY = 1;
Expand Down Expand Up @@ -1334,12 +1354,7 @@
_functionReverse: function(resolvedArgs) {
var typeName = this._getTypeName(resolvedArgs[0]);
if (typeName === TYPE_STRING) {
var originalStr = resolvedArgs[0];
var reversedStr = "";
for (var i = originalStr.length - 1; i >= 0; i--) {
reversedStr += originalStr[i];
}
return reversedStr;
return Array.from(resolvedArgs[0]).reverse().join("");
} else {
var reversedArray = resolvedArgs[0].slice(0);
reversedArray.reverse();
Expand Down Expand Up @@ -1374,7 +1389,7 @@

_functionLength: function(resolvedArgs) {
if (!isObject(resolvedArgs[0])) {
return resolvedArgs[0].length;
return Array.from(resolvedArgs[0]).length;
} else {
// As far as I can tell, there's no way to get the length
// of an object without O(n) iteration through the object.
Expand Down Expand Up @@ -1533,7 +1548,14 @@

_functionSort: function(resolvedArgs) {
var sortedArray = resolvedArgs[0].slice(0);
sortedArray.sort();
if (sortedArray.length === 0) {
return sortedArray;
}
if (this._getTypeName(sortedArray[0]) === TYPE_STRING) {
sortedArray.sort(compareStringsByCodePoints);
} else {
sortedArray.sort();
}
return sortedArray;
},

Expand Down Expand Up @@ -1573,7 +1595,9 @@
"TypeError: expected " + requiredType + ", received " +
that._getTypeName(exprB));
}
if (exprA > exprB) {
if (requiredType === TYPE_STRING) {
return compareStringsByCodePoints(exprA, exprB) || a[0] - b[0];
} else if (exprA > exprB) {
return 1;
} else if (exprA < exprB) {
return -1;
Expand Down

0 comments on commit 4868df4

Please sign in to comment.