2 var escapeMatcher = /~[01]/g
3 function escapeReplacer (m) {
8 throw new Error('Invalid tilde escape: ' + m)
11 function untilde (str) {
12 if (!hasExcape.test(str)) return str
13 return str.replace(escapeMatcher, escapeReplacer)
16 function setter (obj, pointer, value) {
20 for (var p = 1, len = pointer.length; p < len;) {
21 part = untilde(pointer[p++])
24 if (typeof obj[part] === 'undefined') {
25 // support setting of /-
26 if (Array.isArray(obj) && part === '-') {
30 // support nested objects/array when setting values
32 if ((pointer[p] !== '' && pointer[p] < Infinity) || pointer[p] === '-') obj[part] = []
37 if (!hasNextPart) break
41 var oldValue = obj[part]
42 if (value === undefined) delete obj[part]
43 else obj[part] = value
47 function compilePointer (pointer) {
48 if (typeof pointer === 'string') {
49 pointer = pointer.split('/')
50 if (pointer[0] === '') return pointer
51 throw new Error('Invalid JSON pointer.')
52 } else if (Array.isArray(pointer)) {
56 throw new Error('Invalid JSON pointer.')
59 function get (obj, pointer) {
60 if (typeof obj !== 'object') throw new Error('Invalid input object.')
61 pointer = compilePointer(pointer)
62 var len = pointer.length
63 if (len === 1) return obj
65 for (var p = 1; p < len;) {
66 obj = obj[untilde(pointer[p++])]
67 if (len === p) return obj
68 if (typeof obj !== 'object') return undefined
72 function set (obj, pointer, value) {
73 if (typeof obj !== 'object') throw new Error('Invalid input object.')
74 pointer = compilePointer(pointer)
75 if (pointer.length === 0) throw new Error('Invalid JSON pointer for set.')
76 return setter(obj, pointer, value)
79 function compile (pointer) {
80 var compiled = compilePointer(pointer)
82 get: function (object) {
83 return get(object, compiled)
85 set: function (object, value) {
86 return set(object, compiled, value)
93 exports.compile = compile