parse-stream.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. 'use strict'
  2. module.exports = parseStream
  3. const stream = require('stream')
  4. const TOMLParser = require('./lib/toml-parser.js')
  5. function parseStream (stm) {
  6. if (stm) {
  7. return parseReadable(stm)
  8. } else {
  9. return parseTransform(stm)
  10. }
  11. }
  12. function parseReadable (stm) {
  13. const parser = new TOMLParser()
  14. stm.setEncoding('utf8')
  15. return new Promise((resolve, reject) => {
  16. let readable
  17. let ended = false
  18. let errored = false
  19. function finish () {
  20. ended = true
  21. if (readable) return
  22. try {
  23. resolve(parser.finish())
  24. } catch (err) {
  25. reject(err)
  26. }
  27. }
  28. function error (err) {
  29. errored = true
  30. reject(err)
  31. }
  32. stm.once('end', finish)
  33. stm.once('error', error)
  34. readNext()
  35. function readNext () {
  36. readable = true
  37. let data
  38. while ((data = stm.read()) !== null) {
  39. try {
  40. parser.parse(data)
  41. } catch (err) {
  42. return error(err)
  43. }
  44. }
  45. readable = false
  46. /* istanbul ignore if */
  47. if (ended) return finish()
  48. /* istanbul ignore if */
  49. if (errored) return
  50. stm.once('readable', readNext)
  51. }
  52. })
  53. }
  54. function parseTransform () {
  55. const parser = new TOMLParser()
  56. return new stream.Transform({
  57. objectMode: true,
  58. transform (chunk, encoding, cb) {
  59. try {
  60. parser.parse(chunk.toString(encoding))
  61. } catch (err) {
  62. this.emit('error', err)
  63. }
  64. cb()
  65. },
  66. flush (cb) {
  67. try {
  68. this.push(parser.finish())
  69. } catch (err) {
  70. this.emit('error', err)
  71. }
  72. cb()
  73. }
  74. })
  75. }