UI for Zipcoin Blue

index.js 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. 'use strict'
  2. const assert = require('assert')
  3. const Buffer = require('buffer').Buffer
  4. const binding = process.binding('zlib')
  5. const constants = exports.constants = require('./constants.js')
  6. const MiniPass = require('minipass')
  7. class ZlibError extends Error {
  8. constructor (msg, errno) {
  9. super('zlib: ' + msg)
  10. this.errno = errno
  11. this.code = codes.get(errno)
  12. }
  13. get name () {
  14. return 'ZlibError'
  15. }
  16. }
  17. // translation table for return codes.
  18. const codes = new Map([
  19. [constants.Z_OK, 'Z_OK'],
  20. [constants.Z_STREAM_END, 'Z_STREAM_END'],
  21. [constants.Z_NEED_DICT, 'Z_NEED_DICT'],
  22. [constants.Z_ERRNO, 'Z_ERRNO'],
  23. [constants.Z_STREAM_ERROR, 'Z_STREAM_ERROR'],
  24. [constants.Z_DATA_ERROR, 'Z_DATA_ERROR'],
  25. [constants.Z_MEM_ERROR, 'Z_MEM_ERROR'],
  26. [constants.Z_BUF_ERROR, 'Z_BUF_ERROR'],
  27. [constants.Z_VERSION_ERROR, 'Z_VERSION_ERROR']
  28. ])
  29. const validFlushFlags = new Set([
  30. constants.Z_NO_FLUSH,
  31. constants.Z_PARTIAL_FLUSH,
  32. constants.Z_SYNC_FLUSH,
  33. constants.Z_FULL_FLUSH,
  34. constants.Z_FINISH,
  35. constants.Z_BLOCK
  36. ])
  37. const strategies = new Set([
  38. constants.Z_FILTERED,
  39. constants.Z_HUFFMAN_ONLY,
  40. constants.Z_RLE,
  41. constants.Z_FIXED,
  42. constants.Z_DEFAULT_STRATEGY
  43. ])
  44. // the Zlib class they all inherit from
  45. // This thing manages the queue of requests, and returns
  46. // true or false if there is anything in the queue when
  47. // you call the .write() method.
  48. const _opts = Symbol('opts')
  49. const _chunkSize = Symbol('chunkSize')
  50. const _flushFlag = Symbol('flushFlag')
  51. const _finishFlush = Symbol('finishFlush')
  52. const _handle = Symbol('handle')
  53. const _hadError = Symbol('hadError')
  54. const _buffer = Symbol('buffer')
  55. const _offset = Symbol('offset')
  56. const _level = Symbol('level')
  57. const _strategy = Symbol('strategy')
  58. const _ended = Symbol('ended')
  59. const _writeState = Symbol('writeState')
  60. class Zlib extends MiniPass {
  61. constructor (opts, mode) {
  62. super(opts)
  63. this[_ended] = false
  64. this[_opts] = opts = opts || {}
  65. this[_chunkSize] = opts.chunkSize || constants.Z_DEFAULT_CHUNK
  66. if (opts.flush && !validFlushFlags.has(opts.flush)) {
  67. throw new TypeError('Invalid flush flag: ' + opts.flush)
  68. }
  69. if (opts.finishFlush && !validFlushFlags.has(opts.finishFlush)) {
  70. throw new TypeError('Invalid flush flag: ' + opts.finishFlush)
  71. }
  72. this[_flushFlag] = opts.flush || constants.Z_NO_FLUSH
  73. this[_finishFlush] = typeof opts.finishFlush !== 'undefined' ?
  74. opts.finishFlush : constants.Z_FINISH
  75. if (opts.chunkSize) {
  76. if (opts.chunkSize < constants.Z_MIN_CHUNK) {
  77. throw new RangeError('Invalid chunk size: ' + opts.chunkSize)
  78. }
  79. }
  80. if (opts.windowBits) {
  81. if (opts.windowBits < constants.Z_MIN_WINDOWBITS ||
  82. opts.windowBits > constants.Z_MAX_WINDOWBITS) {
  83. throw new RangeError('Invalid windowBits: ' + opts.windowBits)
  84. }
  85. }
  86. if (opts.level) {
  87. if (opts.level < constants.Z_MIN_LEVEL ||
  88. opts.level > constants.Z_MAX_LEVEL) {
  89. throw new RangeError('Invalid compression level: ' + opts.level)
  90. }
  91. }
  92. if (opts.memLevel) {
  93. if (opts.memLevel < constants.Z_MIN_MEMLEVEL ||
  94. opts.memLevel > constants.Z_MAX_MEMLEVEL) {
  95. throw new RangeError('Invalid memLevel: ' + opts.memLevel)
  96. }
  97. }
  98. if (opts.strategy && !(strategies.has(opts.strategy)))
  99. throw new TypeError('Invalid strategy: ' + opts.strategy)
  100. if (opts.dictionary) {
  101. if (!(opts.dictionary instanceof Buffer)) {
  102. throw new TypeError('Invalid dictionary: it should be a Buffer instance')
  103. }
  104. }
  105. this[_handle] = new binding.Zlib(mode)
  106. this[_hadError] = false
  107. this[_handle].onerror = (message, errno) => {
  108. // there is no way to cleanly recover.
  109. // continuing only obscures problems.
  110. this.close()
  111. this[_hadError] = true
  112. const error = new ZlibError(message, errno)
  113. this.emit('error', error)
  114. }
  115. const level = typeof opts.level === 'number' ? opts.level
  116. : constants.Z_DEFAULT_COMPRESSION
  117. var strategy = typeof opts.strategy === 'number' ? opts.strategy
  118. : constants.Z_DEFAULT_STRATEGY
  119. this[_writeState] = new Uint32Array(2);
  120. const window = opts.windowBits || constants.Z_DEFAULT_WINDOWBITS
  121. const memLevel = opts.memLevel || constants.Z_DEFAULT_MEMLEVEL
  122. // API changed in node v9
  123. /* istanbul ignore next */
  124. if (/^v[0-8]\./.test(process.version)) {
  125. this[_handle].init(window,
  126. level,
  127. memLevel,
  128. strategy,
  129. opts.dictionary)
  130. } else {
  131. this[_handle].init(window,
  132. level,
  133. memLevel,
  134. strategy,
  135. this[_writeState],
  136. () => {},
  137. opts.dictionary)
  138. }
  139. this[_buffer] = Buffer.allocUnsafe(this[_chunkSize])
  140. this[_offset] = 0
  141. this[_level] = level
  142. this[_strategy] = strategy
  143. this.once('end', this.close)
  144. }
  145. close () {
  146. if (this[_handle]) {
  147. this[_handle].close()
  148. this[_handle] = null
  149. this.emit('close')
  150. }
  151. }
  152. params (level, strategy) {
  153. if (!this[_handle])
  154. throw new Error('cannot switch params when binding is closed')
  155. // no way to test this without also not supporting params at all
  156. /* istanbul ignore if */
  157. if (!this[_handle].params)
  158. throw new Error('not supported in this implementation')
  159. if (level < constants.Z_MIN_LEVEL ||
  160. level > constants.Z_MAX_LEVEL) {
  161. throw new RangeError('Invalid compression level: ' + level)
  162. }
  163. if (!(strategies.has(strategy)))
  164. throw new TypeError('Invalid strategy: ' + strategy)
  165. if (this[_level] !== level || this[_strategy] !== strategy) {
  166. this.flush(constants.Z_SYNC_FLUSH)
  167. assert(this[_handle], 'zlib binding closed')
  168. this[_handle].params(level, strategy)
  169. /* istanbul ignore else */
  170. if (!this[_hadError]) {
  171. this[_level] = level
  172. this[_strategy] = strategy
  173. }
  174. }
  175. }
  176. reset () {
  177. assert(this[_handle], 'zlib binding closed')
  178. return this[_handle].reset()
  179. }
  180. flush (kind) {
  181. if (kind === undefined)
  182. kind = constants.Z_FULL_FLUSH
  183. if (this.ended)
  184. return
  185. const flushFlag = this[_flushFlag]
  186. this[_flushFlag] = kind
  187. this.write(Buffer.alloc(0))
  188. this[_flushFlag] = flushFlag
  189. }
  190. end (chunk, encoding, cb) {
  191. if (chunk)
  192. this.write(chunk, encoding)
  193. this.flush(this[_finishFlush])
  194. this[_ended] = true
  195. return super.end(null, null, cb)
  196. }
  197. get ended () {
  198. return this[_ended]
  199. }
  200. write (chunk, encoding, cb) {
  201. // process the chunk using the sync process
  202. // then super.write() all the outputted chunks
  203. if (typeof encoding === 'function')
  204. cb = encoding, encoding = 'utf8'
  205. if (typeof chunk === 'string')
  206. chunk = new Buffer(chunk, encoding)
  207. let availInBefore = chunk && chunk.length
  208. let availOutBefore = this[_chunkSize] - this[_offset]
  209. let inOff = 0 // the offset of the input buffer
  210. const flushFlag = this[_flushFlag]
  211. let writeReturn = true
  212. assert(this[_handle], 'zlib binding closed')
  213. do {
  214. let res = this[_handle].writeSync(
  215. flushFlag,
  216. chunk, // in
  217. inOff, // in_off
  218. availInBefore, // in_len
  219. this[_buffer], // out
  220. this[_offset], //out_off
  221. availOutBefore // out_len
  222. )
  223. if (this[_hadError])
  224. break
  225. // API changed in v9
  226. /* istanbul ignore next */
  227. let availInAfter = res ? res[0] : this[_writeState][1]
  228. /* istanbul ignore next */
  229. let availOutAfter = res ? res[1] : this[_writeState][0]
  230. const have = availOutBefore - availOutAfter
  231. assert(have >= 0, 'have should not go down')
  232. if (have > 0) {
  233. const out = this[_buffer].slice(
  234. this[_offset], this[_offset] + have
  235. )
  236. this[_offset] += have
  237. // serve some output to the consumer.
  238. writeReturn = super.write(out) && writeReturn
  239. }
  240. // exhausted the output buffer, or used all the input create a new one.
  241. if (availOutAfter === 0 || this[_offset] >= this[_chunkSize]) {
  242. availOutBefore = this[_chunkSize]
  243. this[_offset] = 0
  244. this[_buffer] = Buffer.allocUnsafe(this[_chunkSize])
  245. }
  246. if (availOutAfter === 0) {
  247. // Not actually done. Need to reprocess.
  248. // Also, update the availInBefore to the availInAfter value,
  249. // so that if we have to hit it a third (fourth, etc.) time,
  250. // it'll have the correct byte counts.
  251. inOff += (availInBefore - availInAfter)
  252. availInBefore = availInAfter
  253. continue
  254. }
  255. break
  256. } while (!this[_hadError])
  257. if (cb)
  258. cb()
  259. return writeReturn
  260. }
  261. }
  262. // minimal 2-byte header
  263. class Deflate extends Zlib {
  264. constructor (opts) {
  265. super(opts, constants.DEFLATE)
  266. }
  267. }
  268. class Inflate extends Zlib {
  269. constructor (opts) {
  270. super(opts, constants.INFLATE)
  271. }
  272. }
  273. // gzip - bigger header, same deflate compression
  274. class Gzip extends Zlib {
  275. constructor (opts) {
  276. super(opts, constants.GZIP)
  277. }
  278. }
  279. class Gunzip extends Zlib {
  280. constructor (opts) {
  281. super(opts, constants.GUNZIP)
  282. }
  283. }
  284. // raw - no header
  285. class DeflateRaw extends Zlib {
  286. constructor (opts) {
  287. super(opts, constants.DEFLATERAW)
  288. }
  289. }
  290. class InflateRaw extends Zlib {
  291. constructor (opts) {
  292. super(opts, constants.INFLATERAW)
  293. }
  294. }
  295. // auto-detect header.
  296. class Unzip extends Zlib {
  297. constructor (opts) {
  298. super(opts, constants.UNZIP)
  299. }
  300. }
  301. exports.Deflate = Deflate
  302. exports.Inflate = Inflate
  303. exports.Gzip = Gzip
  304. exports.Gunzip = Gunzip
  305. exports.DeflateRaw = DeflateRaw
  306. exports.InflateRaw = InflateRaw
  307. exports.Unzip = Unzip