1 /*
2 * Copyright (C) 2010, Google Inc.
3 * and other copyright owners as documented in the project's IP log.
4 *
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 package org.eclipse.jgit.lib;
45
46 import java.io.IOException;
47 import java.io.InputStream;
48
49 /**
50 * Stream of data coming from an object loaded by {@link org.eclipse.jgit.lib.ObjectLoader}.
51 */
52 public abstract class ObjectStream extends InputStream {
53 /**
54 * Get Git object type, see {@link Constants}.
55 *
56 * @return Git object type, see {@link Constants}.
57 */
58 public abstract int getType();
59
60 /**
61 * Get total size of object in bytes
62 *
63 * @return total size of object in bytes
64 */
65 public abstract long getSize();
66
67 /**
68 * Simple stream around the cached byte array created by a loader.
69 * <p>
70 * ObjectLoader implementations can use this stream type when the object's
71 * content is small enough to be accessed as a single byte array, but the
72 * application has still requested it in stream format.
73 */
74 public static class SmallStream extends ObjectStream {
75 private final int type;
76
77 private final byte[] data;
78
79 private int ptr;
80
81 private int mark;
82
83 /**
84 * Create the stream from an existing loader's cached bytes.
85 *
86 * @param loader
87 * the loader.
88 */
89 public SmallStream(ObjectLoader loader) {
90 this(loader.getType(), loader.getCachedBytes());
91 }
92
93 /**
94 * Create the stream from an existing byte array and type.
95 *
96 *@param type
97 * the type constant for the object.
98 *@param data
99 * the fully inflated content of the object.
100 */
101 public SmallStream(int type, byte[] data) {
102 this.type = type;
103 this.data = data;
104 }
105
106 @Override
107 public int getType() {
108 return type;
109 }
110
111 @Override
112 public long getSize() {
113 return data.length;
114 }
115
116 @Override
117 public int available() {
118 return data.length - ptr;
119 }
120
121 @Override
122 public long skip(long n) {
123 int s = (int) Math.min(available(), Math.max(0, n));
124 ptr += s;
125 return s;
126 }
127
128 @Override
129 public int read() {
130 if (ptr == data.length)
131 return -1;
132 return data[ptr++] & 0xff;
133 }
134
135 @Override
136 public int read(byte[] b, int off, int len) {
137 if (ptr == data.length)
138 return -1;
139 int n = Math.min(available(), len);
140 System.arraycopy(data, ptr, b, off, n);
141 ptr += n;
142 return n;
143 }
144
145 @Override
146 public boolean markSupported() {
147 return true;
148 }
149
150 @Override
151 public void mark(int readlimit) {
152 mark = ptr;
153 }
154
155 @Override
156 public void reset() {
157 ptr = mark;
158 }
159 }
160
161 /**
162 * Simple filter stream around another stream.
163 * <p>
164 * ObjectLoader implementations can use this stream type when the object's
165 * content is available from a standard InputStream.
166 */
167 public static class Filter extends ObjectStream {
168 private final int type;
169
170 private final long size;
171
172 private final InputStream in;
173
174 /**
175 * Create a filter stream for an object.
176 *
177 * @param type
178 * the type of the object.
179 * @param size
180 * total size of the object, in bytes.
181 * @param in
182 * stream the object's raw data is available from. This
183 * stream should be buffered with some reasonable amount of
184 * buffering.
185 */
186 public Filter(int type, long size, InputStream in) {
187 this.type = type;
188 this.size = size;
189 this.in = in;
190 }
191
192 @Override
193 public int getType() {
194 return type;
195 }
196
197 @Override
198 public long getSize() {
199 return size;
200 }
201
202 @Override
203 public int available() throws IOException {
204 return in.available();
205 }
206
207 @Override
208 public long skip(long n) throws IOException {
209 return in.skip(n);
210 }
211
212 @Override
213 public int read() throws IOException {
214 return in.read();
215 }
216
217 @Override
218 public int read(byte[] b, int off, int len) throws IOException {
219 return in.read(b, off, len);
220 }
221
222 @Override
223 public boolean markSupported() {
224 return in.markSupported();
225 }
226
227 @Override
228 public void mark(int readlimit) {
229 in.mark(readlimit);
230 }
231
232 @Override
233 public void reset() throws IOException {
234 in.reset();
235 }
236
237 @Override
238 public void close() throws IOException {
239 in.close();
240 }
241 }
242 }