var toWords = function (string) {
var padding = 8 - (string.length & 0x7)
if (padding != 8) {
string = '00000000'.substring(0, padding) + string
}
return string.match(/(.{1,8})/g).map(function (word) {
return parseInt(word, 16)
})
}
var toString = function (words) {
var string = [ words[0].toString(16) ]
for (var i = 1, I = words.length; i < I; i++) {
string.push(('00000000000' + words[i].toString(16)).substr(-8))
}
var string = string.join('')
return string
}
var Part = {
toWords: toWords,
toString: toString,
compare: function (these, those) {
var compare = these.length - those.length
if (!compare) {
for (var i = 0, I = these.length; i < I; i++) {
compare = these[i] - those[i]
if (compare) {
return compare
}
}
}
return compare
},
increment: function (words) {
words = words.slice()
for (var i = words.length - 1; i != -1; i--) {
if (words[i] == 0xffffffff) {
words[i] = 0
} else {
words[i]++
break
}
}
if (words[0] == 0) {
words.unshift(0x1)
}
return words
},
add: function (words, value) {
words = words.slice()
var carry = value
for (var i = words.length - 1; i != -1; i--) {
words[i] += carry
if (words[i] > 0xffffffff) {
carry = Math.floor(words[i] / Math.pow(2, 32))
words[i] = words[i] & 0xffffffff
} else {
carry = 0
}
}
if (carry != 0) {
words.unshift(carry)
}
return words
},
difference: function (these, those) {
these = these.slice().reverse()
those = those.slice().reverse()
var difference = 0
for (var i = 0, I = Math.max(these.length, those.length); i < I; i++) {
difference += ((these[i] || 0) - (those[i] || 0)) * Math.pow(2, 32 * i)
}
return difference
},
asString: {
toWords: toWords,
toString: toString,
compare: function (a, b) {
return Part.compare(Part.toWords(a), Part.toWords(b))
},
increment: function (number) {
return Part.toString(Part.increment(Part.toWords(number)))
},
add: function (number, value) {
return Part.toString(Part.increment(Part.toWords(number)))
},
difference: function (a, b) {
return Part.difference(Part.toWords(a), Part.toWords(b))
}
}
}
var toWords = function (number) {
return number.split('/').map(function (part) { return Part.toWords(part) })
}
var toString = function (number) {
return number.map(function (part) { return Part.toString(part) }).join('/')
}
var Path = {
toWords: toWords,
toString: toString,
compare: function (a, b) {
for (var i = 0, I = Math.min(a.length, b.length); i < I; i++) {
var compare = Part.compare(a[i], b[i])
if (compare) {
return compare
}
}
return a.length - b.length
},
compareIndex: function (a, b, index) {
return Part.compare(a[index], b[index])
},
increment: function (number, index) {
number = Path.toWords(Path.toString(number))
number[index] = Part.increment(number[index])
for (var i = index + 1, I = number.length; i < I; i++) {
number[i] = [ 0 ]
}
return number
},
add: function (number, value) {
number = Path.toWords(Path.toString(number))
number[number.length - 1] = Part.add(number[number.length - 1], value)
return number
},
difference: function (a, b, index) {
return Part.difference(a[index], b[index])
},
isBoundary: function (number, index) {
for (var i = index + 1, I = number.length; i < I; i++) {
if (!(number[i].length == 1 && number[i][0] == 0)) {
return false
}
}
return true
},
Part: Part,
asString: {
toWords: toWords,
toString: toString,
compare: function (a, b) {
return Path.compare(Path.toWords(a), Path.toWords(b))
},
compareIndex: function (a, b, index) {
return Path.compareIndex(Path.toWords(a), Path.toWords(b), index)
},
increment: function (number, index) {
return Path.toString(Path.increment(Path.toWords(number), index))
},
add: function (number, value) {
return Path.toString(Path.add(Path.toWords(number), value))
},
isBoundary: function (number, index) {
return Path.isBoundary(Path.toWords(number), index)
},
difference: function (a, b, index) {
return Path.difference(Path.toWords(a), Path.toWords(b), index)
}
}
}
module.exports = Path