Mercurial > hg4j
comparison src/com/tmate/hgkit/fs/FilterDataAccess.java @ 51:9429c7bd1920 wrap-data-access
Try DataAccess to reach revision data instead of plain byte arrays
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Sun, 16 Jan 2011 01:20:26 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
50:f1db8610da62 | 51:9429c7bd1920 |
---|---|
1 /* | |
2 * Copyright (c) 2011 Artem Tikhomirov | |
3 */ | |
4 package com.tmate.hgkit.fs; | |
5 | |
6 import java.io.IOException; | |
7 | |
8 /** | |
9 * XXX Perhaps, DataAccessSlice? Unlike FilterInputStream, we limit amount of data read from DataAccess being filtered. | |
10 * | |
11 * @author artem | |
12 */ | |
13 public class FilterDataAccess extends DataAccess { | |
14 private final DataAccess dataAccess; | |
15 private final long offset; | |
16 private final int length; | |
17 private int count; | |
18 | |
19 public FilterDataAccess(DataAccess dataAccess, long offset, int length) { | |
20 this.dataAccess = dataAccess; | |
21 this.offset = offset; | |
22 this.length = length; | |
23 count = length; | |
24 } | |
25 | |
26 protected int available() { | |
27 return count; | |
28 } | |
29 | |
30 @Override | |
31 public void reset() throws IOException { | |
32 count = length; | |
33 } | |
34 | |
35 @Override | |
36 public boolean isEmpty() { | |
37 return count <= 0; | |
38 } | |
39 | |
40 @Override | |
41 public long length() { | |
42 return length; | |
43 } | |
44 | |
45 @Override | |
46 public void seek(long localOffset) throws IOException { | |
47 if (localOffset < 0 || localOffset > length) { | |
48 throw new IllegalArgumentException(); | |
49 } | |
50 dataAccess.seek(offset + localOffset); | |
51 count = (int) (length - localOffset); | |
52 } | |
53 | |
54 @Override | |
55 public void skip(int bytes) throws IOException { | |
56 int newCount = count - bytes; | |
57 if (newCount < 0 || newCount > length) { | |
58 throw new IllegalArgumentException(); | |
59 } | |
60 seek(length - newCount); | |
61 /* | |
62 can't use next code because don't want to rewind backing DataAccess on reset() | |
63 i.e. this.reset() modifies state of this instance only, while filtered DA may go further. | |
64 Only actual this.skip/seek/read would rewind it to desired position | |
65 dataAccess.skip(bytes); | |
66 count = newCount; | |
67 */ | |
68 | |
69 } | |
70 | |
71 @Override | |
72 public byte readByte() throws IOException { | |
73 if (count <= 0) { | |
74 throw new IllegalArgumentException("Underflow"); // XXX be descriptive | |
75 } | |
76 if (count == length) { | |
77 dataAccess.seek(offset); | |
78 } | |
79 count--; | |
80 return dataAccess.readByte(); | |
81 } | |
82 | |
83 @Override | |
84 public void readBytes(byte[] b, int off, int len) throws IOException { | |
85 if (count <= 0 || len > count) { | |
86 throw new IllegalArgumentException("Underflow"); // XXX be descriptive | |
87 } | |
88 if (count == length) { | |
89 dataAccess.seek(offset); | |
90 } | |
91 dataAccess.readBytes(b, off, len); | |
92 count -= len; | |
93 } | |
94 | |
95 // done shall be no-op, as we have no idea what's going on with DataAccess we filter | |
96 } |