git ssb

3+

cel / ssb-npm-registry



Tree: d2f2697f296dd39aed6a8b63c6d04a736a7db5b3

Files: d2f2697f296dd39aed6a8b63c6d04a736a7db5b3 / node_modules / pull-file / index.js

3715 bytesRaw
1
2/* jshint node: true */
3'use strict';
4
5var fs = require('fs');
6var Decoder = require('pull-utf8-decoder')
7/**
8 # pull-file
9
10 This is a simple module which uses raw file reading methods available in
11 the node `fs` module to read files on-demand. It's a work in progress
12 and feedback is welcome :)
13
14 ## Example Usage
15
16 <<< examples/ipsum-chunks.js
17
18**/
19module.exports = function(filename, opts) {
20 var mode = opts && opts.mode || 0x1B6; // 0666
21 var bufferSize = opts && (opts.bufferSize || (opts.buffer && opts.buffer.length)) || 1024*64;
22 var start = opts && opts.start || 0
23 var end = opts && opts.end || Number.MAX_SAFE_INTEGER
24 var fd = opts && opts.fd
25
26 var ended, closeNext, busy;
27 var _buffer = opts && opts.buffer || new Buffer(bufferSize)
28 var live = opts && !!opts.live
29 var liveCb, closeCb
30 var watcher
31 if(live) {
32 watcher = fs.watch(filename, {
33 persistent: opts.persistent !== false,
34 },
35 function (event) {
36 if(liveCb && event === 'change') {
37 var cb = liveCb
38 liveCb = null
39 closeNext = false
40 readNext(cb)
41 }
42 })
43
44 }
45
46 var flags = opts && opts.flags || 'r'
47
48 function readNext(cb) {
49 if(closeNext) {
50 if(!live) close(cb);
51 else liveCb = cb;
52 return
53 }
54 var toRead = Math.min(end - start, bufferSize);
55 busy = true;
56
57 fs.read(
58 fd,
59 _buffer,
60 0,
61 toRead,
62 start,
63 function(err, count, buffer) {
64 busy = false;
65 start += count;
66 // if we have received an end noticiation, just discard this data
67 if(closeNext && !live) {
68 close(closeCb);
69 return cb(closeNext);
70 }
71
72 if (ended) {
73 return cb(err || ended);
74 }
75
76 // if we encountered a read error pass it on
77 if (err) {
78 return cb(err);
79 }
80
81 if(count === buffer.length) {
82 cb(null, buffer);
83 } else if(count === 0 && live) {
84 liveCb = cb; closeNext = true
85 } else {
86 closeNext = true;
87 cb(null, buffer.slice(0, count));
88 }
89 }
90 );
91 _buffer = opts && opts.buffer || new Buffer(Math.min(end - start, bufferSize))
92 }
93
94 function open(cb) {
95 busy = true;
96 fs.open(filename, flags, mode, function(err, descriptor) {
97 // save the file descriptor
98 fd = descriptor;
99
100 busy = false
101 if(closeNext) {
102 close(closeCb);
103 return cb(closeNext);
104 }
105
106 if (err) {
107 return cb(err);
108 }
109
110 // read the next bytes
111 return readNext(cb);
112 });
113 }
114
115 function close (cb) {
116 if(!cb) throw new Error('close must have cb')
117 if(watcher) watcher.close()
118 //if auto close is disabled, then user manages fd.
119 if(opts && opts.autoClose === false) return cb(true)
120
121 //wait until we have got out of bed, then go back to bed.
122 //or if we are reading, wait till we read, then go back to bed.
123 else if(busy) {
124 closeCb = cb
125 return closeNext = true
126 }
127
128 //first read was close, don't even get out of bed.
129 else if(!fd) {
130 return cb(true)
131 }
132
133 //go back to bed
134 else {
135 fs.close(fd, function(err) {
136 fd = null;
137 cb(err || true);
138 });
139 }
140 }
141
142 function source (end, cb) {
143 if (end) {
144 ended = end;
145 live = false;
146 if(liveCb) {
147 liveCb(end || true);
148 }
149 close(cb);
150 }
151 // if we have already received the end notification, abort further
152 else if (ended) {
153 cb(ended);
154 }
155
156 else if (! fd) {
157 open(cb);
158 }
159
160 else
161 readNext(cb);
162 };
163
164 //read directly to text
165 if(opts && opts.encoding)
166 return Decoder(opts.encoding)(source)
167
168 return source
169
170};
171

Built with git-ssb-web