Skip to content

Commit d9fa24f

Browse files
committed
Merge pull request #10 from dysinger/add-sync-open-read-write-close
Add file descriptor features (open, read, next, write, append, flush, close)
2 parents 152ac43 + 42c1767 commit d9fa24f

File tree

2 files changed

+178
-1
lines changed

2 files changed

+178
-1
lines changed

examples/Test.purs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import Control.Monad.Eff.Exception
88
import Data.Either
99
import Debug.Trace
1010
import Node.Encoding
11+
import Node.Buffer
12+
import Node.Path
13+
import Data.Maybe
1114

1215
main = do
1316

@@ -90,3 +93,14 @@ main = do
9093
trace $ show $ accessedTime x'
9194
trace "statusChangedTime:"
9295
trace $ show $ statusChangedTime x'
96+
97+
let fdFile = join ["tmp", "FD.json"]
98+
fd0 <- S.fdOpen fdFile S.W (Just 420)
99+
let buf0 = fromString "[ 42 ]" UTF8
100+
bytes0 <- S.fdAppend fd0 buf0
101+
S.fdFlush fd0
102+
S.fdClose fd0
103+
fd1 <- S.fdOpen fdFile S.R Nothing
104+
let buf1 = create (size buf0)
105+
bytes1 <- S.fdNext fd1 buf1
106+
S.fdClose fd1

src/Node/FS/Sync.purs

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,46 @@ module Node.FS.Sync
2222
, appendFile
2323
, appendTextFile
2424
, exists
25+
, FileDescriptor(..)
26+
, FileFlags(..)
27+
, BufferLength(..)
28+
, BufferOffset(..)
29+
, ByteCount(..)
30+
, FileMode(..)
31+
, FilePosition(..)
32+
, fdOpen
33+
, fdRead
34+
, fdNext
35+
, fdWrite
36+
, fdAppend
37+
, fdFlush
38+
, fdClose
2539
) where
2640

2741
import Control.Monad.Eff
2842
import Control.Monad.Eff.Exception
2943
import Data.Date
3044
import Data.Either
3145
import Data.Function
32-
import Node.Buffer (Buffer(..))
46+
import Data.Maybe (Maybe(..))
47+
import Node.Buffer (Buffer(..), size)
3348
import Node.Encoding
3449
import Node.FS
3550
import Node.FS.Stats
3651
import Node.Path (FilePath())
3752

53+
foreign import data FileDescriptor :: *
54+
55+
data FileFlags = R | R_PLUS | RS | RS_PLUS
56+
| W | WX | W_PLUS | WX_PLUS
57+
| A | AX | A_PLUS | AX_PLUS
58+
59+
type BufferLength = Number
60+
type BufferOffset = Number
61+
type ByteCount = Number
62+
type FileMode = Number
63+
type FilePosition = Number
64+
3865
foreign import fs "var fs = require('fs');" ::
3966
{ renameSync :: Fn2 FilePath FilePath Unit
4067
, truncateSync :: Fn2 FilePath Number Unit
@@ -54,7 +81,39 @@ foreign import fs "var fs = require('fs');" ::
5481
, writeFileSync :: forall a opts. Fn3 FilePath a { | opts } Unit
5582
, appendFileSync :: forall a opts. Fn3 FilePath a { | opts } Unit
5683
, existsSync :: FilePath -> Boolean
84+
, openSync :: Fn2 FilePath String FileDescriptor
85+
, readSync :: Fn5 FileDescriptor Buffer BufferOffset BufferLength FilePosition ByteCount
86+
, writeSync :: Fn5 FileDescriptor Buffer BufferOffset BufferLength FilePosition ByteCount
87+
, fsyncSync :: Fn1 FileDescriptor Unit
88+
, closeSync :: Fn1 FileDescriptor Unit
89+
}
90+
91+
foreign import createSync
92+
"""
93+
var fs = require('fs');
94+
function createSync(file, flags, mode) {
95+
return fs.openSync(file, flags, mode);
96+
}
97+
"""
98+
:: Fn3 FilePath String FileMode FileDescriptor
99+
100+
foreign import writeSeqSync
101+
"""
102+
var fs = require('fs');
103+
function writeSeqSync(fd, buffer, offset, len) {
104+
return fs.writeSync(fd, buffer, offset, len);
57105
}
106+
"""
107+
:: Fn4 FileDescriptor Buffer BufferOffset BufferLength ByteCount
108+
109+
foreign import readSeqSync
110+
"""
111+
var fs = require('fs');
112+
function readSeqSync(fd, buffer, offset, len) {
113+
return fs.readSync(fd, buffer, offset, len);
114+
}
115+
"""
116+
:: Fn4 FileDescriptor Buffer BufferOffset BufferLength ByteCount
58117

59118
foreign import mkEff
60119
"function mkEff(action) {\
@@ -287,3 +346,107 @@ appendTextFile encoding file buff = mkEff $ \_ -> runFn3
287346
exists :: forall eff. FilePath
288347
-> Eff (fs :: FS | eff) Boolean
289348
exists file = mkEff $ \_ -> fs.existsSync file
349+
350+
{- Synchronous File Descriptor Functions -}
351+
352+
--|
353+
-- Open a file synchronously. See <a
354+
-- href="http://nodejs.org/api/fs.html#fs_fs_opensync_path_flags_mode">Node
355+
-- Documentation</a> for details.
356+
--
357+
fdOpen :: forall opts eff.
358+
FilePath
359+
-> FileFlags
360+
-> Maybe FileMode
361+
-> Eff (err :: Exception, fs :: FS | eff) FileDescriptor
362+
fdOpen file flags mode =
363+
case mode of
364+
Nothing -> mkEff $ \_ -> runFn2 fs.openSync file (toStr flags)
365+
(Just m) -> mkEff $ \_ -> runFn3 createSync file (toStr flags) m
366+
where
367+
toStr R = "r"
368+
toStr R_PLUS = "r+"
369+
toStr RS = "rs"
370+
toStr RS_PLUS = "rs+"
371+
toStr W = "w"
372+
toStr WX = "wx"
373+
toStr W_PLUS = "w+"
374+
toStr WX_PLUS = "wx+"
375+
toStr A = "a"
376+
toStr AX = "ax"
377+
toStr A_PLUS = "a+"
378+
toStr AX_PLUS = "ax+"
379+
380+
--|
381+
-- Read to a file synchronously. See <a
382+
-- href="http://nodejs.org/api/fs.html#fs_fs_readsync_fd_buffer_offset_length_position">Node
383+
-- ocumentation</a> for details.
384+
--
385+
fdRead :: forall eff.
386+
FileDescriptor
387+
-> Buffer
388+
-> BufferOffset
389+
-> BufferLength
390+
-> Maybe FilePosition
391+
-> Eff (err :: Exception, fs :: FS | eff) ByteCount
392+
fdRead fd buff off len Nothing =
393+
mkEff $ \_ -> runFn4 readSeqSync fd buff off len
394+
fdRead fd buff off len (Just pos) =
395+
mkEff $ \_ -> runFn5 fs.readSync fd buff off len pos
396+
397+
--|
398+
-- Convienence function to fill the whole buffer from the current
399+
-- file position.
400+
--
401+
fdNext :: forall eff.
402+
FileDescriptor
403+
-> Buffer
404+
-> Eff (err :: Exception, fs :: FS | eff) ByteCount
405+
fdNext fd buff = fdRead fd buff 0 (size buff) Nothing
406+
407+
--|
408+
-- Write to a file synchronously. See <a
409+
-- href="http://nodejs.org/api/fs.html#fs_fs_writesync_fd_buffer_offset_length_position">Node
410+
-- Documentation</a> for details.
411+
--
412+
fdWrite :: forall eff.
413+
FileDescriptor
414+
-> Buffer
415+
-> BufferOffset
416+
-> BufferLength
417+
-> Maybe FilePosition
418+
-> Eff (err :: Exception, fs :: FS | eff) ByteCount
419+
fdWrite fd buff off len Nothing =
420+
mkEff $ \_ -> runFn4 writeSeqSync fd buff off len
421+
fdWrite fd buff off len (Just pos) =
422+
mkEff $ \_ -> runFn5 fs.writeSync fd buff off len pos
423+
424+
--|
425+
-- Convienence function to append the whole buffer to the current
426+
-- file position.
427+
--
428+
fdAppend :: forall eff.
429+
FileDescriptor
430+
-> Buffer
431+
-> Eff (err :: Exception, fs :: FS | eff) ByteCount
432+
fdAppend fd buff = fdWrite fd buff 0 (size buff) Nothing
433+
434+
--|
435+
-- Flush a file synchronously. See <a
436+
-- href="http://nodejs.org/api/fs.html#fs_fs_fsyncsync_fd">Node
437+
-- Documentation</a> for details.
438+
--
439+
fdFlush :: forall eff.
440+
FileDescriptor
441+
-> Eff (err :: Exception, fs :: FS | eff) Unit
442+
fdFlush fd = mkEff $ \_ -> runFn1 fs.fsyncSync fd
443+
444+
--|
445+
-- Close a file synchronously. See <a
446+
-- href="http://nodejs.org/api/fs.html#fs_fs_closesync_fd">Node
447+
-- Documentation</a> for details.
448+
--
449+
fdClose :: forall eff.
450+
FileDescriptor
451+
-> Eff (err :: Exception, fs :: FS | eff) Unit
452+
fdClose fd = mkEff $ \_ -> runFn1 fs.closeSync fd

0 commit comments

Comments
 (0)