001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. All Rights Reserved. */
003 /* Open Source Software - may be modified and shared by FRC teams. The code */
004 /* must be accompanied by the FIRST BSD license file in the root directory of */
005 /* the project. */
006 /*----------------------------------------------------------------------------*/
007
008 package com.sun.squawk.io.j2me.dserror;
009
010 import com.sun.cldc.jna.Pointer;
011 import java.io.*;
012 import javax.microedition.io.*;
013 import com.sun.squawk.io.*;
014 import edu.wpi.first.wpilibj.communication.FRCControl;
015
016 /**
017 * This Generic Connection Framework Protocol class writes to the FRC Driver Station error pane.
018 * @author dw29446
019 */
020 public class Protocol extends ConnectionBase implements OutputConnection {
021
022 protected boolean opened = false;
023
024 public Protocol() {
025 }
026
027 /**
028 * Open the connection
029 * @param name the target for the connection
030 * @param timeouts a flag to indicate that the called wants
031 * timeout exceptions
032 */
033 public Connection open(String protocol, String name, int mode, boolean timeouts)
034 throws IOException {
035 return this;
036 }
037
038 /**
039 * Returns an output stream for this socket.
040 *
041 * @return an output stream for writing bytes to this socket.
042 * @exception IOException if an I/O error occurs when creating
043 * the output stream.
044 */
045 public OutputStream openOutputStream()
046 throws IOException {
047
048 if (opened) {
049 throw new IOException("Stream already opened");
050 }
051 opened = true;
052 return new DSErrorOutputStream();
053 }
054 }
055
056 /**
057 * Output stream for the connection
058 */
059 class DSErrorOutputStream extends OutputStream {
060
061 final static int DEFAULT_BUFFER_SIZE = 512;
062 private Pointer errorBuffer;
063 private int index;
064 private boolean errorOccurred;
065
066 /**
067 * Constructor
068 */
069 DSErrorOutputStream() {
070 errorBuffer = new Pointer(DEFAULT_BUFFER_SIZE);
071 index = 0;
072 }
073
074 /**
075 * Writes the specified byte to this output stream.
076 *
077 * @param b the <code>byte</code>.
078 * @exception IOException if an I/O error occurs. In particular,
079 * an <code>IOException</code> may be thrown if the
080 * output stream has been closed.
081 */
082 synchronized public void write(int b)
083 throws IOException {
084 if (errorOccurred) {
085 return;
086 }
087 try {
088 if (errorBuffer == null) {
089 throw new IllegalStateException("DSErrorOutputStream is closed");
090 }
091
092 if (index >= errorBuffer.getSize()) {
093 flush();
094 }
095
096 if (b == '\n' && index != 0) {
097 flush(); // appends cr and nl...
098 } else {
099 errorBuffer.setByte(index++, (byte) b);
100 }
101 } catch (Throwable e) {
102 errorOccurred = true;
103 throw new RuntimeException("Squashing exception in error stream writer: " + e);
104 }
105 }
106
107 // public synchronized void write(byte b[], int off, int len) throws IOException {
108 // if (b == null) {
109 // throw new NullPointerException();
110 // } else if ((off < 0) || (off > b.length) || (len < 0) ||
111 // ((off + len) > b.length) || ((off + len) < 0)) {
112 // throw new IndexOutOfBoundsException();
113 // } else if (len == 0) {
114 // return;
115 // }
116 // for (int i = 0 ; i < len ; i++) {
117 // write(b[off + i]);
118 // }
119 // }
120
121 /**
122 * Flushes this output stream and forces any buffered output bytes
123 * to be written out. The general contract of <code>flush</code> is
124 * that calling it is an indication that, if any bytes previously
125 * written have been buffered by the implementation of the output
126 * stream, such bytes should immediately be written to their
127 * intended destination.
128 * <p>
129 * The <code>flush</code> method of <code>OutputStream</code> does nothing.
130 *
131 * @exception IOException if an I/O error occurs.
132 */
133 public synchronized void flush()
134 throws IOException {
135 if (errorBuffer == null) {
136 throw new IllegalStateException("DSErrorOutputStream is closed");
137 }
138
139 if (index > 0) {
140 FRCControl.setErrorData(errorBuffer, index, 100);
141 index = 0;
142 }
143 }
144
145 /**
146 * Close the stream
147 *
148 * @exception IOException if an I/O error occurs.
149 */
150 public synchronized void close() {
151 if (errorBuffer != null) {
152 index = 0;
153 errorBuffer.free();
154 errorBuffer = null;
155 }
156 }
157 }
158