Socket.hx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c) 2005, The haXe Project Contributors
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * - Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * - Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  23. * DAMAGE.
  24. *
  25. * Contributor: Lee McColl Sylvester
  26. */
  27. package neko.net;
  28. enum SocketHandle {
  29. }
  30. class Socket {
  31. private var __s : SocketHandle;
  32. public var input(default,null) : SocketInput;
  33. public var output(default,null) : SocketOutput;
  34. public var custom : Dynamic;
  35. public function new( ?s ) {
  36. __s = if( s == null ) socket_new(false) else s;
  37. input = new SocketInput(__s);
  38. output = new SocketOutput(__s);
  39. }
  40. public function close() : Void {
  41. socket_close(__s);
  42. untyped {
  43. input.__s = null;
  44. output.__s = null;
  45. }
  46. input.close();
  47. output.close();
  48. }
  49. public function read() : String {
  50. return socket_read(__s);
  51. }
  52. public function write( content : String ) {
  53. socket_write(__s, untyped content.__s);
  54. }
  55. public function connect(host : Host, port : Int) {
  56. try {
  57. socket_connect(__s, host.ip, port);
  58. } catch( s : String ) {
  59. if( s == "std@socket_connect" )
  60. throw "Failed to connect on "+(try host.reverse() catch( e : Dynamic ) host.toString())+":"+port;
  61. else
  62. neko.Lib.rethrow(s);
  63. }
  64. }
  65. public function listen(connections : Int) {
  66. socket_listen(__s, connections);
  67. }
  68. public function shutdown( read : Bool, write : Bool ){
  69. socket_shutdown(__s,read,write);
  70. }
  71. public function bind(host : Host, port : Int) {
  72. socket_bind(__s, host.ip, port);
  73. }
  74. public function accept() : Socket {
  75. return new Socket(socket_accept(__s));
  76. }
  77. public function peer() : { host : Host, port : Int } {
  78. var a : Dynamic = socket_peer(__s);
  79. var h = new Host("127.0.0.1");
  80. untyped h.ip = a[0];
  81. return { host : h, port : a[1] };
  82. }
  83. public function host() : { host : Host, port : Int } {
  84. var a : Dynamic = socket_host(__s);
  85. var h = new Host("127.0.0.1");
  86. untyped h.ip = a[0];
  87. return { host : h, port : a[1] };
  88. }
  89. public function setTimeout( timeout : Float ) {
  90. socket_set_timeout(__s, timeout);
  91. }
  92. public function waitForRead() {
  93. select([this],null,null,null);
  94. }
  95. public function setBlocking( b : Bool ) {
  96. socket_set_blocking(__s,b);
  97. }
  98. public static function newUdpSocket() {
  99. return new Socket(socket_new(true));
  100. }
  101. // STATICS
  102. public static function select(read : Array<Socket>, write : Array<Socket>, others : Array<Socket>, timeout : Float) : {read: Array<Socket>,write: Array<Socket>,others: Array<Socket>} {
  103. var c = untyped __dollar__hnew( 1 );
  104. var f = function( a : Array<Socket> ){
  105. if( a == null ) return null;
  106. untyped {
  107. var r = __dollar__amake(a.length);
  108. var i = 0;
  109. while( i < a.length ){
  110. r[i] = a[i].__s;
  111. __dollar__hadd(c,a[i].__s,a[i]);
  112. i += 1;
  113. }
  114. return r;
  115. }
  116. }
  117. var neko_array = socket_select(f(read),f(write),f(others), timeout);
  118. var g = function( a ) : Array<Socket> {
  119. if( a == null ) return null;
  120. var r = new Array();
  121. var i = 0;
  122. while( i < untyped __dollar__asize(a) ){
  123. var t = untyped __dollar__hget(c,a[i],null);
  124. if( t == null ) throw "Socket object not found.";
  125. r[i] = t;
  126. i += 1;
  127. }
  128. return r;
  129. }
  130. return {
  131. read: g(neko_array[0]),
  132. write: g(neko_array[1]),
  133. others: g(neko_array[2])
  134. };
  135. }
  136. private static var socket_new = neko.Lib.load("std","socket_new",1);
  137. private static var socket_close = neko.Lib.load("std","socket_close",1);
  138. private static var socket_write = neko.Lib.load("std","socket_write",2);
  139. private static var socket_read = neko.Lib.load("std","socket_read",1);
  140. private static var socket_connect = neko.Lib.load("std","socket_connect",3);
  141. private static var socket_listen = neko.Lib.load("std","socket_listen",2);
  142. private static var socket_select = neko.Lib.load("std","socket_select",4);
  143. private static var socket_bind = neko.Lib.load("std","socket_bind",3);
  144. private static var socket_accept = neko.Lib.load("std","socket_accept",1);
  145. private static var socket_peer = neko.Lib.load("std","socket_peer",1);
  146. private static var socket_host = neko.Lib.load("std","socket_host",1);
  147. private static var socket_set_timeout = neko.Lib.load("std","socket_set_timeout",2);
  148. private static var socket_shutdown = neko.Lib.load("std","socket_shutdown",3);
  149. private static var socket_set_blocking = neko.Lib.load("std","socket_set_blocking",2);
  150. }