;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; A simple echo server.  To test just start the server
;; and then: telnet 127.0.0.1 12345
;; Then type something to se it echo back.
;;
;; Author: Matthew W. Coan
;; Start Date: 05/17/2002
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.class EchoServer
.access public
.modifyers
.extends java.lang.Object
.implements java.lang.Runnable

;;;;;;;;;;;;;;;;;;;;;
;; The client socket
;;;;;;;;;;;;;;;;;;;;;
.field _clientSocket
.access private
.modifyers
.type Ljava/net/Socket;

;;;;;;;;;;;;;;;;;;;;;
;; Construct from a 
;; client socket
;;;;;;;;;;;;;;;;;;;;;
.method <init>
.maxStack 5
.access public
.modifyers
.signature (Ljava/net/Socket;)V
.args client

.data

.code
	aload this
	invokespecial java.lang.Object <init> ()V
	fieldref EchoServer _clientSocket Ljava/net/Socket; cli
	aload this
	aload client
	putfield cli
	aload this
	return
.end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The run method:
;; Loop forever accpeting connections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.method run
.maxStack 5
.access public
.modifyers
.signature ()V
.args

.data
java.io.InputStream in
java.io.InputStreamReader ir
java.io.BufferedReader br
java.lang.String line
java.io.OutputStream out
java.io.PrintStream ps

.code
	fieldref EchoServer _clientSocket Ljava/net/Socket; cli
	fieldref java.lang.System out Ljava/io/PrintStream; stdout

	;; Create a buffred reader to read text
	;; from the client.
	aload this
	getfield cli
	invokevirtual java.net.Socket getInputStream ()Ljava/io/InputStream;
	astore in
	new java.io.InputStreamReader
	dup
	aload in
	invokespecial java.io.InputStreamReader <init> (Ljava/io/InputStream;)V
	astore ir
	new java.io.BufferedReader
	dup
	aload ir
	invokespecial java.io.BufferedReader <init> (Ljava/io/Reader;)V
	astore br

	;; Create a print stream to echo the text back
	;; to the client.
	aload this
	getfield cli
	invokevirtual java.net.Socket getOutputStream ()Ljava/io/OutputStream;
	astore out
	new java.io.PrintStream
	dup
	aload out
	invokespecial java.io.PrintStream <init> (Ljava/io/OutputStream;)V
	astore ps
	
	;; Read lines of text and echo them back 
	;; until the client closes the connection.
L1	aload br
	invokevirtual java.io.BufferedReader readLine ()Ljava/lang/String;
	astore line
	aload line
	aconst_null
	if_acmpeq L2
	getstatic stdout
	aload line
	invokevirtual java.io.PrintStream println (Ljava/lang/String;)V
	aload ps
	aload line
	invokevirtual java.io.PrintStream println (Ljava/lang/String;)V
	aload ps
	invokevirtual java.io.PrintStream flush ()V
	goto L1

	;; Close the connection
L2	aload this
	getfield cli
	invokevirtual java.net.Socket close ()V
	return
.end

;;;;;;;;;;;;;;;;;;;;
;; Main entry point
;;;;;;;;;;;;;;;;;;;;
.method main
.maxStack 5
.access public
.modifyers static
.signature ([Ljava/lang/String;)V
.args args

.data
java.net.ServerSocket serverSocket
java.net.Socket clientSocket
java.lang.Thread thread
EchoServer runner

.code
	;; Cretae the server socket on port 12345
	new java.net.ServerSocket
	dup
	ipush 12345
	invokespecial java.net.ServerSocket <init> (I)V
	astore serverSocket

	;; Wait for a connection
L1	aload serverSocket
	invokevirtual java.net.ServerSocket accept ()Ljava/net/Socket;
	astore clientSocket

	;; Spawn a new thread to handle the connection
	new EchoServer
	dup
	aload clientSocket
	invokespecial EchoServer <init> (Ljava/net/Socket;)V
	astore runner
	new java.lang.Thread
	dup
	aload runner
	invokespecial java.lang.Thread <init> (Ljava/lang/Runnable;)V
	invokevirtual java.lang.Thread start ()V
	goto L1
	return
.end
