├── .gitignore ├── .npmignore ├── .travis.yml ├── AUTHORS ├── LICENSE ├── README.md ├── binding.gyp ├── examples ├── parsefile.js ├── passthru.js ├── pipefile.js └── pushfile.js ├── lib ├── dvbtee.js └── parser.js ├── node-dvbtee.pro ├── package-lock.json ├── package.json ├── scripts └── prepare-publish.sh ├── src ├── async_factory_worker_cpp03.h ├── dvbtee-parser.cc ├── dvbtee-parser.h └── node-dvbtee.cc └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # nyc test coverage 19 | .nyc_output 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # node-waf configuration 25 | .lock-wscript 26 | 27 | # Compiled binary addons (http://nodejs.org/api/addons.html) 28 | build 29 | 30 | # Dependency directories 31 | node_modules 32 | jspm_packages 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional REPL history 38 | .node_repl_history 39 | 40 | # junk 41 | *.orig 42 | *.rej 43 | _stage 44 | 45 | # dvbtee library source code 46 | libdvbtee 47 | 48 | # sample ts files 49 | *.ts 50 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .dntrc 2 | .travis.yml 3 | .npmignore 4 | appveyor.yml 5 | Makefile 6 | cpplint.py 7 | doc/.build.sh 8 | node-dvbtee.pro 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | 3 | os: 4 | - linux 5 | - osx 6 | 7 | language: node_js 8 | node_js: 9 | - 'stable' 10 | - '0.10' 11 | - '0.12' 12 | - '4' 13 | - '5' 14 | - '6' 15 | - '7' 16 | - '8' 17 | - '9' 18 | - '10' 19 | - '11' 20 | - '12' 21 | - '13' 22 | - '14' 23 | 24 | env: 25 | matrix: 26 | exclude: 27 | - node_js: '0.12' 28 | os: osx 29 | include: 30 | - node_js: '0.12' 31 | os: osx 32 | osx_image: xcode7.3 33 | allow_failures: 34 | - node_js: '0.10' 35 | - node_js: '0.12' 36 | - node_js: '4' 37 | - node_js: '5' 38 | 39 | before_install: 40 | - npm install nan bindings mocha should 41 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Michael Ira Krufky (http://github.com/mkrufky) 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michael Ira Krufky 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-dvbtee 2 | 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/mkrufky/node-dvbtee.svg)](https://greenkeeper.io/) 4 | [![npm version](https://badge.fury.io/js/dvbtee.svg)](https://badge.fury.io/js/dvbtee) 5 | [![Build Status](https://travis-ci.org/mkrufky/node-dvbtee.svg?branch=master)](https://travis-ci.org/mkrufky/node-dvbtee) 6 | [![David](https://img.shields.io/david/mkrufky/node-dvbtee.svg)]() 7 | [![David](https://img.shields.io/david/optional/mkrufky/node-dvbtee.svg)]() 8 | [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](#license) 9 | 10 | node-dvbtee is an MPEG2 transport stream parser addon for Node.js 11 | 12 | Any standard MPEG2TS stream is supported, with additional specific support for broadcast television transport streams containing PSIP tables and descriptors. 13 | 14 | These tables and descriptors contain information about the stream, such as broadcast info, program info, and electronic program guide (EPG). 15 | 16 | [![NPM](https://nodei.co/npm/dvbtee.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/dvbtee) 17 | 18 | ## Installation 19 | 20 | ```bash 21 | $ npm install dvbtee 22 | ``` 23 | 24 | ## Example 25 | 26 | ```javascript 27 | var dvbtee = require('dvbtee') 28 | 29 | var parser = new dvbtee.Parser 30 | 31 | parser.on('data', function(data) { 32 | console.log('table id: ' + data.tableId, 33 | '\ntable name: ' + data.tableName, 34 | '\ntable data:\n', JSON.stringify(data, null, 2)) 35 | }) 36 | 37 | // on a stream: 38 | fs.createReadStream('sample1.ts').pipe(parser) 39 | 40 | // on a buffer: 41 | fs.readFile('sample2.ts', function(err, buf) { 42 | 43 | parser.feed(buf, buf.length, function(err, status) { 44 | 45 | if (err) 46 | console.log(err) 47 | else 48 | console.log('complete: status = ' + status) 49 | 50 | }) 51 | }) 52 | ``` 53 | 54 | ## Pass-Thru Mode Example 55 | 56 | ```javascript 57 | var dvbtee = require('dvbtee') 58 | 59 | var parser = new dvbtee.Parser({ 'passThru': true }) 60 | 61 | parser.on('psip', function(data) { 62 | console.log('table id: ' + data.tableId, 63 | '\ntable name: ' + data.tableName, 64 | '\ntable data:\n', JSON.stringify(data, null, 2)) 65 | }) 66 | 67 | // on a stream in pass-thru mode: 68 | fs.createReadStream('sample3.ts').pipe(parser).pipe(fs.createWriteStream('outfile.ts')) 69 | ``` 70 | 71 | ### Sample output from the above scripts 72 | ``` 73 | pushing 9029076 bytes 74 | table id: 0 75 | table name: PAT 76 | table data: 77 | { programs: [ { number: 1, pid: 48 }, { number: 2, pid: 64 } ], 78 | tableId: 0, 79 | tableName: 'PAT', 80 | tsId: 2157, 81 | version: 2 } 82 | table id: 199 83 | table name: MGT 84 | table data: 85 | { tableId: 199, 86 | tableName: 'MGT', 87 | tables: 88 | [ { bytes: 120, pid: 8187, type: 0, version: 1 }, 89 | { bytes: 409, pid: 5000, type: 256, version: 4 }, 90 | { bytes: 621, pid: 5001, type: 257, version: 4 }, 91 | { bytes: 431, pid: 5002, type: 258, version: 3 }, 92 | { bytes: 398, pid: 5003, type: 259, version: 3 }, 93 | { bytes: 308, pid: 5004, type: 260, version: 3 }, 94 | { bytes: 534, pid: 5005, type: 261, version: 3 }, 95 | { bytes: 434, pid: 5006, type: 262, version: 3 }, 96 | { bytes: 560, pid: 5007, type: 263, version: 3 }, 97 | { bytes: 365, pid: 5008, type: 264, version: 3 }, 98 | { bytes: 561, pid: 5009, type: 265, version: 3 }, 99 | { bytes: 446, pid: 5010, type: 266, version: 2 }, 100 | { bytes: 388, pid: 5011, type: 267, version: 2 }, 101 | { bytes: 297, pid: 5012, type: 268, version: 2 }, 102 | { bytes: 500, pid: 5013, type: 269, version: 2 }, 103 | { bytes: 423, pid: 5014, type: 270, version: 2 }, 104 | { bytes: 526, pid: 5015, type: 271, version: 2 }, 105 | { bytes: 421, pid: 5016, type: 272, version: 2 }, 106 | { bytes: 536, pid: 5017, type: 273, version: 2 }, 107 | { bytes: 430, pid: 5018, type: 274, version: 1 }, 108 | { bytes: 354, pid: 5019, type: 275, version: 1 }, 109 | { bytes: 280, pid: 5020, type: 276, version: 1 }, 110 | { bytes: 572, pid: 5021, type: 277, version: 1 }, 111 | { bytes: 406, pid: 5022, type: 278, version: 1 }, 112 | { bytes: 598, pid: 5023, type: 279, version: 1 }, 113 | { bytes: 719, pid: 5128, type: 512, version: 4 }, 114 | { bytes: 708, pid: 5129, type: 513, version: 4 }, 115 | { bytes: 700, pid: 5130, type: 514, version: 3 }, 116 | { bytes: 478, pid: 5131, type: 515, version: 3 }, 117 | { bytes: 511, pid: 5132, type: 516, version: 3 }, 118 | { bytes: 356, pid: 5133, type: 517, version: 3 }, 119 | { bytes: 667, pid: 5134, type: 518, version: 3 }, 120 | { bytes: 399, pid: 5135, type: 519, version: 3 }, 121 | { bytes: 571, pid: 5136, type: 520, version: 3 }, 122 | { bytes: 544, pid: 5137, type: 521, version: 3 }, 123 | { bytes: 591, pid: 5138, type: 522, version: 2 }, 124 | { bytes: 293, pid: 5139, type: 523, version: 2 }, 125 | { bytes: 490, pid: 5140, type: 524, version: 2 }, 126 | { bytes: 364, pid: 5141, type: 525, version: 2 }, 127 | { bytes: 677, pid: 5142, type: 526, version: 2 }, 128 | { bytes: 409, pid: 5143, type: 527, version: 2 }, 129 | { bytes: 760, pid: 5144, type: 528, version: 2 }, 130 | { bytes: 576, pid: 5145, type: 529, version: 2 }, 131 | { bytes: 645, pid: 5146, type: 530, version: 1 }, 132 | { bytes: 314, pid: 5147, type: 531, version: 1 }, 133 | { bytes: 463, pid: 5148, type: 532, version: 1 }, 134 | { bytes: 377, pid: 5149, type: 533, version: 1 }, 135 | { bytes: 542, pid: 5150, type: 534, version: 1 }, 136 | { bytes: 451, pid: 5151, type: 535, version: 1 } ], 137 | version: 25 } 138 | table id: 200 139 | table name: VCT 140 | table data: 141 | { channels: 142 | [ { accessControlled: false, 143 | carrierFreq: 0, 144 | etmLocation: 0, 145 | hidden: false, 146 | hideGuide: false, 147 | major: 2, 148 | minor: 1, 149 | modulation: 4, 150 | outOfBand: true, 151 | pathSelect: true, 152 | program: 1, 153 | serviceName: 'WCBS-HD', 154 | serviceType: 2, 155 | sourceId: 1, 156 | tsId: 2157 }, 157 | { accessControlled: false, 158 | carrierFreq: 0, 159 | etmLocation: 0, 160 | hidden: false, 161 | hideGuide: false, 162 | major: 2, 163 | minor: 2, 164 | modulation: 4, 165 | outOfBand: true, 166 | pathSelect: true, 167 | program: 2, 168 | serviceName: 'DECADES', 169 | serviceType: 2, 170 | sourceId: 2, 171 | tsId: 2157 } ], 172 | isCableVCT: false, 173 | tableId: 200, 174 | tableName: 'VCT', 175 | tsId: 2157, 176 | version: 1 } 177 | table id: 2 178 | table name: PMT 179 | table data: 180 | { pcrPid: 49, 181 | program: 1, 182 | streams: 183 | [ { pid: 49, streamType: 2, streamTypeString: 'Video MPEG-2' }, 184 | { pid: 52, 185 | streamType: 129, 186 | streamTypeString: 'Audio AC3 (ATSC)' }, 187 | { pid: 53, 188 | streamType: 129, 189 | streamTypeString: 'Audio AC3 (ATSC)' } ], 190 | tableId: 2, 191 | tableName: 'PMT', 192 | version: 1 } 193 | table id: 203 194 | table name: EIT 195 | table data: 196 | { events: 197 | [ { etmLoc: 1, 198 | eventId: 5083, 199 | lengthSec: 1800, 200 | startTime: 1137801616, 201 | title: 'The Insider' }, 202 | { etmLoc: 1, 203 | eventId: 5084, 204 | lengthSec: 1800, 205 | startTime: 1137803416, 206 | title: 'Entertainment Tonight' }, 207 | { etmLoc: 1, 208 | eventId: 5085, 209 | lengthSec: 3600, 210 | startTime: 1137805216, 211 | title: 'Supergirl' }, 212 | { etmLoc: 1, 213 | eventId: 5086, 214 | lengthSec: 3540, 215 | startTime: 1137808816, 216 | title: 'Scorpion' }, 217 | { etmLoc: 1, 218 | eventId: 5087, 219 | lengthSec: 3660, 220 | startTime: 1137812356, 221 | title: 'NCIS: Los Angeles' } ], 222 | extension: 1, 223 | sourceId: 1, 224 | tableId: 203, 225 | tableName: 'EIT', 226 | version: 4 } 227 | table id: 203 228 | table name: EIT 229 | table data: 230 | { events: 231 | [ { etmLoc: 1, 232 | eventId: 5156, 233 | lengthSec: 7200, 234 | startTime: 1138017616, 235 | title: 'CBS This Morning' }, 236 | { etmLoc: 1, 237 | eventId: 5157, 238 | lengthSec: 1800, 239 | startTime: 1138024816, 240 | title: 'Hot Bench' }, 241 | { etmLoc: 1, 242 | eventId: 5158, 243 | lengthSec: 1800, 244 | startTime: 1138026616, 245 | title: 'Hot Bench' } ], 246 | extension: 1, 247 | sourceId: 1, 248 | tableId: 203, 249 | tableName: 'EIT', 250 | version: 1 } 251 | table id: 203 252 | table name: EIT 253 | table data: 254 | { events: 255 | [ { etmLoc: 1, 256 | eventId: 5081, 257 | lengthSec: 3600, 258 | startTime: 1137801616, 259 | title: 'Through the Decades' }, 260 | { etmLoc: 1, 261 | eventId: 5082, 262 | lengthSec: 7200, 263 | startTime: 1137805216, 264 | title: 'The Day Reagan Was Shot' } ], 265 | extension: 2, 266 | sourceId: 2, 267 | tableId: 203, 268 | tableName: 'EIT', 269 | version: 4 } 270 | table id: 2 271 | table name: PMT 272 | table data: 273 | { pcrPid: 65, 274 | program: 2, 275 | streams: 276 | [ { pid: 65, streamType: 2, streamTypeString: 'Video MPEG-2' }, 277 | { pid: 68, 278 | streamType: 129, 279 | streamTypeString: 'Audio AC3 (ATSC)' } ], 280 | tableId: 2, 281 | tableName: 'PMT', 282 | version: 1 } 283 | table id: 203 284 | table name: EIT 285 | table data: 286 | { events: 287 | [ { etmLoc: 1, 288 | eventId: 5145, 289 | lengthSec: 3600, 290 | startTime: 1138017616, 291 | title: 'Through the Decades' }, 292 | { etmLoc: 1, 293 | eventId: 5146, 294 | lengthSec: 9000, 295 | startTime: 1138021216, 296 | title: 'Club Land' } ], 297 | extension: 2, 298 | sourceId: 2, 299 | tableId: 203, 300 | tableName: 'EIT', 301 | version: 1 } 302 | table id: 203 303 | table name: EIT 304 | table data: 305 | { events: 306 | [ { etmLoc: 0, 307 | eventId: 5159, 308 | lengthSec: 3600, 309 | startTime: 1138028416, 310 | title: 'Let\'s Make a Deal' }, 311 | { etmLoc: 0, 312 | eventId: 5160, 313 | lengthSec: 3600, 314 | startTime: 1138032016, 315 | title: 'The Price Is Right' }, 316 | { etmLoc: 1, 317 | eventId: 5161, 318 | lengthSec: 1800, 319 | startTime: 1138035616, 320 | title: 'CBS 2 News at Noon' }, 321 | { etmLoc: 1, 322 | eventId: 5162, 323 | lengthSec: 3600, 324 | startTime: 1138037416, 325 | title: 'The Young and the Restless' } ], 326 | extension: 1, 327 | sourceId: 1, 328 | tableId: 203, 329 | tableName: 'EIT', 330 | version: 1 } 331 | table id: 203 332 | table name: EIT 333 | table data: 334 | { events: 335 | [ { etmLoc: 1, 336 | eventId: 5146, 337 | lengthSec: 9000, 338 | startTime: 1138021216, 339 | title: 'Club Land' }, 340 | { etmLoc: 0, 341 | eventId: 5147, 342 | lengthSec: 1800, 343 | startTime: 1138030216, 344 | title: 'MovieStar' }, 345 | { etmLoc: 1, 346 | eventId: 5148, 347 | lengthSec: 3600, 348 | startTime: 1138032016, 349 | title: 'Kent State: The Day the War Came Home' }, 350 | { etmLoc: 1, 351 | eventId: 5149, 352 | lengthSec: 1800, 353 | startTime: 1138035616, 354 | title: 'Power Players' }, 355 | { etmLoc: 0, 356 | eventId: 5150, 357 | lengthSec: 1800, 358 | startTime: 1138037416, 359 | title: 'Power Players' } ], 360 | extension: 2, 361 | sourceId: 2, 362 | tableId: 203, 363 | tableName: 'EIT', 364 | version: 1 } 365 | table id: 203 366 | table name: EIT 367 | table data: 368 | { events: 369 | [ { etmLoc: 1, 370 | eventId: 5162, 371 | lengthSec: 3600, 372 | startTime: 1138037416, 373 | title: 'The Young and the Restless' }, 374 | { etmLoc: 1, 375 | eventId: 5163, 376 | lengthSec: 1800, 377 | startTime: 1138041016, 378 | title: 'The Bold and the Beautiful' }, 379 | { etmLoc: 1, 380 | eventId: 5164, 381 | lengthSec: 3600, 382 | startTime: 1138042816, 383 | title: 'The Talk' }, 384 | { etmLoc: 1, 385 | eventId: 5165, 386 | lengthSec: 3600, 387 | startTime: 1138046416, 388 | title: 'Dr. Phil' } ], 389 | extension: 1, 390 | sourceId: 1, 391 | tableId: 203, 392 | tableName: 'EIT', 393 | version: 1 } 394 | table id: 203 395 | table name: EIT 396 | table data: 397 | { events: 398 | [ { etmLoc: 1, 399 | eventId: 5151, 400 | lengthSec: 3600, 401 | startTime: 1138039216, 402 | title: 'Through the Decades' }, 403 | { etmLoc: 1, 404 | eventId: 5152, 405 | lengthSec: 9000, 406 | startTime: 1138042816, 407 | title: 'Club Land' } ], 408 | extension: 2, 409 | sourceId: 2, 410 | tableId: 203, 411 | tableName: 'EIT', 412 | version: 1 } 413 | table id: 203 414 | table name: EIT 415 | table data: 416 | { events: 417 | [ { etmLoc: 0, 418 | eventId: 5166, 419 | lengthSec: 1800, 420 | startTime: 1138050016, 421 | title: 'Judge Judy' }, 422 | { etmLoc: 1, 423 | eventId: 5167, 424 | lengthSec: 1800, 425 | startTime: 1138051816, 426 | title: 'Judge Judy' }, 427 | { etmLoc: 1, 428 | eventId: 5168, 429 | lengthSec: 3600, 430 | startTime: 1138053616, 431 | title: 'CBS 2 News at 5PM' }, 432 | { etmLoc: 1, 433 | eventId: 5169, 434 | lengthSec: 1800, 435 | startTime: 1138057216, 436 | title: 'CBS 2 News at 6PM' }, 437 | { etmLoc: 0, 438 | eventId: 5170, 439 | lengthSec: 1800, 440 | startTime: 1138059016, 441 | title: 'CBS Evening News With Scott Pelley' } ], 442 | extension: 1, 443 | sourceId: 1, 444 | tableId: 203, 445 | tableName: 'EIT', 446 | version: 1 } 447 | table id: 205 448 | table name: STT 449 | table data: 450 | { descriptors: [], 451 | tableId: 205, 452 | tableName: 'STT', 453 | time: 1453775318 } 454 | table id: 203 455 | table name: EIT 456 | table data: 457 | { events: 458 | [ { etmLoc: 1, 459 | eventId: 5152, 460 | lengthSec: 9000, 461 | startTime: 1138042816, 462 | title: 'Club Land' }, 463 | { etmLoc: 0, 464 | eventId: 5153, 465 | lengthSec: 1800, 466 | startTime: 1138051816, 467 | title: 'MovieStar' }, 468 | { etmLoc: 1, 469 | eventId: 5154, 470 | lengthSec: 3600, 471 | startTime: 1138053616, 472 | title: 'Kent State: The Day the War Came Home' }, 473 | { etmLoc: 1, 474 | eventId: 5155, 475 | lengthSec: 1800, 476 | startTime: 1138057216, 477 | title: 'Power Players' }, 478 | { etmLoc: 0, 479 | eventId: 5156, 480 | lengthSec: 1800, 481 | startTime: 1138059016, 482 | title: 'Power Players' } ], 483 | extension: 2, 484 | sourceId: 2, 485 | tableId: 203, 486 | tableName: 'EIT', 487 | version: 1 } 488 | table id: 203 489 | table name: EIT 490 | table data: 491 | { events: 492 | [ { etmLoc: 1, 493 | eventId: 5090, 494 | lengthSec: 3600, 495 | startTime: 1137821836, 496 | title: 'The Late Late Show With James Corden' }, 497 | { etmLoc: 1, 498 | eventId: 5091, 499 | lengthSec: 1800, 500 | startTime: 1137825436, 501 | title: 'Comics Unleashed With Byron Allen' }, 502 | { etmLoc: 1, 503 | eventId: 5092, 504 | lengthSec: 1800, 505 | startTime: 1137827236, 506 | title: 'Fast Joint Relief' }, 507 | { etmLoc: 1, 508 | eventId: 5093, 509 | lengthSec: 1800, 510 | startTime: 1137829036, 511 | title: 'Larry King Special Report' }, 512 | { etmLoc: 1, 513 | eventId: 5094, 514 | lengthSec: 3180, 515 | startTime: 1137830836, 516 | title: 'CBS Overnight News' } ], 517 | extension: 1, 518 | sourceId: 1, 519 | tableId: 203, 520 | tableName: 'EIT', 521 | version: 3 } 522 | table id: 203 523 | table name: EIT 524 | table data: 525 | { events: 526 | [ { etmLoc: 1, 527 | eventId: 5089, 528 | lengthSec: 3600, 529 | startTime: 1137823216, 530 | title: 'Through the Decades' }, 531 | { etmLoc: 1, 532 | eventId: 5090, 533 | lengthSec: 7200, 534 | startTime: 1137826816, 535 | title: 'The Day Reagan Was Shot' } ], 536 | extension: 2, 537 | sourceId: 2, 538 | tableId: 203, 539 | tableName: 'EIT', 540 | version: 3 } 541 | table id: 203 542 | table name: EIT 543 | table data: 544 | { events: 545 | [ { etmLoc: 1, 546 | eventId: 5095, 547 | lengthSec: 1800, 548 | startTime: 1137834016, 549 | title: 'CBS Morning News' }, 550 | { etmLoc: 1, 551 | eventId: 5096, 552 | lengthSec: 9000, 553 | startTime: 1137835816, 554 | title: 'CBS 2 News This Morning' } ], 555 | extension: 1, 556 | sourceId: 1, 557 | tableId: 203, 558 | tableName: 'EIT', 559 | version: 3 } 560 | table id: 203 561 | table name: EIT 562 | table data: 563 | { events: 564 | [ { etmLoc: 1, 565 | eventId: 5091, 566 | lengthSec: 1800, 567 | startTime: 1137834016, 568 | title: 'The Greats' }, 569 | { etmLoc: 1, 570 | eventId: 5092, 571 | lengthSec: 1800, 572 | startTime: 1137835816, 573 | title: 'The Greats' }, 574 | { etmLoc: 0, 575 | eventId: 5093, 576 | lengthSec: 1800, 577 | startTime: 1137837616, 578 | title: 'Power Players' }, 579 | { etmLoc: 0, 580 | eventId: 5094, 581 | lengthSec: 1800, 582 | startTime: 1137839416, 583 | title: 'Power Players' }, 584 | { etmLoc: 1, 585 | eventId: 5095, 586 | lengthSec: 1800, 587 | startTime: 1137841216, 588 | title: 'The Achievers' }, 589 | { etmLoc: 1, 590 | eventId: 5096, 591 | lengthSec: 1800, 592 | startTime: 1137843016, 593 | title: 'M*A*S*H' } ], 594 | extension: 2, 595 | sourceId: 2, 596 | tableId: 203, 597 | tableName: 'EIT', 598 | version: 3 } 599 | table id: 203 600 | table name: EIT 601 | table data: 602 | { events: 603 | [ { etmLoc: 1, 604 | eventId: 5087, 605 | lengthSec: 3660, 606 | startTime: 1137812356, 607 | title: 'NCIS: Los Angeles' }, 608 | { etmLoc: 1, 609 | eventId: 5088, 610 | lengthSec: 2100, 611 | startTime: 1137816016, 612 | title: 'CBS 2 News at 11PM' }, 613 | { etmLoc: 1, 614 | eventId: 5089, 615 | lengthSec: 3720, 616 | startTime: 1137818116, 617 | title: 'The Late Show With Stephen Colbert' }, 618 | { etmLoc: 1, 619 | eventId: 5090, 620 | lengthSec: 3600, 621 | startTime: 1137821836, 622 | title: 'The Late Late Show With James Corden' } ], 623 | extension: 1, 624 | sourceId: 1, 625 | tableId: 203, 626 | tableName: 'EIT', 627 | version: 4 } 628 | table id: 203 629 | table name: EIT 630 | table data: 631 | { events: 632 | [ { etmLoc: 1, 633 | eventId: 5097, 634 | lengthSec: 7200, 635 | startTime: 1137844816, 636 | title: 'CBS This Morning' }, 637 | { etmLoc: 1, 638 | eventId: 5098, 639 | lengthSec: 1800, 640 | startTime: 1137852016, 641 | title: 'Hot Bench' }, 642 | { etmLoc: 1, 643 | eventId: 5099, 644 | lengthSec: 1800, 645 | startTime: 1137853816, 646 | title: 'Hot Bench' } ], 647 | extension: 1, 648 | sourceId: 1, 649 | tableId: 203, 650 | tableName: 'EIT', 651 | version: 3 } 652 | table id: 203 653 | table name: EIT 654 | table data: 655 | { events: 656 | [ { etmLoc: 1, 657 | eventId: 5083, 658 | lengthSec: 1800, 659 | startTime: 1137812416, 660 | title: 'The Greats' }, 661 | { etmLoc: 1, 662 | eventId: 5084, 663 | lengthSec: 1800, 664 | startTime: 1137814216, 665 | title: 'The Greats' }, 666 | { etmLoc: 0, 667 | eventId: 5085, 668 | lengthSec: 1800, 669 | startTime: 1137816016, 670 | title: 'Power Players' }, 671 | { etmLoc: 0, 672 | eventId: 5086, 673 | lengthSec: 1800, 674 | startTime: 1137817816, 675 | title: 'Power Players' }, 676 | { etmLoc: 1, 677 | eventId: 5087, 678 | lengthSec: 1800, 679 | startTime: 1137819616, 680 | title: 'The Achievers' }, 681 | { etmLoc: 1, 682 | eventId: 5088, 683 | lengthSec: 1800, 684 | startTime: 1137821416, 685 | title: 'M*A*S*H' } ], 686 | extension: 2, 687 | sourceId: 2, 688 | tableId: 203, 689 | tableName: 'EIT', 690 | version: 4 } 691 | table id: 203 692 | table name: EIT 693 | table data: 694 | { events: 695 | [ { etmLoc: 1, 696 | eventId: 5097, 697 | lengthSec: 3600, 698 | startTime: 1137844816, 699 | title: 'Through the Decades' }, 700 | { etmLoc: 1, 701 | eventId: 5098, 702 | lengthSec: 7200, 703 | startTime: 1137848416, 704 | title: 'Ann Rule Presents: The Stranger Beside Me' } ], 705 | extension: 2, 706 | sourceId: 2, 707 | tableId: 203, 708 | tableName: 'EIT', 709 | version: 3 } 710 | table id: 203 711 | table name: EIT 712 | table data: 713 | { events: 714 | [ { etmLoc: 1, 715 | eventId: 5119, 716 | lengthSec: 3600, 717 | startTime: 1137908236, 718 | title: 'The Late Late Show With James Corden' }, 719 | { etmLoc: 1, 720 | eventId: 5120, 721 | lengthSec: 1800, 722 | startTime: 1137911836, 723 | title: 'Comics Unleashed With Byron Allen' }, 724 | { etmLoc: 1, 725 | eventId: 5121, 726 | lengthSec: 1800, 727 | startTime: 1137913636, 728 | title: 'Paid Programming' }, 729 | { etmLoc: 1, 730 | eventId: 5122, 731 | lengthSec: 1800, 732 | startTime: 1137915436, 733 | title: 'How to Avoid a Facelift' }, 734 | { etmLoc: 1, 735 | eventId: 5123, 736 | lengthSec: 3180, 737 | startTime: 1137917236, 738 | title: 'CBS Overnight News' } ], 739 | extension: 1, 740 | sourceId: 1, 741 | tableId: 203, 742 | tableName: 'EIT', 743 | version: 2 } 744 | table id: 203 745 | table name: EIT 746 | table data: 747 | { events: 748 | [ { etmLoc: 1, 749 | eventId: 5115, 750 | lengthSec: 3600, 751 | startTime: 1137909616, 752 | title: 'Through the Decades' }, 753 | { etmLoc: 1, 754 | eventId: 5116, 755 | lengthSec: 7200, 756 | startTime: 1137913216, 757 | title: 'Ann Rule Presents: The Stranger Beside Me' } ], 758 | extension: 2, 759 | sourceId: 2, 760 | tableId: 203, 761 | tableName: 'EIT', 762 | version: 2 } 763 | complete: status = 0 764 | ``` 765 | 766 | ## License 767 | MIT License 768 | 769 | Copyright (c) 2018 Michael Ira Krufky 770 | 771 | Permission is hereby granted, free of charge, to any person obtaining a copy 772 | of this software and associated documentation files (the "Software"), to deal 773 | in the Software without restriction, including without limitation the rights 774 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 775 | copies of the Software, and to permit persons to whom the Software is 776 | furnished to do so, subject to the following conditions: 777 | 778 | The above copyright notice and this permission notice shall be included in all 779 | copies or substantial portions of the Software. 780 | 781 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 782 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 783 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 784 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 785 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 786 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 787 | SOFTWARE. 788 | 789 | [![Analytics](https://ga-beacon.appspot.com/UA-71301363-4/mkrufky/node-dvbtee/README.md)](https://github.com/igrigorik/ga-beacon) 790 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "dvbtee", 5 | "sources": [ 6 | "src/node-dvbtee.cc", 7 | "src/dvbtee-parser.cc" 8 | ], 9 | "dependencies": [ 10 | " 0) { 93 | try { 94 | var b = Buffer.concat( 95 | [ self._buffer, chunk.slice(0, 188 - self._buffer.length) ], 188) 96 | self.feed(b, b.length, function (err) { 97 | chunk = chunk.slice(188 - self._buffer.length) 98 | cb(err) 99 | }) 100 | if (self.options.passThru) { 101 | self.push(b) 102 | } 103 | } catch (err) { 104 | cb(err) 105 | } 106 | } else { 107 | cb() 108 | } 109 | } 110 | 111 | var feedChunk = function (cb) { 112 | 113 | try { 114 | var next = 188 * Math.floor(chunk.length / 188) 115 | var b = chunk.slice(0, next) 116 | 117 | self.feed(b, b.length, function (err) { 118 | self._buffer = chunk.slice(next) 119 | cb(err) 120 | }) 121 | if (self.options.passThru) { 122 | self.push(b) 123 | } 124 | } catch (err) { 125 | cb(err) 126 | } 127 | } 128 | 129 | checkCache(function () { 130 | feedCache(function (err) { 131 | if (err) { 132 | done(err) 133 | } else { 134 | feedChunk(done) 135 | } 136 | }) 137 | }) 138 | } 139 | 140 | Parser.prototype._flush = function (done) { 141 | 142 | var self = this 143 | 144 | // don't bother sending partial packets to the TS Parser- they'll just get dropped 145 | if ((self.options.passThru) && (self._buffer.length > 0)) { 146 | self.push(self._buffer) 147 | self._buffer = self.bufferAllocUnsafe(0) 148 | } 149 | done() 150 | } 151 | 152 | module.exports = Parser 153 | -------------------------------------------------------------------------------- /node-dvbtee.pro: -------------------------------------------------------------------------------- 1 | OTHER_FILES += \ 2 | lib/dvbtee.js \ 3 | lib/parser.js \ 4 | src/node-dvbtee.cc \ 5 | src/dvbtee-parser.cc \ 6 | src/dvbtee-parser.h \ 7 | src/async_factory_worker_cpp03.h \ 8 | test/test.js \ 9 | binding.gyp \ 10 | package.json \ 11 | scripts/configure-build.js 12 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dvbtee", 3 | "version": "0.4.5", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ansi-colors": { 8 | "version": "3.2.3", 9 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", 10 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", 11 | "dev": true 12 | }, 13 | "ansi-regex": { 14 | "version": "3.0.0", 15 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 16 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 17 | "dev": true 18 | }, 19 | "ansi-styles": { 20 | "version": "3.2.1", 21 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 22 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 23 | "dev": true, 24 | "requires": { 25 | "color-convert": "^1.9.0" 26 | } 27 | }, 28 | "anymatch": { 29 | "version": "3.1.1", 30 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 31 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 32 | "dev": true, 33 | "requires": { 34 | "normalize-path": "^3.0.0", 35 | "picomatch": "^2.0.4" 36 | } 37 | }, 38 | "argparse": { 39 | "version": "1.0.10", 40 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 41 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 42 | "dev": true, 43 | "requires": { 44 | "sprintf-js": "~1.0.2" 45 | } 46 | }, 47 | "async-factory-worker": { 48 | "version": "0.0.1", 49 | "resolved": "https://registry.npmjs.org/async-factory-worker/-/async-factory-worker-0.0.1.tgz", 50 | "integrity": "sha512-P+c23JrO66j1FPfZx9kD+5fdPoSCHXSLpZCsiivweGezc1x/mwT99PSiA6ZZzYsdCjMnRpQuG/bl93a43VTzJQ==", 51 | "requires": { 52 | "nan": "^2.10.0" 53 | } 54 | }, 55 | "balanced-match": { 56 | "version": "1.0.0", 57 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 58 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 59 | "dev": true 60 | }, 61 | "binary-extensions": { 62 | "version": "2.0.0", 63 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", 64 | "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", 65 | "dev": true 66 | }, 67 | "bindings": { 68 | "version": "1.5.0", 69 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 70 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 71 | "optional": true, 72 | "requires": { 73 | "file-uri-to-path": "1.0.0" 74 | } 75 | }, 76 | "brace-expansion": { 77 | "version": "1.1.11", 78 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 79 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 80 | "dev": true, 81 | "requires": { 82 | "balanced-match": "^1.0.0", 83 | "concat-map": "0.0.1" 84 | } 85 | }, 86 | "braces": { 87 | "version": "3.0.2", 88 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 89 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 90 | "dev": true, 91 | "requires": { 92 | "fill-range": "^7.0.1" 93 | } 94 | }, 95 | "browser-stdout": { 96 | "version": "1.3.1", 97 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 98 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 99 | "dev": true 100 | }, 101 | "camelcase": { 102 | "version": "5.3.1", 103 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 104 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 105 | "dev": true 106 | }, 107 | "chalk": { 108 | "version": "2.4.2", 109 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 110 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 111 | "dev": true, 112 | "requires": { 113 | "ansi-styles": "^3.2.1", 114 | "escape-string-regexp": "^1.0.5", 115 | "supports-color": "^5.3.0" 116 | }, 117 | "dependencies": { 118 | "supports-color": { 119 | "version": "5.5.0", 120 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 121 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 122 | "dev": true, 123 | "requires": { 124 | "has-flag": "^3.0.0" 125 | } 126 | } 127 | } 128 | }, 129 | "chokidar": { 130 | "version": "3.3.0", 131 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", 132 | "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", 133 | "dev": true, 134 | "requires": { 135 | "anymatch": "~3.1.1", 136 | "braces": "~3.0.2", 137 | "fsevents": "~2.1.1", 138 | "glob-parent": "~5.1.0", 139 | "is-binary-path": "~2.1.0", 140 | "is-glob": "~4.0.1", 141 | "normalize-path": "~3.0.0", 142 | "readdirp": "~3.2.0" 143 | } 144 | }, 145 | "cliui": { 146 | "version": "5.0.0", 147 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 148 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 149 | "dev": true, 150 | "requires": { 151 | "string-width": "^3.1.0", 152 | "strip-ansi": "^5.2.0", 153 | "wrap-ansi": "^5.1.0" 154 | }, 155 | "dependencies": { 156 | "ansi-regex": { 157 | "version": "4.1.0", 158 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 159 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 160 | "dev": true 161 | }, 162 | "string-width": { 163 | "version": "3.1.0", 164 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 165 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 166 | "dev": true, 167 | "requires": { 168 | "emoji-regex": "^7.0.1", 169 | "is-fullwidth-code-point": "^2.0.0", 170 | "strip-ansi": "^5.1.0" 171 | } 172 | }, 173 | "strip-ansi": { 174 | "version": "5.2.0", 175 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 176 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 177 | "dev": true, 178 | "requires": { 179 | "ansi-regex": "^4.1.0" 180 | } 181 | } 182 | } 183 | }, 184 | "color-convert": { 185 | "version": "1.9.3", 186 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 187 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 188 | "dev": true, 189 | "requires": { 190 | "color-name": "1.1.3" 191 | } 192 | }, 193 | "color-name": { 194 | "version": "1.1.3", 195 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 196 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 197 | "dev": true 198 | }, 199 | "concat-map": { 200 | "version": "0.0.1", 201 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 202 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 203 | "dev": true 204 | }, 205 | "debug": { 206 | "version": "3.2.6", 207 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 208 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 209 | "dev": true, 210 | "requires": { 211 | "ms": "^2.1.1" 212 | } 213 | }, 214 | "decamelize": { 215 | "version": "1.2.0", 216 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 217 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 218 | "dev": true 219 | }, 220 | "define-properties": { 221 | "version": "1.1.3", 222 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 223 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 224 | "dev": true, 225 | "requires": { 226 | "object-keys": "^1.0.12" 227 | } 228 | }, 229 | "diff": { 230 | "version": "3.5.0", 231 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 232 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 233 | "dev": true 234 | }, 235 | "emoji-regex": { 236 | "version": "7.0.3", 237 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 238 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 239 | "dev": true 240 | }, 241 | "es-abstract": { 242 | "version": "1.17.5", 243 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", 244 | "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", 245 | "dev": true, 246 | "requires": { 247 | "es-to-primitive": "^1.2.1", 248 | "function-bind": "^1.1.1", 249 | "has": "^1.0.3", 250 | "has-symbols": "^1.0.1", 251 | "is-callable": "^1.1.5", 252 | "is-regex": "^1.0.5", 253 | "object-inspect": "^1.7.0", 254 | "object-keys": "^1.1.1", 255 | "object.assign": "^4.1.0", 256 | "string.prototype.trimleft": "^2.1.1", 257 | "string.prototype.trimright": "^2.1.1" 258 | } 259 | }, 260 | "es-to-primitive": { 261 | "version": "1.2.1", 262 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 263 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 264 | "dev": true, 265 | "requires": { 266 | "is-callable": "^1.1.4", 267 | "is-date-object": "^1.0.1", 268 | "is-symbol": "^1.0.2" 269 | } 270 | }, 271 | "escape-string-regexp": { 272 | "version": "1.0.5", 273 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 274 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 275 | "dev": true 276 | }, 277 | "esprima": { 278 | "version": "4.0.1", 279 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 280 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 281 | "dev": true 282 | }, 283 | "file-uri-to-path": { 284 | "version": "1.0.0", 285 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 286 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", 287 | "optional": true 288 | }, 289 | "fill-range": { 290 | "version": "7.0.1", 291 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 292 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 293 | "dev": true, 294 | "requires": { 295 | "to-regex-range": "^5.0.1" 296 | } 297 | }, 298 | "find-up": { 299 | "version": "3.0.0", 300 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 301 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 302 | "dev": true, 303 | "requires": { 304 | "locate-path": "^3.0.0" 305 | } 306 | }, 307 | "flat": { 308 | "version": "4.1.0", 309 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 310 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 311 | "dev": true, 312 | "requires": { 313 | "is-buffer": "~2.0.3" 314 | } 315 | }, 316 | "fs.realpath": { 317 | "version": "1.0.0", 318 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 319 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 320 | "dev": true 321 | }, 322 | "fsevents": { 323 | "version": "2.1.3", 324 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 325 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 326 | "dev": true, 327 | "optional": true 328 | }, 329 | "function-bind": { 330 | "version": "1.1.1", 331 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 332 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 333 | "dev": true 334 | }, 335 | "get-caller-file": { 336 | "version": "2.0.5", 337 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 338 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 339 | "dev": true 340 | }, 341 | "glob": { 342 | "version": "7.1.3", 343 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 344 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 345 | "dev": true, 346 | "requires": { 347 | "fs.realpath": "^1.0.0", 348 | "inflight": "^1.0.4", 349 | "inherits": "2", 350 | "minimatch": "^3.0.4", 351 | "once": "^1.3.0", 352 | "path-is-absolute": "^1.0.0" 353 | } 354 | }, 355 | "glob-parent": { 356 | "version": "5.1.1", 357 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 358 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 359 | "dev": true, 360 | "requires": { 361 | "is-glob": "^4.0.1" 362 | } 363 | }, 364 | "growl": { 365 | "version": "1.10.5", 366 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 367 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 368 | "dev": true 369 | }, 370 | "has": { 371 | "version": "1.0.3", 372 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 373 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 374 | "dev": true, 375 | "requires": { 376 | "function-bind": "^1.1.1" 377 | } 378 | }, 379 | "has-flag": { 380 | "version": "3.0.0", 381 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 382 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 383 | "dev": true 384 | }, 385 | "has-symbols": { 386 | "version": "1.0.1", 387 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 388 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 389 | "dev": true 390 | }, 391 | "he": { 392 | "version": "1.2.0", 393 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 394 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 395 | "dev": true 396 | }, 397 | "inflight": { 398 | "version": "1.0.6", 399 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 400 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 401 | "dev": true, 402 | "requires": { 403 | "once": "^1.3.0", 404 | "wrappy": "1" 405 | } 406 | }, 407 | "inherits": { 408 | "version": "2.0.4", 409 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 410 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 411 | "dev": true 412 | }, 413 | "is-binary-path": { 414 | "version": "2.1.0", 415 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 416 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 417 | "dev": true, 418 | "requires": { 419 | "binary-extensions": "^2.0.0" 420 | } 421 | }, 422 | "is-buffer": { 423 | "version": "2.0.4", 424 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 425 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 426 | "dev": true 427 | }, 428 | "is-callable": { 429 | "version": "1.1.5", 430 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", 431 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", 432 | "dev": true 433 | }, 434 | "is-date-object": { 435 | "version": "1.0.2", 436 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 437 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 438 | "dev": true 439 | }, 440 | "is-extglob": { 441 | "version": "2.1.1", 442 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 443 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 444 | "dev": true 445 | }, 446 | "is-fullwidth-code-point": { 447 | "version": "2.0.0", 448 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 449 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 450 | "dev": true 451 | }, 452 | "is-glob": { 453 | "version": "4.0.1", 454 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 455 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 456 | "dev": true, 457 | "requires": { 458 | "is-extglob": "^2.1.1" 459 | } 460 | }, 461 | "is-number": { 462 | "version": "7.0.0", 463 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 464 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 465 | "dev": true 466 | }, 467 | "is-regex": { 468 | "version": "1.0.5", 469 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", 470 | "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", 471 | "dev": true, 472 | "requires": { 473 | "has": "^1.0.3" 474 | } 475 | }, 476 | "is-symbol": { 477 | "version": "1.0.3", 478 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 479 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 480 | "dev": true, 481 | "requires": { 482 | "has-symbols": "^1.0.1" 483 | } 484 | }, 485 | "isexe": { 486 | "version": "2.0.0", 487 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 488 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 489 | "dev": true 490 | }, 491 | "js-yaml": { 492 | "version": "3.13.1", 493 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 494 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 495 | "dev": true, 496 | "requires": { 497 | "argparse": "^1.0.7", 498 | "esprima": "^4.0.0" 499 | } 500 | }, 501 | "libdvbtee_parser": { 502 | "version": "0.6.7", 503 | "resolved": "https://registry.npmjs.org/libdvbtee_parser/-/libdvbtee_parser-0.6.7.tgz", 504 | "integrity": "sha512-+AvxfHlNeZRFUftkwxX/7F90Une5uZOuX9gKisLLx186NU1eBvB6JeuC2YInMr8x3bdh4eFS5G+At3UDJ+KhAA==" 505 | }, 506 | "locate-path": { 507 | "version": "3.0.0", 508 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 509 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 510 | "dev": true, 511 | "requires": { 512 | "p-locate": "^3.0.0", 513 | "path-exists": "^3.0.0" 514 | } 515 | }, 516 | "lodash": { 517 | "version": "4.17.15", 518 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 519 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 520 | "dev": true 521 | }, 522 | "log-symbols": { 523 | "version": "3.0.0", 524 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", 525 | "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", 526 | "dev": true, 527 | "requires": { 528 | "chalk": "^2.4.2" 529 | } 530 | }, 531 | "minimatch": { 532 | "version": "3.0.4", 533 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 534 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 535 | "dev": true, 536 | "requires": { 537 | "brace-expansion": "^1.1.7" 538 | } 539 | }, 540 | "minimist": { 541 | "version": "1.2.5", 542 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 543 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 544 | "dev": true 545 | }, 546 | "mkdirp": { 547 | "version": "0.5.5", 548 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 549 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 550 | "dev": true, 551 | "requires": { 552 | "minimist": "^1.2.5" 553 | } 554 | }, 555 | "mocha": { 556 | "version": "7.1.2", 557 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", 558 | "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", 559 | "dev": true, 560 | "requires": { 561 | "ansi-colors": "3.2.3", 562 | "browser-stdout": "1.3.1", 563 | "chokidar": "3.3.0", 564 | "debug": "3.2.6", 565 | "diff": "3.5.0", 566 | "escape-string-regexp": "1.0.5", 567 | "find-up": "3.0.0", 568 | "glob": "7.1.3", 569 | "growl": "1.10.5", 570 | "he": "1.2.0", 571 | "js-yaml": "3.13.1", 572 | "log-symbols": "3.0.0", 573 | "minimatch": "3.0.4", 574 | "mkdirp": "0.5.5", 575 | "ms": "2.1.1", 576 | "node-environment-flags": "1.0.6", 577 | "object.assign": "4.1.0", 578 | "strip-json-comments": "2.0.1", 579 | "supports-color": "6.0.0", 580 | "which": "1.3.1", 581 | "wide-align": "1.1.3", 582 | "yargs": "13.3.2", 583 | "yargs-parser": "13.1.2", 584 | "yargs-unparser": "1.6.0" 585 | } 586 | }, 587 | "ms": { 588 | "version": "2.1.1", 589 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 590 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 591 | "dev": true 592 | }, 593 | "nan": { 594 | "version": "2.14.1", 595 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", 596 | "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" 597 | }, 598 | "node-environment-flags": { 599 | "version": "1.0.6", 600 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", 601 | "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", 602 | "dev": true, 603 | "requires": { 604 | "object.getownpropertydescriptors": "^2.0.3", 605 | "semver": "^5.7.0" 606 | } 607 | }, 608 | "normalize-path": { 609 | "version": "3.0.0", 610 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 611 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 612 | "dev": true 613 | }, 614 | "object-inspect": { 615 | "version": "1.7.0", 616 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", 617 | "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", 618 | "dev": true 619 | }, 620 | "object-keys": { 621 | "version": "1.1.1", 622 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 623 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 624 | "dev": true 625 | }, 626 | "object.assign": { 627 | "version": "4.1.0", 628 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 629 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 630 | "dev": true, 631 | "requires": { 632 | "define-properties": "^1.1.2", 633 | "function-bind": "^1.1.1", 634 | "has-symbols": "^1.0.0", 635 | "object-keys": "^1.0.11" 636 | } 637 | }, 638 | "object.getownpropertydescriptors": { 639 | "version": "2.1.0", 640 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", 641 | "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", 642 | "dev": true, 643 | "requires": { 644 | "define-properties": "^1.1.3", 645 | "es-abstract": "^1.17.0-next.1" 646 | } 647 | }, 648 | "once": { 649 | "version": "1.4.0", 650 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 651 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 652 | "dev": true, 653 | "requires": { 654 | "wrappy": "1" 655 | } 656 | }, 657 | "p-limit": { 658 | "version": "2.3.0", 659 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 660 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 661 | "dev": true, 662 | "requires": { 663 | "p-try": "^2.0.0" 664 | } 665 | }, 666 | "p-locate": { 667 | "version": "3.0.0", 668 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 669 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 670 | "dev": true, 671 | "requires": { 672 | "p-limit": "^2.0.0" 673 | } 674 | }, 675 | "p-try": { 676 | "version": "2.2.0", 677 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 678 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 679 | "dev": true 680 | }, 681 | "path-exists": { 682 | "version": "3.0.0", 683 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 684 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 685 | "dev": true 686 | }, 687 | "path-is-absolute": { 688 | "version": "1.0.1", 689 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 690 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 691 | "dev": true 692 | }, 693 | "picomatch": { 694 | "version": "2.2.2", 695 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 696 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 697 | "dev": true 698 | }, 699 | "readdirp": { 700 | "version": "3.2.0", 701 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", 702 | "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", 703 | "dev": true, 704 | "requires": { 705 | "picomatch": "^2.0.4" 706 | } 707 | }, 708 | "require-directory": { 709 | "version": "2.1.1", 710 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 711 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 712 | "dev": true 713 | }, 714 | "require-main-filename": { 715 | "version": "2.0.0", 716 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 717 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 718 | "dev": true 719 | }, 720 | "semver": { 721 | "version": "5.7.1", 722 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 723 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 724 | "dev": true 725 | }, 726 | "set-blocking": { 727 | "version": "2.0.0", 728 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 729 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 730 | "dev": true 731 | }, 732 | "should": { 733 | "version": "13.2.3", 734 | "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", 735 | "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", 736 | "dev": true, 737 | "requires": { 738 | "should-equal": "^2.0.0", 739 | "should-format": "^3.0.3", 740 | "should-type": "^1.4.0", 741 | "should-type-adaptors": "^1.0.1", 742 | "should-util": "^1.0.0" 743 | } 744 | }, 745 | "should-equal": { 746 | "version": "2.0.0", 747 | "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", 748 | "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", 749 | "dev": true, 750 | "requires": { 751 | "should-type": "^1.4.0" 752 | } 753 | }, 754 | "should-format": { 755 | "version": "3.0.3", 756 | "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", 757 | "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", 758 | "dev": true, 759 | "requires": { 760 | "should-type": "^1.3.0", 761 | "should-type-adaptors": "^1.0.1" 762 | } 763 | }, 764 | "should-type": { 765 | "version": "1.4.0", 766 | "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", 767 | "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", 768 | "dev": true 769 | }, 770 | "should-type-adaptors": { 771 | "version": "1.1.0", 772 | "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", 773 | "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", 774 | "dev": true, 775 | "requires": { 776 | "should-type": "^1.3.0", 777 | "should-util": "^1.0.0" 778 | } 779 | }, 780 | "should-util": { 781 | "version": "1.0.1", 782 | "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", 783 | "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", 784 | "dev": true 785 | }, 786 | "sprintf-js": { 787 | "version": "1.0.3", 788 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 789 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 790 | "dev": true 791 | }, 792 | "string-width": { 793 | "version": "2.1.1", 794 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 795 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 796 | "dev": true, 797 | "requires": { 798 | "is-fullwidth-code-point": "^2.0.0", 799 | "strip-ansi": "^4.0.0" 800 | } 801 | }, 802 | "string.prototype.trimend": { 803 | "version": "1.0.1", 804 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", 805 | "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", 806 | "dev": true, 807 | "requires": { 808 | "define-properties": "^1.1.3", 809 | "es-abstract": "^1.17.5" 810 | } 811 | }, 812 | "string.prototype.trimleft": { 813 | "version": "2.1.2", 814 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", 815 | "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", 816 | "dev": true, 817 | "requires": { 818 | "define-properties": "^1.1.3", 819 | "es-abstract": "^1.17.5", 820 | "string.prototype.trimstart": "^1.0.0" 821 | } 822 | }, 823 | "string.prototype.trimright": { 824 | "version": "2.1.2", 825 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", 826 | "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", 827 | "dev": true, 828 | "requires": { 829 | "define-properties": "^1.1.3", 830 | "es-abstract": "^1.17.5", 831 | "string.prototype.trimend": "^1.0.0" 832 | } 833 | }, 834 | "string.prototype.trimstart": { 835 | "version": "1.0.1", 836 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", 837 | "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", 838 | "dev": true, 839 | "requires": { 840 | "define-properties": "^1.1.3", 841 | "es-abstract": "^1.17.5" 842 | } 843 | }, 844 | "strip-ansi": { 845 | "version": "4.0.0", 846 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 847 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 848 | "dev": true, 849 | "requires": { 850 | "ansi-regex": "^3.0.0" 851 | } 852 | }, 853 | "strip-json-comments": { 854 | "version": "2.0.1", 855 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 856 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 857 | "dev": true 858 | }, 859 | "supports-color": { 860 | "version": "6.0.0", 861 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", 862 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", 863 | "dev": true, 864 | "requires": { 865 | "has-flag": "^3.0.0" 866 | } 867 | }, 868 | "to-regex-range": { 869 | "version": "5.0.1", 870 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 871 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 872 | "dev": true, 873 | "requires": { 874 | "is-number": "^7.0.0" 875 | } 876 | }, 877 | "which": { 878 | "version": "1.3.1", 879 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 880 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 881 | "dev": true, 882 | "requires": { 883 | "isexe": "^2.0.0" 884 | } 885 | }, 886 | "which-module": { 887 | "version": "2.0.0", 888 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 889 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 890 | "dev": true 891 | }, 892 | "wide-align": { 893 | "version": "1.1.3", 894 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 895 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 896 | "dev": true, 897 | "requires": { 898 | "string-width": "^1.0.2 || 2" 899 | } 900 | }, 901 | "wrap-ansi": { 902 | "version": "5.1.0", 903 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 904 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 905 | "dev": true, 906 | "requires": { 907 | "ansi-styles": "^3.2.0", 908 | "string-width": "^3.0.0", 909 | "strip-ansi": "^5.0.0" 910 | }, 911 | "dependencies": { 912 | "ansi-regex": { 913 | "version": "4.1.0", 914 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 915 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 916 | "dev": true 917 | }, 918 | "string-width": { 919 | "version": "3.1.0", 920 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 921 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 922 | "dev": true, 923 | "requires": { 924 | "emoji-regex": "^7.0.1", 925 | "is-fullwidth-code-point": "^2.0.0", 926 | "strip-ansi": "^5.1.0" 927 | } 928 | }, 929 | "strip-ansi": { 930 | "version": "5.2.0", 931 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 932 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 933 | "dev": true, 934 | "requires": { 935 | "ansi-regex": "^4.1.0" 936 | } 937 | } 938 | } 939 | }, 940 | "wrappy": { 941 | "version": "1.0.2", 942 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 943 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 944 | "dev": true 945 | }, 946 | "y18n": { 947 | "version": "4.0.0", 948 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 949 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 950 | "dev": true 951 | }, 952 | "yargs": { 953 | "version": "13.3.2", 954 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 955 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 956 | "dev": true, 957 | "requires": { 958 | "cliui": "^5.0.0", 959 | "find-up": "^3.0.0", 960 | "get-caller-file": "^2.0.1", 961 | "require-directory": "^2.1.1", 962 | "require-main-filename": "^2.0.0", 963 | "set-blocking": "^2.0.0", 964 | "string-width": "^3.0.0", 965 | "which-module": "^2.0.0", 966 | "y18n": "^4.0.0", 967 | "yargs-parser": "^13.1.2" 968 | }, 969 | "dependencies": { 970 | "ansi-regex": { 971 | "version": "4.1.0", 972 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 973 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 974 | "dev": true 975 | }, 976 | "string-width": { 977 | "version": "3.1.0", 978 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 979 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 980 | "dev": true, 981 | "requires": { 982 | "emoji-regex": "^7.0.1", 983 | "is-fullwidth-code-point": "^2.0.0", 984 | "strip-ansi": "^5.1.0" 985 | } 986 | }, 987 | "strip-ansi": { 988 | "version": "5.2.0", 989 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 990 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 991 | "dev": true, 992 | "requires": { 993 | "ansi-regex": "^4.1.0" 994 | } 995 | } 996 | } 997 | }, 998 | "yargs-parser": { 999 | "version": "13.1.2", 1000 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 1001 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 1002 | "dev": true, 1003 | "requires": { 1004 | "camelcase": "^5.0.0", 1005 | "decamelize": "^1.2.0" 1006 | } 1007 | }, 1008 | "yargs-unparser": { 1009 | "version": "1.6.0", 1010 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", 1011 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", 1012 | "dev": true, 1013 | "requires": { 1014 | "flat": "^4.1.0", 1015 | "lodash": "^4.17.15", 1016 | "yargs": "^13.3.0" 1017 | } 1018 | } 1019 | } 1020 | } 1021 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dvbtee", 3 | "version": "0.4.5", 4 | "description": "MPEG2 transport stream parser for Node.js with support for television broadcast PSIP tables", 5 | "author": "Michael Ira Krufky ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/mkrufky/node-dvbtee.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/mkrufky/node-dvbtee/issues" 13 | }, 14 | "keywords": [ 15 | "dvb-psi", 16 | "atsc", 17 | "dvb", 18 | "dvbt", 19 | "dvb-t", 20 | "psi", 21 | "psip", 22 | "mpeg2", 23 | "mpegts", 24 | "m2ts", 25 | "ts", 26 | "transport-stream", 27 | "transport", 28 | "stream", 29 | "tv", 30 | "dtv", 31 | "digital", 32 | "television", 33 | "pat", 34 | "pmt", 35 | "sdt", 36 | "vct", 37 | "mgt", 38 | "nit", 39 | "eit", 40 | "ett", 41 | "stt", 42 | "tdt", 43 | "tot", 44 | "epg", 45 | "table", 46 | "tables", 47 | "descriptor", 48 | "descriptors", 49 | "parser" 50 | ], 51 | "main": "./lib/dvbtee.js", 52 | "scripts": { 53 | "install": "node-gyp rebuild -j 8", 54 | "test": "mocha" 55 | }, 56 | "dependencies": { 57 | "async-factory-worker": "^0.0.1", 58 | "libdvbtee_parser": "^0.6.7", 59 | "nan": "^2.14.1" 60 | }, 61 | "optionalDependencies": { 62 | "bindings": "^1.5.0" 63 | }, 64 | "devDependencies": { 65 | "mocha": "^6.2.0", 66 | "should": "^13.2.3" 67 | }, 68 | "gypfile": true 69 | } 70 | -------------------------------------------------------------------------------- /scripts/prepare-publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd "$(dirname "$0")"/.. 4 | 5 | rm -rf _stage 6 | mkdir -p _stage 7 | cd _stage 8 | git clone .. node-dvbtee 9 | cd node-dvbtee 10 | 11 | sed -i s/"^libdvbtee"/""/1 .gitignore 12 | 13 | npm publish 14 | 15 | cd ../.. 16 | -------------------------------------------------------------------------------- /src/async_factory_worker_cpp03.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * node-dvbtee for Node.js 3 | * 4 | * Copyright (c) 2018 Michael Ira Krufky 5 | * 6 | * MIT License 7 | * 8 | * See https://github.com/mkrufky/node-dvbtee for more information 9 | ********************************************************************/ 10 | 11 | #ifndef SRC_ASYNC_FACTORY_WORKER_H_ 12 | #define SRC_ASYNC_FACTORY_WORKER_H_ 13 | 14 | #include 15 | #include 16 | 17 | namespace Nan { 18 | 19 | namespace Mkrufky { 20 | 21 | template 22 | /* abstract */ 23 | class AsyncBareFactoryWorker : public AsyncBareProgressWorkerBase { 24 | public: 25 | explicit AsyncBareFactoryWorker( 26 | Callback *callback_, 27 | const char* resource_name = "nan:mkrufky:dvbtee:AsyncBareFactoryWorker") 28 | : AsyncBareProgressWorkerBase(callback_, resource_name) { 29 | } 30 | 31 | virtual ~AsyncBareFactoryWorker() { 32 | } 33 | 34 | class ExecutionProgress { 35 | friend class AsyncBareFactoryWorker; 36 | public: 37 | void Construct(A a, B b, C c) const { 38 | that_->ConstructProgress_(a, b, c); 39 | } 40 | 41 | private: 42 | explicit ExecutionProgress(AsyncBareFactoryWorker *that) : that_(that) {} 43 | NAN_DISALLOW_ASSIGN_COPY_MOVE(ExecutionProgress) 44 | AsyncBareFactoryWorker* const that_; 45 | }; 46 | 47 | virtual void Execute(const ExecutionProgress& progress) = 0; 48 | virtual void HandleProgressCallback(const T *data, size_t size) = 0; 49 | 50 | private: 51 | void Execute() /*final override*/ { 52 | ExecutionProgress progress(this); 53 | Execute(progress); 54 | } 55 | 56 | virtual void ConstructProgress_(A a, B b, C c) = 0; 57 | }; 58 | 59 | template 60 | /* abstract */ 61 | class AsyncFactoryWorker : public AsyncBareFactoryWorker { 62 | public: 63 | explicit AsyncFactoryWorker( 64 | Callback *callback_, 65 | const char* resource_name = "nan:mkrufky:dvbtee:AsyncFactoryWorker") 66 | : AsyncBareFactoryWorker(callback_, resource_name) { 67 | uv_mutex_init(&async_lock); 68 | } 69 | 70 | virtual ~AsyncFactoryWorker() { 71 | uv_mutex_lock(&async_lock); 72 | 73 | while (!asyncdata_.empty()) { 74 | T *data = asyncdata_.front(); 75 | 76 | asyncdata_.pop(); 77 | 78 | delete data; 79 | } 80 | 81 | uv_mutex_unlock(&async_lock); 82 | uv_mutex_destroy(&async_lock); 83 | } 84 | 85 | void WorkComplete() { 86 | WorkProgress(); 87 | AsyncWorker::WorkComplete(); 88 | } 89 | 90 | void WorkProgress() { 91 | uv_mutex_lock(&async_lock); 92 | 93 | while (!asyncdata_.empty()) { 94 | T *data = asyncdata_.front(); 95 | asyncdata_.pop(); 96 | uv_mutex_unlock(&async_lock); 97 | 98 | // Don't send progress events after we've already completed. 99 | if (this->callback) { 100 | this->HandleProgressCallback(data, 1); 101 | } 102 | 103 | delete data; 104 | 105 | uv_mutex_lock(&async_lock); 106 | } 107 | 108 | uv_mutex_unlock(&async_lock); 109 | } 110 | 111 | private: 112 | void ConstructProgress_(A a, B b, C c) { 113 | T *data = new T(a, b, c); 114 | 115 | uv_mutex_lock(&async_lock); 116 | asyncdata_.push(data); 117 | uv_mutex_unlock(&async_lock); 118 | 119 | uv_async_send(&this->async); 120 | } 121 | 122 | uv_mutex_t async_lock; 123 | std::queue asyncdata_; 124 | }; 125 | 126 | } // namespace Mkrufky 127 | 128 | } // namespace Nan 129 | 130 | #endif // SRC_ASYNC_FACTORY_WORKER_H_ 131 | -------------------------------------------------------------------------------- /src/dvbtee-parser.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * node-dvbtee for Node.js 3 | * 4 | * Copyright (c) 2018 Michael Ira Krufky 5 | * 6 | * MIT License 7 | * 8 | * See https://github.com/mkrufky/node-dvbtee for more information 9 | ********************************************************************/ 10 | 11 | #include 12 | #include "dvbtee-parser.h" // NOLINT(build/include) 13 | #if NAN_HAS_CPLUSPLUS_11 14 | #include // NOLINT(build/include) 15 | #else 16 | #include "async_factory_worker_cpp03.h" // NOLINT(build/include) 17 | #endif 18 | 19 | Nan::Persistent dvbteeParser::constructor; 20 | 21 | dvbteeParser::dvbteeParser() 22 | { 23 | } 24 | 25 | dvbteeParser::~dvbteeParser() 26 | { 27 | } 28 | 29 | void dvbteeParser::Init(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE exports) 30 | { 31 | Nan::HandleScope scope; 32 | 33 | v8::Local tpl = Nan::New(New); 34 | tpl->SetClassName(Nan::New("Parser").ToLocalChecked()); 35 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 36 | 37 | Nan::SetPrototypeMethod(tpl, "reset", reset); 38 | Nan::SetPrototypeMethod(tpl, "feed", feed); 39 | Nan::SetPrototypeMethod(tpl, "enableEttCollection", enableEttCollection); 40 | Nan::SetPrototypeMethod(tpl, "enableParseISO6937", enableParseISO6937); 41 | 42 | v8::Local function = Nan::GetFunction(tpl).ToLocalChecked(); 43 | constructor.Reset(function); 44 | Nan::Set(exports, Nan::New("Parser").ToLocalChecked(), function); 45 | } 46 | 47 | void dvbteeParser::New(const Nan::FunctionCallbackInfo &info) 48 | { 49 | if (info.IsConstructCall()) 50 | { 51 | // Invoked as constructor: `new dvbteeParser(...)` 52 | dvbteeParser *obj = new dvbteeParser(); 53 | obj->Wrap(info.This()); 54 | info.GetReturnValue().Set(info.This()); 55 | } 56 | else 57 | { 58 | // Invoked as plain function `dvbteeParser(...)`, turn into construct call. 59 | const int argc = 0; 60 | v8::Local argv[argc] = {}; 61 | v8::Local cons = Nan::New(constructor); 62 | info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked()); 63 | } 64 | } 65 | 66 | //////////////////////////////////////// 67 | 68 | void dvbteeParser::enableEttCollection( 69 | const Nan::FunctionCallbackInfo &info) 70 | { 71 | dvbteeParser *obj = ObjectWrap::Unwrap(info.Holder()); 72 | 73 | bool enable = Nan::To(info[0]).FromMaybe(true); 74 | 75 | obj->m_parser.enable_ett_collection(enable); 76 | 77 | info.GetReturnValue().Set(info.Holder()); 78 | } 79 | 80 | //////////////////////////////////////// 81 | 82 | void dvbteeParser::enableParseISO6937( 83 | const Nan::FunctionCallbackInfo &info) 84 | { 85 | dvbteeParser *obj = ObjectWrap::Unwrap(info.Holder()); 86 | 87 | bool enable = Nan::To(info[0]).FromMaybe(true); 88 | 89 | obj->m_parser.enable_iso6937_translation(enable); 90 | 91 | info.GetReturnValue().Set(info.Holder()); 92 | } 93 | 94 | //////////////////////////////////////// 95 | 96 | class ResetWorker : public Nan::AsyncWorker 97 | { 98 | public: 99 | ResetWorker(Nan::Callback *callback, 100 | const Nan::FunctionCallbackInfo &info) 101 | : Nan::AsyncWorker(callback) 102 | { 103 | m_obj = Nan::ObjectWrap::Unwrap(info.Holder()); 104 | } 105 | ~ResetWorker() 106 | { 107 | } 108 | 109 | void Execute() 110 | { 111 | m_obj->m_parser.cleanup(); 112 | m_obj->m_parser.reset(); 113 | } 114 | 115 | void HandleOKCallback() 116 | { 117 | Nan::HandleScope scope; 118 | 119 | v8::Local argv[] = { 120 | Nan::Null(), Nan::New(0)}; 121 | 122 | callback->Call(2, argv); 123 | } 124 | 125 | private: 126 | dvbteeParser *m_obj; 127 | }; 128 | 129 | void dvbteeParser::reset(const Nan::FunctionCallbackInfo &info) 130 | { 131 | // If a callback function is supplied, this method will run async 132 | // otherwise, it will run synchronous 133 | 134 | int lastArg = info.Length() - 1; 135 | 136 | if ((lastArg >= 0) && (info[lastArg]->IsFunction())) 137 | { 138 | Nan::Callback *callback = new Nan::Callback( 139 | info[lastArg].As()); 140 | Nan::AsyncQueueWorker(new ResetWorker(callback, info)); 141 | } 142 | else 143 | { 144 | dvbteeParser *obj = ObjectWrap::Unwrap(info.Holder()); 145 | 146 | obj->m_parser.cleanup(); 147 | obj->m_parser.reset(); 148 | 149 | info.GetReturnValue().Set(info.Holder()); 150 | } 151 | } 152 | 153 | //////////////////////////////////////// 154 | 155 | class TableData 156 | { 157 | public: 158 | explicit TableData( 159 | const uint8_t &tableId, 160 | const std::string &decoderName, 161 | const std::string &json) 162 | : tableId(tableId), decoderName(decoderName), json(json) 163 | { 164 | } 165 | 166 | const uint8_t tableId; 167 | const std::string decoderName; 168 | const std::string json; 169 | 170 | private: 171 | NAN_DISALLOW_ASSIGN_COPY(TableData) 172 | #if NAN_HAS_CPLUSPLUS_11 173 | TableData() = delete; 174 | #else 175 | TableData(); 176 | #endif // NAN_HAS_CPLUSPLUS_11 177 | }; 178 | 179 | class FeedWorker : public Nan::Mkrufky::AsyncFactoryWorker 181 | { 182 | public: 183 | FeedWorker(Nan::Callback *callback, 184 | Nan::Callback *progress, 185 | const Nan::FunctionCallbackInfo &info, 186 | const char *resource_name = "dvbtee:FeedWorker") 187 | : AsyncFactoryWorker(callback, resource_name), m_progress(progress), m_buf(NULL), m_buf_len(0), m_ret(-1) 188 | { 189 | m_obj = Nan::ObjectWrap::Unwrap(info.Holder()); 190 | 191 | if ((info[0]->IsObject()) && (info[1]->IsNumber())) 192 | { 193 | const char *key = "buf"; 194 | SaveToPersistent(key, info[0]); 195 | Nan::MaybeLocal mbBuf = 196 | Nan::To(GetFromPersistent(key)); 197 | 198 | if (!mbBuf.IsEmpty()) 199 | { 200 | m_buf = node::Buffer::Data(mbBuf.ToLocalChecked()); 201 | m_buf_len = Nan::To(info[1]).FromJust(); 202 | } 203 | } 204 | } 205 | 206 | ~FeedWorker() 207 | { 208 | delete m_progress; 209 | } 210 | 211 | void Execute(const AsyncFactoryWorker::ExecutionProgress &progress) 212 | { 213 | if ((m_buf) && (m_buf_len)) 214 | { 215 | Watcher watch(this->m_obj, progress); 216 | 217 | m_ret = m_obj->m_parser.feed( 218 | m_buf_len, reinterpret_cast(m_buf)); 219 | } 220 | if (m_ret < 0) 221 | { 222 | SetErrorMessage("invalid buffer / length"); 223 | } 224 | } 225 | 226 | void HandleProgressCallback(const TableData *async_data, size_t count) 227 | { 228 | Nan::HandleScope scope; 229 | 230 | if (!m_progress->IsEmpty()) 231 | { 232 | for (unsigned int i = 0; i < count; i++) 233 | { 234 | const TableData *data = &async_data[i]; 235 | 236 | Nan::MaybeLocal jsonStr = Nan::New(data->json); 237 | if (!jsonStr.IsEmpty()) 238 | { 239 | Nan::MaybeLocal jsonVal = 240 | m_obj->NanJSON.Parse(jsonStr.ToLocalChecked()); 241 | 242 | if (!jsonVal.IsEmpty()) 243 | { 244 | Nan::MaybeLocal decoderName = 245 | Nan::New(data->decoderName); 246 | 247 | v8::Local decoderNameArg; 248 | if (decoderName.IsEmpty()) 249 | decoderNameArg = Nan::Null(); 250 | else 251 | decoderNameArg = decoderName.ToLocalChecked(); 252 | 253 | v8::Local argv[] = { 254 | Nan::New(data->tableId), 255 | decoderNameArg, 256 | jsonVal.ToLocalChecked()}; 257 | 258 | m_progress->Call(3, argv); 259 | } 260 | } 261 | } 262 | } 263 | } 264 | 265 | void HandleOKCallback() 266 | { 267 | Nan::HandleScope scope; 268 | 269 | v8::Local argv[] = { 270 | Nan::Null(), Nan::New(m_ret)}; 271 | 272 | callback->Call(2, argv); 273 | } 274 | 275 | private: 276 | Nan::Callback *m_progress; 277 | dvbteeParser *m_obj; 278 | char *m_buf; 279 | unsigned int m_buf_len; 280 | int m_ret; 281 | 282 | class Watcher : public dvbtee::decode::TableWatcher 283 | { 284 | public: 285 | explicit Watcher(dvbteeParser *obj, 286 | const AsyncFactoryWorker::ExecutionProgress &progress) 287 | : m_obj(obj), m_progress(progress) 288 | { 289 | m_obj->m_parser.subscribeTables(this); 290 | } 291 | 292 | ~Watcher() 293 | { 294 | m_obj->m_parser.subscribeTables(NULL); 295 | } 296 | 297 | void updateTable(uint8_t tId, dvbtee::decode::Table *table) 298 | { 299 | m_progress.Construct( 300 | table->getTableid(), 301 | table->getDecoderName(), 302 | table->toJson()); 303 | } 304 | 305 | private: 306 | dvbteeParser *m_obj; 307 | const AsyncFactoryWorker::ExecutionProgress &m_progress; 308 | }; 309 | }; 310 | 311 | void dvbteeParser::feed(const Nan::FunctionCallbackInfo &info) 312 | { 313 | int lastArg = info.Length() - 1; 314 | 315 | if ((lastArg >= 1) && (info[lastArg]->IsFunction()) && 316 | (info[lastArg - 1]->IsFunction())) 317 | { 318 | Nan::Callback *progress = new Nan::Callback( 319 | info[lastArg - 1].As()); 320 | Nan::Callback *callback = new Nan::Callback( 321 | info[lastArg].As()); 322 | Nan::AsyncQueueWorker(new FeedWorker(callback, progress, info)); 323 | } 324 | else 325 | { 326 | info.GetReturnValue().Set(Nan::New(-1)); 327 | } 328 | } 329 | -------------------------------------------------------------------------------- /src/dvbtee-parser.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * node-dvbtee for Node.js 3 | * 4 | * Copyright (c) 2018 Michael Ira Krufky 5 | * 6 | * MIT License 7 | * 8 | * See https://github.com/mkrufky/node-dvbtee for more information 9 | ********************************************************************/ 10 | 11 | #ifndef SRC_DVBTEE_PARSER_H_ 12 | #define SRC_DVBTEE_PARSER_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "parse.h" // NOLINT(build/include) 19 | 20 | class dvbteeParser : public Nan::ObjectWrap 21 | { 22 | public: 23 | static void Init(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE exports); 24 | 25 | private: 26 | dvbteeParser(); 27 | virtual ~dvbteeParser(); 28 | 29 | static void New(const Nan::FunctionCallbackInfo &info); 30 | 31 | static void reset(const Nan::FunctionCallbackInfo &info); 32 | static void feed(const Nan::FunctionCallbackInfo &info); 33 | static void enableEttCollection(const Nan::FunctionCallbackInfo &info); 34 | static void enableParseISO6937(const Nan::FunctionCallbackInfo &info); 35 | 36 | static Nan::Persistent constructor; 37 | Nan::JSON NanJSON; 38 | PrivateParse m_parser; 39 | 40 | friend class FeedWorker; 41 | friend class ResetWorker; 42 | }; 43 | 44 | #endif // SRC_DVBTEE_PARSER_H_ 45 | -------------------------------------------------------------------------------- /src/node-dvbtee.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * node-dvbtee for Node.js 3 | * 4 | * Copyright (c) 2018 Michael Ira Krufky 5 | * 6 | * MIT License 7 | * 8 | * See https://github.com/mkrufky/node-dvbtee for more information 9 | ********************************************************************/ 10 | 11 | #include 12 | #include "dvbtee-parser.h" // NOLINT(build/include) 13 | 14 | void libVersion(const Nan::FunctionCallbackInfo &info) 15 | { 16 | v8::Local version = Nan::New(); 17 | 18 | Nan::Set(version, 0, Nan::New(LIBDVBTEE_VERSION_A)); 19 | Nan::Set(version, 1, Nan::New(LIBDVBTEE_VERSION_B)); 20 | Nan::Set(version, 2, Nan::New(LIBDVBTEE_VERSION_C)); 21 | 22 | info.GetReturnValue().Set(version); 23 | } 24 | 25 | void logLevel(const Nan::FunctionCallbackInfo &info) 26 | { 27 | libdvbtee_set_debug_level( 28 | (info[0]->IsNumber()) ? Nan::To(info[0]).FromJust() : 255, 29 | (info[1]->IsNumber()) ? Nan::To(info[1]).FromJust() : 0); 30 | 31 | info.GetReturnValue().Set(info.Holder()); 32 | } 33 | 34 | template 35 | v8::Local vectorToV8Array(std::vector v) 36 | { 37 | v8::Local a = Nan::New(); 38 | unsigned int pos = 0; 39 | 40 | for (typename std::vector::const_iterator it = v.begin(); 41 | it != v.end(); ++it) 42 | 43 | Nan::Set(a, pos++, Nan::New(*it)); 44 | 45 | return a; 46 | } 47 | 48 | void getTableDecoderIds(const Nan::FunctionCallbackInfo &info) 49 | { 50 | info.GetReturnValue().Set( 51 | vectorToV8Array(dvbtee::decode::TableRegistry::instance().list())); 52 | } 53 | 54 | void getDescriptorDecoderIds(const Nan::FunctionCallbackInfo &info) 55 | { 56 | info.GetReturnValue().Set( 57 | vectorToV8Array(dvbtee::decode::DescriptorRegistry::instance().list())); 58 | } 59 | 60 | NAN_MODULE_INIT(InitAll) 61 | { 62 | Nan::Set(target, 63 | Nan::New("logLevel").ToLocalChecked(), 64 | Nan::GetFunction( 65 | Nan::New(logLevel)) 66 | .ToLocalChecked()); 67 | 68 | Nan::Set(target, 69 | Nan::New("libVersion").ToLocalChecked(), 70 | Nan::GetFunction( 71 | Nan::New(libVersion)) 72 | .ToLocalChecked()); 73 | 74 | Nan::Set(target, 75 | Nan::New("getTableDecoderIds").ToLocalChecked(), 76 | Nan::GetFunction( 77 | Nan::New(getTableDecoderIds)) 78 | .ToLocalChecked()); 79 | 80 | Nan::Set(target, 81 | Nan::New("getDescriptorDecoderIds").ToLocalChecked(), 82 | Nan::GetFunction( 83 | Nan::New(getDescriptorDecoderIds)) 84 | .ToLocalChecked()); 85 | 86 | dvbteeParser::Init(target); 87 | } 88 | 89 | NODE_MODULE(dvbtee, InitAll) 90 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert') 2 | var should = require('should') 3 | var dvbtee = require('../') 4 | 5 | describe('node-dvbtee', function() { 6 | 7 | describe('require(\'dvbtee\')', function() { 8 | 9 | it('should return a function when called without operator new', function() { 10 | assert.equal("function", typeof require('../')) 11 | }) 12 | 13 | it('should return a function when called as a function with operator new', function() { 14 | assert.equal("function", typeof new require('../')) 15 | }) 16 | }) 17 | 18 | describe('#libVersion()', function() { 19 | 20 | var version = dvbtee.libVersion() 21 | 22 | it('should return an Array of 3 Numbers to represent libdvbtee library version in the form [ MAJOR, MINOR, PATCH ]', function() { 23 | assert.equal(3, version.length) 24 | 25 | version.forEach(function (x) { 26 | assert.equal("number", typeof x) 27 | }) 28 | }) 29 | }) 30 | 31 | describe('#logLevel()', function() { 32 | 33 | it('should return the dvbtee object (for method chaining)', function() { 34 | assert.equal(dvbtee, dvbtee.logLevel(0,0)) 35 | }) 36 | }) 37 | 38 | describe('#getTableDecoderIds()', function() { 39 | 40 | var tableIds = dvbtee.getTableDecoderIds() 41 | 42 | it('should return an Array of Numbers that indicate the Table IDs supported by the built-in PSIP table decoders', function() { 43 | tableIds.forEach(function (x) { 44 | assert.equal("number", typeof x) 45 | }) 46 | }) 47 | 48 | it('should include 11 PSIP table decoders', function() { 49 | assert.equal(11, tableIds.length) 50 | }) 51 | 52 | it('should support decoding PAT tables', function() { 53 | tableIds.should.containEql(0x00) 54 | }) 55 | 56 | it('should support decoding PMT tables', function() { 57 | tableIds.should.containEql(0x02) 58 | }) 59 | 60 | it('should support decoding NIT tables', function() { 61 | tableIds.should.containEql(0x40) 62 | }) 63 | 64 | it('should support decoding SDT tables', function() { 65 | tableIds.should.containEql(0x42) 66 | }) 67 | 68 | it('should support decoding EIT (dvb) tables', function() { 69 | tableIds.should.containEql(0x4e) 70 | }) 71 | 72 | it('should support decoding TDT/TOT tables', function() { 73 | tableIds.should.containEql(0x70) 74 | }) 75 | 76 | it('should support decoding MGT tables', function() { 77 | tableIds.should.containEql(0xc7) 78 | }) 79 | 80 | it('should support decoding VCT tables', function() { 81 | tableIds.should.containEql(0xc8) 82 | }) 83 | 84 | it('should support decoding EIT (atsc) tables', function() { 85 | tableIds.should.containEql(0xcb) 86 | }) 87 | 88 | it('should support decoding ETT tables', function() { 89 | tableIds.should.containEql(0xcc) 90 | }) 91 | 92 | it('should support decoding STT tables', function() { 93 | tableIds.should.containEql(0xcd) 94 | }) 95 | }) 96 | 97 | describe('#getDescriptorDecoderIds()', function() { 98 | 99 | var descIds = dvbtee.getDescriptorDecoderIds() 100 | 101 | it('should return an Array of Numbers that indicate the Descriptor IDs supported by the built-in PSIP descriptor decoders', function() { 102 | descIds.forEach(function (x) { 103 | assert.equal("number", typeof x) 104 | }) 105 | }) 106 | 107 | it('should include 10 PSIP descriptor decoders', function() { 108 | assert.equal(10, descIds.length) 109 | }) 110 | 111 | it('should support decoding ISO639 language descriptors', function() { 112 | descIds.should.containEql(0x0a) 113 | }) 114 | 115 | it('should support decoding service descriptors', function() { 116 | descIds.should.containEql(0x48) 117 | }) 118 | 119 | it('should support decoding short event descriptors', function() { 120 | descIds.should.containEql(0x4d) 121 | }) 122 | 123 | it('should support decoding extended event descriptors', function() { 124 | descIds.should.containEql(0x4e) 125 | }) 126 | 127 | it('should support decoding frequency list descriptors', function() { 128 | descIds.should.containEql(0x62) 129 | }) 130 | 131 | it('should support decoding AC-3 audio descriptors', function() { 132 | descIds.should.containEql(0x81) 133 | }) 134 | 135 | it('should support decoding logical channel number descriptors', function() { 136 | descIds.should.containEql(0x83) 137 | }) 138 | 139 | it('should support decoding caption service descriptors', function() { 140 | descIds.should.containEql(0x86) 141 | }) 142 | 143 | it('should support decoding extended channel name descriptors', function() { 144 | descIds.should.containEql(0xa0) 145 | }) 146 | 147 | it('should support decoding service location descriptors', function() { 148 | descIds.should.containEql(0xa1) 149 | }) 150 | }) 151 | }) 152 | 153 | describe('dvbtee-parser', function() { 154 | 155 | describe('#New', function() { 156 | 157 | it('should return an object when called without operator new', function() { 158 | assert.equal("object", typeof dvbtee.Parser()) 159 | }) 160 | 161 | it('should return an object when called with operator new', function() { 162 | assert.equal("object", typeof new dvbtee.Parser()) 163 | }) 164 | 165 | it('correctly applies constructor option, \'passThru\' when set to true', function() { 166 | assert.equal(true, (new dvbtee.Parser({'passThru': true})).options.passThru ) 167 | }) 168 | 169 | it('correctly applies constructor option, \'passThru\' when set to false', function() { 170 | assert.equal(false, (new dvbtee.Parser({'passThru': false})).options.passThru ) 171 | }) 172 | 173 | it('correctly applies constructor option, \'passThru\' default setting to false when constructor options are omitted', function() { 174 | assert.equal(false, (new dvbtee.Parser).options.passThru ) 175 | }) 176 | }) 177 | 178 | /* 179 | describe('#listenTables()', function() { 180 | 181 | var parser = new dvbtee.Parser() 182 | 183 | it('should return the parser object (for method chaining)', function() { 184 | assert.equal(parser, parser.listenTables()) 185 | }) 186 | }) 187 | */ 188 | 189 | describe('#reset()', function() { 190 | 191 | /* 192 | it('should return the parser object when called synchronously (without args) (for method chaining)', function() { 193 | var parser = new dvbtee.Parser() 194 | 195 | assert.equal(parser, parser.reset()) 196 | }) 197 | */ 198 | 199 | /* 200 | it('should return undefined when called asynchronously (with a callback function as the last argument)', function() { 201 | var parser = new dvbtee.Parser() 202 | 203 | assert.equal(undefined, parser.reset(function () { })) 204 | }) 205 | */ 206 | }) 207 | 208 | describe('#feed()', function() { 209 | 210 | it('should return an error when called without args', function() { 211 | var parser = new dvbtee.Parser() 212 | 213 | assert.equal(-1, parser.feed()) 214 | }) 215 | 216 | /* 217 | it('should return undefined when called asynchronously (with a callback function as the last argument)', function() { 218 | var parser = new dvbtee.Parser() 219 | 220 | assert.equal(undefined, parser.feed(function () { })) 221 | }) 222 | */ 223 | }) 224 | }) 225 | --------------------------------------------------------------------------------