1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.core.io.util;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.Serializable;
27 import java.util.Arrays;
28 import java.util.Locale;
29 import org.jdtaus.core.container.ContainerFactory;
30 import org.jdtaus.core.io.FileOperations;
31 import org.jdtaus.core.lang.spi.MemoryManager;
32 import org.jdtaus.core.logging.spi.Logger;
33
34
35
36
37
38
39
40
41
42
43 public final class MemoryFileOperations
44 implements FileOperations, Serializable, Cloneable
45 {
46
47
48
49
50
51
52 private byte[] data;
53
54
55
56
57
58 private long filePointer;
59
60
61
62
63
64 private int length;
65
66
67
68
69
70 private byte[] defaultBuffer;
71
72
73
74
75
76
77
78
79
80
81
82
83 private int getStreamBufferSize()
84 {
85 return ( (java.lang.Integer) ContainerFactory.getContainer().
86 getProperty( this, "streamBufferSize" ) ).intValue();
87
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 private Logger getLogger()
104 {
105 return (Logger) ContainerFactory.getContainer().
106 getDependency( this, "Logger" );
107
108 }
109
110
111
112
113
114
115 private MemoryManager getMemoryManager()
116 {
117 return (MemoryManager) ContainerFactory.getContainer().
118 getDependency( this, "MemoryManager" );
119
120 }
121
122
123
124
125
126
127 private Locale getLocale()
128 {
129 return (Locale) ContainerFactory.getContainer().
130 getDependency( this, "Locale" );
131
132 }
133
134
135
136
137
138
139 public long getLength()
140 {
141 return this.length;
142 }
143
144
145
146
147
148
149
150 public void setLength( final long newLength )
151 {
152 if ( newLength < 0L || newLength > Integer.MAX_VALUE )
153 {
154 throw new IllegalArgumentException( Long.toString( newLength ) );
155 }
156
157 this.ensureCapacity( (int) newLength );
158 this.length = (int) newLength;
159 if ( this.filePointer > this.length )
160 {
161 this.filePointer = this.length;
162 }
163 }
164
165 public long getFilePointer()
166 {
167 return this.filePointer;
168 }
169
170 public void setFilePointer( final long pos )
171 {
172
173 if ( pos < 0L || pos > Integer.MAX_VALUE )
174 {
175 throw new IllegalArgumentException( Long.toString( pos ) );
176 }
177
178 this.filePointer = pos;
179 }
180
181 public int read( final byte[] buf, final int off, final int len )
182 {
183 final int ret;
184
185
186 if ( buf == null )
187 {
188 throw new NullPointerException( "buf" );
189 }
190 if ( off < 0 )
191 {
192 throw new ArrayIndexOutOfBoundsException( off );
193 }
194 if ( len < 0 )
195 {
196 throw new ArrayIndexOutOfBoundsException( len );
197 }
198 if ( off + len > buf.length )
199 {
200 throw new ArrayIndexOutOfBoundsException( off + len );
201 }
202 if ( this.filePointer + len > Integer.MAX_VALUE )
203 {
204 throw new ArrayIndexOutOfBoundsException( Integer.MAX_VALUE );
205 }
206
207 if ( len == 0 )
208 {
209 ret = 0;
210 }
211 else if ( this.filePointer >= this.length )
212 {
213
214 ret = FileOperations.EOF;
215 }
216 else if ( this.filePointer + len > this.length )
217 {
218
219 final int remaining = (int) ( this.length - this.filePointer );
220 System.arraycopy( this.data, (int) this.filePointer, buf, off,
221 remaining );
222
223 this.filePointer += remaining;
224 ret = remaining;
225 }
226 else
227 {
228
229 System.arraycopy(
230 this.data, (int) this.filePointer, buf, off, len );
231
232 this.filePointer += len;
233 ret = len;
234 }
235
236 return ret;
237 }
238
239 public void write( final byte[] buf, final int off, final int len )
240 {
241
242 if ( buf == null )
243 {
244 throw new NullPointerException( "buf" );
245 }
246 if ( off < 0 )
247 {
248 throw new ArrayIndexOutOfBoundsException( off );
249 }
250 if ( len < 0 )
251 {
252 throw new ArrayIndexOutOfBoundsException( len );
253 }
254 if ( off + len > buf.length )
255 {
256 throw new ArrayIndexOutOfBoundsException( off + len );
257 }
258
259 final long newLen = this.filePointer + len;
260 if ( newLen > Integer.MAX_VALUE )
261 {
262 throw new ArrayIndexOutOfBoundsException( Integer.MAX_VALUE );
263 }
264
265 if ( newLen > this.length )
266 {
267 this.setLength( newLen );
268 }
269
270 System.arraycopy( buf, off, this.data, (int) this.filePointer, len );
271 this.filePointer += len;
272 }
273
274 public void read( final OutputStream out ) throws IOException
275 {
276 if ( out == null )
277 {
278 throw new NullPointerException( "out" );
279 }
280
281 out.write( this.data, 0, this.length );
282 this.filePointer = this.length;
283 }
284
285 public void write( final InputStream in ) throws IOException
286 {
287 if ( in == null )
288 {
289 throw new NullPointerException( "in" );
290 }
291
292 int read;
293 final byte[] buf = this.getStreamBuffer();
294
295 while ( ( read = in.read( buf, 0, buf.length ) ) != FileOperations.EOF )
296 {
297 this.write( buf, 0, read );
298 }
299 }
300
301
302
303
304
305
306
307
308
309 public void close()
310 {
311 }
312
313
314
315
316
317 public MemoryFileOperations()
318 {
319 this.filePointer = 0L;
320 this.data = new byte[ 0 ];
321 this.length = 0;
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336 public MemoryFileOperations( final int initialCapacity )
337 {
338 this.filePointer = 0L;
339 this.length = 0;
340 this.data = this.getMemoryManager().allocateBytes( initialCapacity );
341 }
342
343
344
345
346
347
348
349
350 public MemoryFileOperations( final byte[] buf )
351 {
352 this();
353
354 if ( buf == null )
355 {
356 throw new NullPointerException( "buf" );
357 }
358
359 this.data = buf;
360 this.length = buf.length;
361 this.filePointer = 0L;
362 }
363
364
365
366
367
368
369 public int getCapacity()
370 {
371 return this.data.length;
372 }
373
374
375
376
377
378
379
380
381 public void ensureCapacity( final int minimumCapacity )
382 {
383 final int oldLength = this.data.length;
384
385 while ( this.data.length < minimumCapacity )
386 {
387 final byte[] newData = this.getMemoryManager().allocateBytes(
388 this.data.length * 2 >= minimumCapacity
389 ? this.data.length * 2
390 : minimumCapacity );
391
392 Arrays.fill( newData, (byte) 0 );
393 System.arraycopy( this.data, 0, newData, 0, this.data.length );
394 this.data = newData;
395 }
396
397 if ( oldLength != this.data.length &&
398 this.getLogger().isDebugEnabled() )
399 {
400 this.getLogger().debug(
401 this.getLogResizeMessage( this.getLocale(),
402 new Long( this.data.length ) ) );
403
404 }
405 }
406
407
408
409
410
411
412
413
414 public byte[] getData()
415 {
416 final int len = (int) this.getLength();
417 final byte[] ret = this.getMemoryManager().allocateBytes( len );
418
419 System.arraycopy( this.data, 0, ret, 0, len );
420
421 return ret;
422 }
423
424
425
426
427
428
429 private byte[] getStreamBuffer()
430 {
431 if ( this.defaultBuffer == null )
432 {
433 this.defaultBuffer = this.getMemoryManager().
434 allocateBytes( this.getStreamBufferSize() < 0
435 ? 0
436 : this.getStreamBufferSize() );
437
438 }
439
440 return this.defaultBuffer;
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454
455 public boolean equals( final Object o )
456 {
457 boolean equal = this == o;
458
459 if ( !equal && o instanceof MemoryFileOperations )
460 {
461 final MemoryFileOperations that = (MemoryFileOperations) o;
462 equal = Arrays.equals( getData(), that.getData() );
463 }
464
465 return equal;
466 }
467
468
469
470
471
472
473 public int hashCode()
474 {
475
476 final byte[] bytes = getData();
477
478 int result = 1;
479 for ( int i = 0, s0 = bytes.length; i < s0; i++ )
480 {
481 result = 31 * result + bytes[i];
482 }
483
484 return result;
485 }
486
487
488
489
490
491
492 public Object clone()
493 {
494 try
495 {
496 return super.clone();
497 }
498 catch ( CloneNotSupportedException e )
499 {
500 throw new AssertionError( e );
501 }
502 }
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520 private String getLogResizeMessage( final Locale locale,
521 final java.lang.Number bufferSize )
522 {
523 return ContainerFactory.getContainer().
524 getMessage( this, "logResize", locale,
525 new Object[]
526 {
527 bufferSize
528 });
529
530 }
531
532
533
534
535 }