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