200 lines
9.8 KiB
HTML
200 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>json-stream.js</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="../docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul id="jump_to">
|
||
<li>
|
||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||
<a class="small" href="javascript:void(0);">+</a>
|
||
<div id="jump_wrapper">
|
||
<div id="jump_page_wrapper">
|
||
<div id="jump_page">
|
||
|
||
|
||
<a class="source" href="consumer.html">
|
||
./src/consumer.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="index.html">
|
||
./src/index.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="json-stream.html">
|
||
./src/json-stream.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="socket.html">
|
||
./src/socket.js
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>json-stream.js</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-1">¶</a>
|
||
</div>
|
||
<p>adpated from <a href="https://github.com/sebastianseilund/node-json-socket">https://github.com/sebastianseilund/node-json-socket</a></p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>
|
||
<span class="hljs-keyword">import</span> {StringDecoder} <span class="hljs-keyword">from</span> <span class="hljs-string">'string_decoder'</span>
|
||
<span class="hljs-keyword">import</span> EventEmitter <span class="hljs-keyword">from</span> <span class="hljs-string">'events'</span>
|
||
<span class="hljs-keyword">import</span> btc <span class="hljs-keyword">from</span> <span class="hljs-string">'better-try-catch'</span>
|
||
|
||
<span class="hljs-keyword">const</span> decoder = <span class="hljs-keyword">new</span> StringDecoder()
|
||
|
||
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JsonStream</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">EventEmitter</span></span>{
|
||
<span class="hljs-keyword">constructor</span>(opts={}){
|
||
<span class="hljs-keyword">super</span>()
|
||
<span class="hljs-keyword">this</span>._contentLength = <span class="hljs-literal">null</span>
|
||
<span class="hljs-keyword">this</span>._buffer = <span class="hljs-string">''</span>
|
||
<span class="hljs-keyword">this</span>._delimeter = opts.delimiter || <span class="hljs-string">'#'</span>
|
||
<span class="hljs-keyword">this</span>.onData = <span class="hljs-keyword">this</span>.onData.bind(<span class="hljs-keyword">this</span>)
|
||
<span class="hljs-keyword">this</span>.serialize = <span class="hljs-keyword">this</span>.serialize.bind(<span class="hljs-keyword">this</span>)
|
||
}
|
||
|
||
|
||
onData (data) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-2">¶</a>
|
||
</div>
|
||
<p>console.log(‘a chunk arrived’, data)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> data = decoder.write(data)
|
||
<span class="hljs-keyword">try</span> {
|
||
<span class="hljs-keyword">this</span>._handleData(data)
|
||
} <span class="hljs-keyword">catch</span> (e) {
|
||
<span class="hljs-keyword">this</span>.emit(<span class="hljs-string">'error'</span>, { <span class="hljs-attr">error</span>: e })
|
||
}
|
||
}
|
||
|
||
<span class="hljs-keyword">async</span> serialize(message) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>( <span class="hljs-function">(<span class="hljs-params">resolve,reject</span>) =></span> {
|
||
<span class="hljs-keyword">let</span> [err,messageData] = btc(<span class="hljs-built_in">JSON</span>.stringify)(message)
|
||
<span class="hljs-keyword">if</span> (err) reject(err)
|
||
<span class="hljs-keyword">let</span> [err2,length] = btc(Buffer.byteLength)(messageData, <span class="hljs-string">'utf8'</span>)
|
||
<span class="hljs-keyword">if</span> (err2) reject(err2)
|
||
<span class="hljs-keyword">let</span> data = length + <span class="hljs-keyword">this</span>._delimeter + messageData</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-3">¶</a>
|
||
</div>
|
||
<p>console.log(‘serialized’,data)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> resolve(data)
|
||
})
|
||
}
|
||
|
||
_handleData (data) {
|
||
<span class="hljs-keyword">this</span>._buffer += data
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._contentLength == <span class="hljs-literal">null</span>) {
|
||
<span class="hljs-keyword">var</span> i = <span class="hljs-keyword">this</span>._buffer.indexOf(<span class="hljs-keyword">this</span>._delimeter)</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-4">¶</a>
|
||
</div>
|
||
<p>Check if the buffer has a this._opts.delimeter or “#”, if not, the end of the buffer string might be in the middle of a content length string</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (i !== <span class="hljs-number">-1</span>) {
|
||
<span class="hljs-keyword">var</span> rawContentLength = <span class="hljs-keyword">this</span>._buffer.substring(<span class="hljs-number">0</span>, i)
|
||
<span class="hljs-keyword">this</span>._contentLength = <span class="hljs-built_in">parseInt</span>(rawContentLength)
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(<span class="hljs-keyword">this</span>._contentLength)) {
|
||
<span class="hljs-keyword">this</span>._contentLength = <span class="hljs-literal">null</span>
|
||
<span class="hljs-keyword">this</span>._buffer = <span class="hljs-string">''</span>
|
||
<span class="hljs-keyword">var</span> err = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Invalid content length supplied ('</span>+rawContentLength+<span class="hljs-string">') in: '</span>+<span class="hljs-keyword">this</span>._buffer)
|
||
err.code = <span class="hljs-string">'E_INVALID_CONTENT_LENGTH'</span>
|
||
<span class="hljs-keyword">throw</span> err
|
||
}
|
||
<span class="hljs-keyword">this</span>._buffer = <span class="hljs-keyword">this</span>._buffer.substring(i+<span class="hljs-number">1</span>)
|
||
}
|
||
}
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._contentLength != <span class="hljs-literal">null</span>) {
|
||
<span class="hljs-keyword">var</span> length = Buffer.byteLength(<span class="hljs-keyword">this</span>._buffer, <span class="hljs-string">'utf8'</span>)
|
||
<span class="hljs-keyword">if</span> (length == <span class="hljs-keyword">this</span>._contentLength) {
|
||
<span class="hljs-keyword">this</span>._handleMessage(<span class="hljs-keyword">this</span>._buffer)
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (length > <span class="hljs-keyword">this</span>._contentLength) {
|
||
<span class="hljs-keyword">var</span> message = <span class="hljs-keyword">this</span>._buffer.substring(<span class="hljs-number">0</span>, <span class="hljs-keyword">this</span>._contentLength)
|
||
<span class="hljs-keyword">var</span> rest = <span class="hljs-keyword">this</span>._buffer.substring(<span class="hljs-keyword">this</span>._contentLength)
|
||
<span class="hljs-keyword">this</span>._handleMessage(message)
|
||
<span class="hljs-keyword">this</span>.onData(rest)
|
||
}
|
||
}
|
||
}
|
||
|
||
_handleMessage (data) {
|
||
<span class="hljs-keyword">this</span>._contentLength = <span class="hljs-literal">null</span>
|
||
<span class="hljs-keyword">this</span>._buffer = <span class="hljs-string">''</span>
|
||
<span class="hljs-keyword">var</span> message
|
||
<span class="hljs-keyword">try</span> {
|
||
message = <span class="hljs-built_in">JSON</span>.parse(data)
|
||
} <span class="hljs-keyword">catch</span> (e) {
|
||
<span class="hljs-keyword">var</span> err = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Could not parse JSON: '</span>+e.message+<span class="hljs-string">'\nRequest data: '</span>+data)
|
||
err.code = <span class="hljs-string">'E_INVALID_JSON'</span>
|
||
<span class="hljs-keyword">throw</span> err
|
||
}
|
||
message = message || {}
|
||
<span class="hljs-keyword">this</span>.emit(<span class="hljs-string">'message'</span>, message)
|
||
}
|
||
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|