⍝ Quad_FIO.tc
⍝ ----------------------------------

      ⍝ same as File_IO_1.tc but using FILE_IO.apl library
      ⍝ This is the recommeded way to use file_io.so
      ⍝
      ⍝ This file demonstrates the use of the FILE_IO.apl library
      ⍝ and checks that the wrapper functions in FILE_IO.apl are working
      ⍝

      ⍝⍝⍝
      ⍝⍝⍝ If this segfaults then re-install GNU APL !!!
      ⍝⍝⍝
      )COPY 5 FILE_IO.apl
DUMPED ³

      ⍝ fopen this file readonly
      ⍝
      Filename←'testcases/File_IO_1.tc'
      ⎕←Handle←FIO∆fopen_ro Filename
⁰

      ⍝ get statistics
      ⍝
      ⎕←FIO∆fstat Handle
⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰ ⁰

      ⍝ close this file
      ⍝
      ⎕←FIO∆fclose Handle
0

      ⍝ close this file again (which is an error)
      ⍝
      FIO∆fclose Handle
DOMAIN ERROR+
FIO∆fclose[2]  Ze←⎕FIO[4]Bh
                  ^      ^
      →

      ⍝ create new file
      ⍝
      Filename← "FILE_IO.test"
      ⎕←Handle←'w' FIO∆fopen Filename
⁰
      FIO∆errno
0
      FIO∆strerror FIO∆errno
Success

      ⍝ write 3 lines
      ⍝
      ⎕←(⎕UCS "Hello\n") FIO∆fwrite Handle
6
      ⎕←(⎕UCS "World\n") FIO∆fwrite Handle
6
      ⎕←(⎕UCS "Line 3...\n") FIO∆fwrite Handle
10

      ⍝ close the file
      ⍝
      FIO∆fclose Handle
0

      ⍝ print the file
      ⍝
      )HOST cat FILE_IO.test
Hello
World
Line 3...

0 

      ⍝ open file again for reading
      ⍝
      ⎕←Handle← FIO∆fopen_ro Filename
⁰

      ⍝ read one line (default max_len)
      ⍝
      Z← FIO∆fgets Handle
      ⎕UCS Z
Hello

      ⍝ read another line (max_len 200)
      ⍝
      Z←200 FIO∆fgets Handle
      ⎕UCS Z
World

      ⍴Z
6

      ⍝ end of file ? (no)
      ⍝
      FIO∆feof Handle
0

      ⍝ read more bytes
      ⍝
      Z←200 FIO∆fread Handle
      ⍴Z
10

      ⍝ end of file ? (yes)
      ⍝
      FIO∆feof Handle
1

      ⍝ get statistics
      ⍝
      ⎕←FSTAT←FIO∆fstat Handle ◊ 0 8 8 8 ⊤ FSTAT[3]
⁰ ⁰ ⁰ 1 ⁰ ⁰ 0 22 ⁰ ⁰ ⁰ ⁰ ⁰
64 6 ⁰ ⁰

      ⍝ close the file
      ⍝
      FIO∆fclose Handle
0

      ⍝ delete the file
      ⍝
      FIO∆unlink Filename
0

      ⍝ delete the file again (should fail)
      ⍝
      Error←-FIO∆unlink Filename
      FIO∆strerror Error
No such file or directory

      ⎕FIO['strerror'] Error   ⍝ monadic with axis string
No such file or directory


      ⍝ printf
      ⍝
      )ERASE FORMAT
      FORMAT←⊂"⎕everything %d Pi %e String %s\n" 
      FIO∆printf FORMAT, 42 (○1) 'Hello'
44

      ⍝ fwrite with UCS in UTF8 out
      ⍝
      Filename← 'FILE_IO.test1'
      ⎕←Handle←'w' FIO∆fopen Filename
⁰
      'HELLO ⍋ ⌽ ⍒ ⍴ ⍵' FIO∆fwrite_utf8 Handle
25

      FIO∆fclose Handle ⍝ close file
0

      )HOST cat FILE_IO.test1 
HELLO ⍋ ⌽ ⍒ ⍴ ⍵
0 

      ⍝ popen "r"
      ⍝
      Command←'ls FILE_IO*'
      Handle← FIO∆popen_ro Command
      Z←20000 FIO∆fread Handle
      ⍴Z
⁰
      FIO∆pclose Handle ⍝ close command (returning its exit code)
0

      ⍝ read entire file
      ⍝
      ⎕UCS FIO∆read_file 'FILE_IO.test1'
72 69 76 76 79 32 226 141 139 32 226 140 189 32 226 141 146 32 226 141 180 32 
      226 141 181


      ⍝ socket communication: send 'Hello' from one socket to another socket
      ⍝ and send 'World!' back.
      ⍝
      AF_INET     ← 2           ⍝ see /usr/include/.../bits/socket.h
      SOCK_STREAM ← 1           ⍝ see /usr/include/.../bits/socket_type.h
      IPPROTO_IP       ← 0      ⍝ see /usr/include/netinet/in.h
      LOCALHOST←256⊥127 0 0 1   ⍝ 127.0.0.1 in host byte order
      Port ← 22222
      Server←AF_INET, LOCALHOST, Port

      ⍝ socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
      ⍝
      3 ≤ Handle←FIO∆socket AF_INET, SOCK_STREAM, IPPROTO_IP
1

      ⍝ setsockopt(Handle, SOL_SOCKET, SO_REUSEADDR, 1)
      ⍝
      SOL_SOCKET←1              ⍝ see /usr/include/asm-generic/socket.h
      SO_REUSEADDR←2            ⍝ see /usr/include/asm-generic/socket.h
      (SOL_SOCKET, SO_REUSEADDR, 1) FIO∆setsockopt Handle
0

      ⍝ bind(AF_INET, LOCALHOST, Port)
      ⍝
      Server FIO∆bind Handle
0

      ⍝ listen(10)
      ⍝
      10 FIO∆listen Handle
0

      ⍝ socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
      ⍝
      4 ≤ Handle1←FIO∆socket AF_INET, SOCK_STREAM, IPPROTO_IP
1

      ⍝ connect() Handle1 to Handle
      ⍝
      Server FIO∆connect Handle1
0

      ⍝ accept() returns Handle, remote address
      ⍝
      Handle2 ← ↑ FIO∆accept Handle

      ⍝ send("Hello")
      ⍝
      'Hello' FIO∆send_utf8 Handle2
5

      ⍝ recv()
      ⍝
      ⎕UCS 200 FIO∆recv Handle1
Hello

      ⍝ send("World!")
      ⍝
      'World!' FIO∆send_utf8 Handle1
6

      ⍝ recv()
      ⍝
      ⎕UCS 200 FIO∆recv Handle2
World!

      ⎕←FIO∆fclose Handle2
0
      ⎕←FIO∆fclose Handle1
0
      ⎕←FIO∆fclose Handle
0

      ⍝ fscanf
      ⍝
      Filename← 'FILE_IO.test1'
      ⎕←Handle←'w' FIO∆fopen Filename
⁰
      ⍴DATA←'int 22 perc % doub 3.14 char C chars DEFGH qqq str st⍴ing'
57
      FMT←'int %d perc %% doub %f char %c chars %5c qqq str %s %n'
      DATA FIO∆fwrite_utf8 Handle
59

      FIO∆fclose Handle ⍝ close file
0
      ⎕←Handle←'r' FIO∆fopen Filename
⁰
      FMT FIO∆fscanf Handle
 22 3.14 C DEFGH st⍴ing 59 

      FIO∆fclose Handle ⍝ close file
0

      ⍝ sscanf
      ⍝
      ⍴DATA←'int 22 perc % doub 3.14 char C chars DEFGH qqq str st⍴ing'
57
      FMT←'int %d perc %% doub %f char %c chars %5c qqq str %s %n'
      FMT FIO∆sscanf DATA
 22 3.14 C DEFGH st⍴ing 57 

      FMT ⎕FIO['sscanf'] DATA   ⍝ dyadic with axis string
 22 3.14 C DEFGH st⍴ing 57 

      ⍝ execve
      ⍝
      ⍝Filename←'/usr/local/lib/apl/TLV_server'  ⍝ whereever TLV_server lives
      Filename←'../tools/TLV_server'
      Handle ← FIO∆execve Filename        ⍝ start & connect TLV_server
      TLV ← 33 ⎕CR 42,'Forty-Two'         ⍝ encode a TLV buffer, Tag 42
      ⊣TLV ⎕FIO[43] Handle                ⍝ send TLV buffer to TLV_server
      TL ← 8 ⎕FIO[6] Handle               ⍝ read tag/lenght from TLV_server
      Value ← (256⊥4↓TL) ⎕FIO[6] Handle   ⍝ read value  from TLV_server
      34 ⎕CR TL,Value                     ⍝ display response tag and value
¯42 owT-ytroF
      TLV ← 33 ⎕CR 99,'quit'              ⍝ encode stop command, Tag 99
      ⊣TLV ⎕FIO[43] Handle                ⍝ send TLV buffer to TLV_server
      ⊣(⎕FIO[4] Handle)                   ⍝ close connection (stops TLV_server)

      FIO∆mkdir_777 FIO∆getcwd,'/test_data'
0
      DATA←'Kiss,n. A word invented by poets as a rhyme for bliss.'
      DATA FIO∆pipeto 'wc>test_data/wc.txt'
0
      FIO∆read_file 'test_data/wc.txt'
      0      11      54

      FIO∆pipefrom 'ls test_data'
wc.txt

      FIO∆unlink 'test_data/wc.txt'
0
      FIO∆rmdir 'test_data'
0

      )ERASE FORMAT Handle Handle1 Handle2 Command AF_INET SOCK_STREAM
      )ERASE Error FSTAT Filename LOCALHOST Port Z Server IPPROTO_IP
      )ERASE FMT DATA TL TLV Value

⍝     )VARS

⍝ ==================================