The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.js 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*!
  2. * range-parser
  3. * Copyright(c) 2012-2014 TJ Holowaychuk
  4. * Copyright(c) 2015-2016 Douglas Christopher Wilson
  5. * MIT Licensed
  6. */
  7. 'use strict'
  8. /**
  9. * Module exports.
  10. * @public
  11. */
  12. module.exports = rangeParser
  13. /**
  14. * Parse "Range" header `str` relative to the given file `size`.
  15. *
  16. * @param {Number} size
  17. * @param {String} str
  18. * @param {Object} [options]
  19. * @return {Array}
  20. * @public
  21. */
  22. function rangeParser (size, str, options) {
  23. if (typeof str !== 'string') {
  24. throw new TypeError('argument str must be a string')
  25. }
  26. var index = str.indexOf('=')
  27. if (index === -1) {
  28. return -2
  29. }
  30. // split the range string
  31. var arr = str.slice(index + 1).split(',')
  32. var ranges = []
  33. // add ranges type
  34. ranges.type = str.slice(0, index)
  35. // parse all ranges
  36. for (var i = 0; i < arr.length; i++) {
  37. var range = arr[i].split('-')
  38. var start = parseInt(range[0], 10)
  39. var end = parseInt(range[1], 10)
  40. // -nnn
  41. if (isNaN(start)) {
  42. start = size - end
  43. end = size - 1
  44. // nnn-
  45. } else if (isNaN(end)) {
  46. end = size - 1
  47. }
  48. // limit last-byte-pos to current length
  49. if (end > size - 1) {
  50. end = size - 1
  51. }
  52. // invalid or unsatisifiable
  53. if (isNaN(start) || isNaN(end) || start > end || start < 0) {
  54. continue
  55. }
  56. // add range
  57. ranges.push({
  58. start: start,
  59. end: end
  60. })
  61. }
  62. if (ranges.length < 1) {
  63. // unsatisifiable
  64. return -1
  65. }
  66. return options && options.combine
  67. ? combineRanges(ranges)
  68. : ranges
  69. }
  70. /**
  71. * Combine overlapping & adjacent ranges.
  72. * @private
  73. */
  74. function combineRanges (ranges) {
  75. var ordered = ranges.map(mapWithIndex).sort(sortByRangeStart)
  76. for (var j = 0, i = 1; i < ordered.length; i++) {
  77. var range = ordered[i]
  78. var current = ordered[j]
  79. if (range.start > current.end + 1) {
  80. // next range
  81. ordered[++j] = range
  82. } else if (range.end > current.end) {
  83. // extend range
  84. current.end = range.end
  85. current.index = Math.min(current.index, range.index)
  86. }
  87. }
  88. // trim ordered array
  89. ordered.length = j + 1
  90. // generate combined range
  91. var combined = ordered.sort(sortByRangeIndex).map(mapWithoutIndex)
  92. // copy ranges type
  93. combined.type = ranges.type
  94. return combined
  95. }
  96. /**
  97. * Map function to add index value to ranges.
  98. * @private
  99. */
  100. function mapWithIndex (range, index) {
  101. return {
  102. start: range.start,
  103. end: range.end,
  104. index: index
  105. }
  106. }
  107. /**
  108. * Map function to remove index value from ranges.
  109. * @private
  110. */
  111. function mapWithoutIndex (range) {
  112. return {
  113. start: range.start,
  114. end: range.end
  115. }
  116. }
  117. /**
  118. * Sort function to sort ranges by index.
  119. * @private
  120. */
  121. function sortByRangeIndex (a, b) {
  122. return a.index - b.index
  123. }
  124. /**
  125. * Sort function to sort ranges by start position.
  126. * @private
  127. */
  128. function sortByRangeStart (a, b) {
  129. return a.start - b.start
  130. }