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 }