Source code: com/neuron/jaffer/ByteWriter.java
1 /*
2 * Copyright (c) 2003 Stewart Allen <stewart@neuron.com>. All rights reserved.
3 * This program is free software. See the 'License' file for details.
4 */
5
6 package com.neuron.jaffer;
7
8 import java.io.*;
9 import java.net.*;
10 import java.util.*;
11
12 public final class ByteWriter extends Utility
13 {
14 private Vector deferred;
15 private int deferredOffset;
16 private byte data[];
17 private int pos;
18
19 private final static int TYPE_PSTRING = 1;
20 private final static int TYPE_AFPSTRING = 2;
21 private final static int TYPE_PSTRING_ARR = 3;
22 private final static int TYPE_AFPSTRING_ARR = 4;
23 private final static int TYPE_BYTE_ARR = 5;
24
25 ByteWriter(int size)
26 {
27 this(new byte[size]);
28 }
29
30 ByteWriter(byte data[])
31 {
32 this.data = data;
33 }
34
35 // non-write helper methods
36
37 public void readFromFile(RandomAccessFile file, long length)
38 throws IOException
39 {
40 int len = (int)length;
41 int read = 0;
42 while (read < len)
43 {
44 int got = file.read(data, pos, len - read);
45 if (got < 0)
46 {
47 throw new EOFException();
48 }
49 read += got;
50 }
51 pos += len;
52 }
53
54 public byte[] toByteArray()
55 throws IOException
56 {
57 flushDeferred();
58 byte ndata[] = new byte[pos];
59 System.arraycopy(data, 0, ndata, 0, pos);
60 return ndata;
61 }
62
63 public void writeTo(OutputStream os)
64 throws IOException
65 {
66 flushDeferred();
67 os.write(data, 0, pos);
68 }
69
70 private void flushDeferred()
71 {
72 if (deferred != null)
73 {
74 for (int i=0; i<deferred.size(); i++)
75 {
76 ((Deferred)deferred.get(i)).writeString();
77 ((Deferred)deferred.get(i)).writePtr(data);
78 }
79 deferred = null;
80 }
81 }
82
83 public int getOffset()
84 {
85 return pos;
86 }
87
88 public int getSize()
89 {
90 flushDeferred();
91 return pos;
92 }
93
94 // deferred write methods
95
96 public void markDeferredOffset()
97 {
98 deferredOffset = pos;
99 }
100
101 public void writeAFPStringDeferred(String s)
102 {
103 writeDeferred(s, TYPE_AFPSTRING);
104 }
105
106 public void writePStringDeferred(String s)
107 {
108 writeDeferred(s, TYPE_PSTRING);
109 }
110
111 public void writePStringArrayDeferred(String s[])
112 {
113 writeDeferred(s, TYPE_PSTRING_ARR);
114 }
115
116 public void writeBytesDeferred(byte b[])
117 {
118 writeDeferred(b, TYPE_BYTE_ARR);
119 }
120
121 private void writeDeferred(Object s, int type)
122 {
123 if (deferred == null)
124 {
125 deferred = new Vector(3);
126 }
127 deferred.add(new Deferred(s, type));
128 writeShort(0);
129 }
130
131 // immediate write methods
132
133 public void writePString(String s)
134 {
135 writeByte(s.length());
136 writeBytes(s.getBytes());
137 }
138
139 public void writePStringArray(String s[])
140 {
141 writeByte(s.length);
142 for (int i=0; i<s.length; i++)
143 {
144 writePString(s[i]);
145 }
146 }
147
148 public void writeAFPString(String s)
149 {
150 writeShort(s.length());
151 writeBytes(s.getBytes());
152 }
153
154 public void writeByte(int i)
155 {
156 data[pos++] = (byte)(i & 0xff);
157 }
158
159 public void writeBytes(byte b[])
160 {
161 System.arraycopy(b, 0, data, pos, b.length);
162 pos += b.length;
163 }
164
165 public void writeBytes(byte b[], int off, int len)
166 {
167 System.arraycopy(b, off, data, pos, len);
168 pos += len;
169 }
170
171 public void writeShortAtPos(int i, int pos)
172 {
173 writeInt2(data, pos, i);
174 }
175
176 public void writeIntAtPos(int i, int pos)
177 {
178 writeInt4(data, pos, i);
179 }
180
181 public void writeShort(int i)
182 {
183 writeInt2(data, pos, i);
184 pos += 2;
185 }
186
187 public void writeInt(int i)
188 {
189 writeInt4(data, pos, i);
190 pos += 4;
191 }
192
193 public void writeLong(long l)
194 {
195 writeInt8(data, pos, l);
196 pos += 8;
197 }
198
199 public void write(int v)
200 {
201 writeByte(v);
202 }
203
204 public void writeBytes(String s)
205 {
206 writeBytes(s.getBytes());
207 }
208
209 // deferred write helper class
210
211 private class Deferred
212 {
213 private int type;
214 private int ptrPos;
215 private int arrPos;
216 private Object object;
217
218 Deferred(Object o, int t)
219 {
220 this.object = o;
221 this.type = t;
222 this.ptrPos = pos;
223 }
224
225 void writeString()
226 {
227 this.arrPos = pos - deferredOffset;
228 switch (type)
229 {
230 case TYPE_PSTRING: writePString((String)object); break;
231 case TYPE_AFPSTRING: writeAFPString((String)object); break;
232 case TYPE_PSTRING_ARR: writePStringArray((String[])object); break;
233 case TYPE_BYTE_ARR: writeBytes((byte[])object); break;
234 default: error("unknown deferred object type: "+type); break;
235 }
236 }
237
238 void writePtr(byte b[])
239 {
240 writeInt2(b, ptrPos, arrPos);
241 }
242 }
243
244 }
245