1 /*** 2 * Copyright 2006 Joseph M. Ferner 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.fernsroth.easyio; 17 18 import java.io.FilterOutputStream; 19 import java.io.IOException; 20 import java.io.OutputStream; 21 import java.lang.reflect.Field; 22 import java.math.BigInteger; 23 import java.util.LinkedList; 24 import java.util.List; 25 import java.util.Queue; 26 27 import com.fernsroth.easyio.exception.EasyIOException; 28 import com.fernsroth.easyio.util.BeanUtils; 29 30 /*** 31 * @author Joseph M. Ferner (Near Infinity Corporation) 32 */ 33 public class EasyIOOutputStream extends FilterOutputStream { 34 35 /*** 36 * count of bytes that have been processed. 37 */ 38 private long count = 0; 39 40 /*** 41 * the field handler registry. 42 */ 43 private FieldHandlerRegistry fieldHandlerRegistry = DefaultFieldHandlerRegistry 44 .getInstance(); 45 46 /*** 47 * constructor. 48 * @param out the output stream to wrap. 49 */ 50 public EasyIOOutputStream(OutputStream out) { 51 super(out); 52 } 53 54 /*** 55 * constructor. 56 * @param out the output stream to wrap. 57 */ 58 public EasyIOOutputStream(IOutputStream out) { 59 this(new OutputStreamAdapter(out)); 60 } 61 62 /*** 63 * writes an object to the stream. 64 * @param obj the object to write. 65 * @throws EasyIOException 66 * @throws IOException 67 */ 68 public void write(Object obj) throws EasyIOException, IOException { 69 List<Field> fields = BeanUtils.getAllFields(obj.getClass()); 70 Queue<Field> fieldsQueue = new LinkedList<Field>(fields); 71 Field field; 72 73 while (!fieldsQueue.isEmpty()) { 74 field = fieldsQueue.peek(); 75 FieldHandler handler = this.fieldHandlerRegistry.lookup(obj, field); 76 if (handler != null) { 77 handler.write(this, obj, fieldsQueue); 78 } else { 79 fieldsQueue.remove(); 80 } 81 } 82 } 83 84 /*** 85 * writes an 64-bit integer (little endien). 86 * @param val the value to write. 87 * @throws IOException 88 */ 89 public void writeINT64(long val) throws IOException { 90 byte[] data = new byte[8]; 91 data[0] = (byte) ((val >> 0) & 0xff); 92 data[1] = (byte) ((val >> 8) & 0xff); 93 data[2] = (byte) ((val >> 16) & 0xff); 94 data[3] = (byte) ((val >> 24) & 0xff); 95 data[4] = (byte) ((val >> 32) & 0xff); 96 data[5] = (byte) ((val >> 40) & 0xff); 97 data[6] = (byte) ((val >> 48) & 0xff); 98 data[7] = (byte) ((val >> 56) & 0xff); 99 write(data); 100 } 101 102 /*** 103 * write a uint64. 104 * @param val the value to write. 105 * @throws IOException 106 */ 107 public void writeUINT64(BigInteger val) throws IOException { 108 String valstr = val.toString(16); 109 byte[] data = new byte[8]; 110 for (int i = 0; i < data.length; i++) { 111 data[i] = (byte) Integer.parseInt(valstr.substring(i * 2, 112 (i + 1) * 2), 16); 113 } 114 write(data); 115 } 116 117 /*** 118 * writes an unsigned 64-bit integer (little endien). 119 * @param val the value to write. 120 * @throws IOException 121 */ 122 public void writeUINT32(long val) throws IOException { 123 byte[] data = new byte[4]; 124 data[0] = (byte) ((val >> 0) & 0xff); 125 data[1] = (byte) ((val >> 8) & 0xff); 126 data[2] = (byte) ((val >> 16) & 0xff); 127 data[3] = (byte) ((val >> 24) & 0xff); 128 write(data); 129 } 130 131 /*** 132 * writes an unsigned 16-bit integer (little endien). 133 * @param val the value to write. 134 * @throws IOException 135 */ 136 public void writeUINT16(int val) throws IOException { 137 byte[] data = new byte[2]; 138 data[0] = (byte) ((val >> 0) & 0xff); 139 data[1] = (byte) ((val >> 8) & 0xff); 140 write(data); 141 } 142 143 /*** 144 * writes an unsigned 8-bit integer. 145 * @param val the value to write. 146 * @throws IOException 147 */ 148 public void writeUINT8(int val) throws IOException { 149 write(val); 150 } 151 152 /*** 153 * gets the count of bytes written. 154 * @return the count of bytes written. 155 */ 156 public long getCount() { 157 return this.count; 158 } 159 160 /*** 161 * {@inheritDoc} 162 */ 163 @Override 164 public void write(int b) throws IOException { 165 super.write(b); 166 this.count++; 167 } 168 }