77 lines
1.5 KiB
JavaScript
77 lines
1.5 KiB
JavaScript
|
var untilde = function(str) {
|
||
|
return str.replace(/~./g, function(m) {
|
||
|
switch (m) {
|
||
|
case "~0":
|
||
|
return "~";
|
||
|
case "~1":
|
||
|
return "/";
|
||
|
}
|
||
|
throw new Error("Invalid tilde escape: " + m);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var traverse = function(obj, pointer, value) {
|
||
|
// assert(isArray(pointer))
|
||
|
var part = untilde(pointer.shift());
|
||
|
if(!obj.hasOwnProperty(part)) {
|
||
|
return null;
|
||
|
}
|
||
|
if(pointer.length !== 0) { // keep traversin!
|
||
|
return traverse(obj[part], pointer, value);
|
||
|
}
|
||
|
// we're done
|
||
|
if(typeof value === "undefined") {
|
||
|
// just reading
|
||
|
return obj[part];
|
||
|
}
|
||
|
// set new value, return old value
|
||
|
var old_value = obj[part];
|
||
|
if(value === null) {
|
||
|
delete obj[part];
|
||
|
} else {
|
||
|
obj[part] = value;
|
||
|
}
|
||
|
return old_value;
|
||
|
}
|
||
|
|
||
|
var validate_input = function(obj, pointer) {
|
||
|
if(typeof obj !== "object") {
|
||
|
throw new Error("Invalid input object.");
|
||
|
}
|
||
|
|
||
|
if(pointer === "") {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
if(!pointer) {
|
||
|
throw new Error("Invalid JSON pointer.");
|
||
|
}
|
||
|
|
||
|
pointer = pointer.split("/");
|
||
|
var first = pointer.shift();
|
||
|
if (first !== "") {
|
||
|
throw new Error("Invalid JSON pointer.");
|
||
|
}
|
||
|
|
||
|
return pointer;
|
||
|
}
|
||
|
|
||
|
var get = function(obj, pointer) {
|
||
|
pointer = validate_input(obj, pointer);
|
||
|
if (pointer.length === 0) {
|
||
|
return obj;
|
||
|
}
|
||
|
return traverse(obj, pointer);
|
||
|
}
|
||
|
|
||
|
var set = function(obj, pointer, value) {
|
||
|
pointer = validate_input(obj, pointer);
|
||
|
if (pointer.length === 0) {
|
||
|
throw new Error("Invalid JSON pointer for set.")
|
||
|
}
|
||
|
return traverse(obj, pointer, value);
|
||
|
}
|
||
|
|
||
|
exports.get = get
|
||
|
exports.set = set
|