Remove System.out.println from RevWalkFilterTest
[egit/chris.git] / org.spearce.jgit / src / org / spearce / jgit / lib / WindowCursor.java
blob0723a785336e19fb8a5f848954cbaf501380210a
1 /*
2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
21 * written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org.spearce.jgit.lib;
40 import java.io.IOException;
41 import java.util.zip.DataFormatException;
42 import java.util.zip.Inflater;
44 /** Active handle to a ByteWindow. */
45 public final class WindowCursor {
46 /** Temporary buffer large enough for at least one raw object id. */
47 final byte[] tempId = new byte[Constants.OBJECT_ID_LENGTH];
49 private Inflater inf;
51 private ByteWindow window;
53 /**
54 * Copy bytes from the window to a caller supplied buffer.
56 * @param pack
57 * the file the desired window is stored within.
58 * @param position
59 * position within the file to read from.
60 * @param dstbuf
61 * destination buffer to copy into.
62 * @param dstoff
63 * offset within <code>dstbuf</code> to start copying into.
64 * @param cnt
65 * number of bytes to copy. This value may exceed the number of
66 * bytes remaining in the window starting at offset
67 * <code>pos</code>.
68 * @return number of bytes actually copied; this may be less than
69 * <code>cnt</code> if <code>cnt</code> exceeded the number of
70 * bytes available.
71 * @throws IOException
72 * this cursor does not match the provider or id and the proper
73 * window could not be acquired through the provider's cache.
75 int copy(final PackFile pack, long position, final byte[] dstbuf,
76 int dstoff, final int cnt) throws IOException {
77 final long length = pack.length;
78 int need = cnt;
79 while (need > 0 && position < length) {
80 pin(pack, position);
81 final int r = window.copy(position, dstbuf, dstoff, need);
82 position += r;
83 dstoff += r;
84 need -= r;
86 return cnt - need;
89 /**
90 * Pump bytes into the supplied inflater as input.
92 * @param pack
93 * the file the desired window is stored within.
94 * @param position
95 * position within the file to read from.
96 * @param dstbuf
97 * destination buffer the inflater should output decompressed
98 * data to.
99 * @param dstoff
100 * current offset within <code>dstbuf</code> to inflate into.
101 * @return updated <code>dstoff</code> based on the number of bytes
102 * successfully inflated into <code>dstbuf</code>.
103 * @throws IOException
104 * this cursor does not match the provider or id and the proper
105 * window could not be acquired through the provider's cache.
106 * @throws DataFormatException
107 * the inflater encountered an invalid chunk of data. Data
108 * stream corruption is likely.
110 int inflate(final PackFile pack, long position, final byte[] dstbuf,
111 int dstoff) throws IOException, DataFormatException {
112 if (inf == null)
113 inf = InflaterCache.get();
114 else
115 inf.reset();
116 for (;;) {
117 pin(pack, position);
118 dstoff = window.inflate(position, dstbuf, dstoff, inf);
119 if (inf.finished())
120 return dstoff;
121 position = window.end;
125 void inflateVerify(final PackFile pack, long position)
126 throws IOException, DataFormatException {
127 if (inf == null)
128 inf = InflaterCache.get();
129 else
130 inf.reset();
131 for (;;) {
132 pin(pack, position);
133 window.inflateVerify(position, inf);
134 if (inf.finished())
135 return;
136 position = window.end;
140 private void pin(final PackFile pack, final long position)
141 throws IOException {
142 final ByteWindow w = window;
143 if (w == null || !w.contains(pack, position)) {
144 // If memory is low, we may need what is in our window field to
145 // be cleaned up by the GC during the get for the next window.
146 // So we always clear it, even though we are just going to set
147 // it again.
149 window = null;
150 window = WindowCache.get(pack, position);
154 /** Release the current window cursor. */
155 public void release() {
156 window = null;
157 try {
158 InflaterCache.release(inf);
159 } finally {
160 inf = null;
165 * @param curs cursor to release; may be null.
166 * @return always null.
168 public static WindowCursor release(final WindowCursor curs) {
169 if (curs != null)
170 curs.release();
171 return null;