PageRenderTime 31ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/contrib/Network/Socket/Data.idr

https://github.com/idris-lang/Idris-dev
Idris | 172 lines | 120 code | 41 blank | 11 comment | 2 complexity | f462fc11273d2a01b20e20d89bf65134 MD5 | raw file
  1. ||| Low-Level C Sockets bindings for Idris. Used by higher-level, cleverer things.
  2. ||| Types used by Network.Socket.Raw and Network.Socket.
  3. |||
  4. ||| Original (C) SimonJF, MIT Licensed, 2014
  5. ||| Modified (C) The Idris Community, 2015, 2016
  6. module Network.Socket.Data
  7. %access public export
  8. -- ------------------------------------------------------------ [ Type Aliases ]
  9. ByteLength : Type
  10. ByteLength = Int
  11. ResultCode : Type
  12. ResultCode = Int
  13. ||| Protocol Number.
  14. |||
  15. ||| Generally good enough to just set it to 0.
  16. ProtocolNumber : Type
  17. ProtocolNumber = Int
  18. ||| SocketError: Error thrown by a socket operation
  19. SocketError : Type
  20. SocketError = Int
  21. ||| SocketDescriptor: Native C Socket Descriptor
  22. SocketDescriptor : Type
  23. SocketDescriptor = Int
  24. Port : Type
  25. Port = Int
  26. -- --------------------------------------------------------------- [ Constants ]
  27. ||| Backlog used within listen() call -- number of incoming calls
  28. BACKLOG : Int
  29. BACKLOG = 20
  30. EAGAIN : Int
  31. EAGAIN =
  32. -- I'm sorry
  33. -- maybe
  34. unsafePerformIO $ foreign FFI_C "idrnet_geteagain" (() -> IO Int) ()
  35. -- -------------------------------------------------------------- [ Interfaces ]
  36. interface ToCode a where
  37. toCode : a -> Int
  38. -- --------------------------------------------------------- [ Socket Families ]
  39. ||| Socket Families
  40. |||
  41. ||| The ones that people might actually use. We're not going to need US
  42. ||| Government proprietary ones.
  43. data SocketFamily : Type where
  44. ||| Unspecified
  45. AF_UNSPEC : SocketFamily
  46. ||| IP / UDP etc. IPv4
  47. AF_INET : SocketFamily
  48. ||| IP / UDP etc. IPv6
  49. AF_INET6 : SocketFamily
  50. Show SocketFamily where
  51. show AF_UNSPEC = "AF_UNSPEC"
  52. show AF_INET = "AF_INET"
  53. show AF_INET6 = "AF_INET6"
  54. ToCode SocketFamily where
  55. toCode AF_UNSPEC = unsafePerformIO (foreign FFI_C "#AF_UNSPEC" (IO Int))
  56. toCode AF_INET = unsafePerformIO (foreign FFI_C "#AF_INET" (IO Int))
  57. toCode AF_INET6 = unsafePerformIO (foreign FFI_C "#AF_INET6" (IO Int))
  58. getSocketFamily : Int -> Maybe SocketFamily
  59. getSocketFamily i =
  60. Prelude.List.lookup i [ (toCode AF_UNSPEC, AF_UNSPEC)
  61. , (toCode AF_INET, AF_INET)
  62. , (toCode AF_INET6, AF_INET6)
  63. ]
  64. -- ------------------------------------------------------------ [ Socket Types ]
  65. ||| Socket Types.
  66. data SocketType : Type where
  67. ||| Not a socket, used in certain operations
  68. NotASocket : SocketType
  69. ||| TCP
  70. Stream : SocketType
  71. ||| UDP
  72. Datagram : SocketType
  73. ||| Raw sockets
  74. RawSocket : SocketType
  75. Show SocketType where
  76. show NotASocket = "Not a socket"
  77. show Stream = "Stream"
  78. show Datagram = "Datagram"
  79. show RawSocket = "Raw"
  80. ToCode SocketType where
  81. toCode NotASocket = 0
  82. toCode Stream = 1
  83. toCode Datagram = 2
  84. toCode RawSocket = 3
  85. -- --------------------------------------------------------------- [ Addresses ]
  86. ||| Network Addresses
  87. data SocketAddress : Type where
  88. IPv4Addr : Int -> Int -> Int -> Int -> SocketAddress
  89. ||| Not implemented (yet)
  90. IPv6Addr : SocketAddress
  91. Hostname : String -> SocketAddress
  92. ||| Used when there's a parse error
  93. InvalidAddress : SocketAddress
  94. Show SocketAddress where
  95. show (IPv4Addr i1 i2 i3 i4) = concat $ Prelude.List.intersperse "." (map show [i1, i2, i3, i4])
  96. show IPv6Addr = "NOT IMPLEMENTED YET"
  97. show (Hostname host) = host
  98. show InvalidAddress = "Invalid"
  99. ||| Parses a textual representation of an IPv4 address into a SocketAddress
  100. parseIPv4 : String -> SocketAddress
  101. parseIPv4 str =
  102. case splitted of
  103. (i1 :: i2 :: i3 :: i4 :: _) => IPv4Addr i1 i2 i3 i4
  104. otherwise => InvalidAddress
  105. where
  106. toInt' : String -> Integer
  107. toInt' = cast
  108. toInt : String -> Int
  109. toInt s = fromInteger $ toInt' s
  110. splitted : List Int
  111. splitted = map toInt (Prelude.Strings.split (\c => c == '.') str)
  112. -- --------------------------------------------------------- [ UDP Information ]
  113. -- TODO: Expand to non-string payloads
  114. record UDPRecvData where
  115. constructor MkUDPRecvData
  116. remote_addr : SocketAddress
  117. remote_port : Port
  118. recv_data : String
  119. data_len : Int
  120. record UDPAddrInfo where
  121. constructor MkUDPAddrInfo
  122. remote_addr : SocketAddress
  123. remote_port : Port
  124. -- ----------------------------------------------------------------- [ Sockets ]
  125. ||| The metadata about a socket
  126. record Socket where
  127. constructor MkSocket
  128. descriptor : SocketDescriptor
  129. family : SocketFamily
  130. socketType : SocketType
  131. protocolNumber : ProtocolNumber