KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > db > store > InodeBlobInputStream


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.db.store;
30
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33
34 /**
35  * Directly reading the blob from the inode.
36  */

37 public class InodeBlobInputStream extends InputStream JavaDoc {
38   private static final int INODE_DIRECT_BLOCKS = 14;
39     
40   private Store _store;
41
42   private long _length;
43   private long _offset;
44
45   private byte []_inode;
46   private int _inodeOffset;
47
48   private Block _block;
49   private byte []_buffer;
50   private int _bufferOffset;
51   private int _bufferEnd;
52   
53   /**
54    * Creates a blob output stream.
55    *
56    * @param store the output store
57    */

58   public InodeBlobInputStream(Store store, byte []inode, int inodeOffset)
59   {
60     init(store, inode, inodeOffset);
61   }
62   
63   /**
64    * Creates a blob output stream.
65    *
66    * @param store the output store
67    */

68   public InodeBlobInputStream(Inode inode)
69   {
70     init(inode.getStore(), inode.getBuffer(), 0);
71   }
72
73   /**
74    * Initialize the output stream.
75    */

76   public void init(Store store, byte []inode, int inodeOffset)
77   {
78     if (store == null)
79       throw new NullPointerException JavaDoc();
80     
81     _store = store;
82
83     _inode = inode;
84     _inodeOffset = inodeOffset;
85
86     _length = readLong(inode, inodeOffset);
87     _offset = 0;
88     
89     _block = null;
90
91     if (_length <= Inode.INLINE_BLOB_SIZE) {
92       _buffer = inode;
93       _bufferOffset = inodeOffset + 8;
94       _bufferEnd = (int) (_bufferOffset + _length);
95     }
96     else {
97       _buffer = null;
98       _bufferOffset = 0;
99       _bufferEnd = 0;
100     }
101   }
102
103   /**
104    * Reads a byte.
105    */

106   public int read()
107     throws IOException JavaDoc
108   {
109     if (_length <= _offset)
110       return -1;
111
112     if (_bufferEnd <= _bufferOffset)
113       readBlock();
114
115     _offset++;
116
117     return _buffer[_bufferOffset++] & 0xff;
118   }
119
120   /**
121    * Reads a buffer.
122    */

123   public int read(byte []buf, int offset, int length)
124     throws IOException JavaDoc
125   {
126     if (_length <= _offset)
127       return -1;
128
129     if (_bufferEnd <= _bufferOffset)
130       readBlock();
131
132     int sublen = _bufferEnd - _bufferOffset;
133     if (length < sublen)
134       sublen = length;
135
136     _offset += sublen;
137
138     System.arraycopy(_buffer, _bufferOffset, buf, offset, sublen);
139
140     _bufferOffset += sublen;
141
142     return sublen;
143   }
144
145   /**
146    * Closes the buffer.
147    */

148   public void close()
149   {
150     if (_block != null) {
151       Block block = _block;
152       _block = null;
153       block.free();
154     }
155   }
156
157   /**
158    * Updates the buffer.
159    */

160   public void readBlock()
161     throws IOException JavaDoc
162   {
163     if (_block != null) {
164       Block block = _block;
165       _block = null;
166       block.free();
167     }
168
169     long addr;
170
171     int blockCount = (int) (_offset / Store.BLOCK_SIZE);
172       
173     if (blockCount < INODE_DIRECT_BLOCKS) {
174       addr = readLong(_inode, _inodeOffset + 8 * (blockCount + 1));
175     }
176     else {
177       long ptrAddr = readLong(_inode,
178                   _inodeOffset + 8 * (INODE_DIRECT_BLOCKS + 1));
179
180       Block ptr = _store.readBlock(_store.addressToBlockId(ptrAddr));
181
182       addr = readLong(ptr.getBuffer(), 8 * (blockCount - INODE_DIRECT_BLOCKS));
183
184       ptr.free();
185     }
186
187     _block = _store.readBlock(_store.addressToBlockId(addr));
188     _buffer = _block.getBuffer();
189
190     int offset = (int) (addr & Store.BLOCK_OFFSET_MASK);
191
192     if (offset > 0) {
193       _bufferOffset = readShort(_buffer, offset);
194       _bufferEnd = _bufferOffset + readShort(_buffer, offset + 2);
195     }
196     else {
197       _bufferOffset = 0;
198       _bufferEnd = _buffer.length;
199     }
200   }
201
202   /**
203    * Writes the long.
204    */

205   public static long readLong(byte []buffer, int offset)
206   {
207     return (((buffer[offset + 0] & 0xffL) << 56) +
208         ((buffer[offset + 1] & 0xffL) << 48) +
209         ((buffer[offset + 2] & 0xffL) << 40) +
210         ((buffer[offset + 3] & 0xffL) << 32) +
211         ((buffer[offset + 4] & 0xffL) << 24) +
212         ((buffer[offset + 5] & 0xffL) << 16) +
213         ((buffer[offset + 6] & 0xffL) << 8) +
214         ((buffer[offset + 7] & 0xffL)));
215   }
216
217   /**
218    * Writes the short.
219    */

220   private static int readShort(byte []buffer, int offset)
221   {
222     return (((buffer[offset + 0] & 0xff) << 8) +
223         ((buffer[offset + 1] & 0xff)));
224   }
225 }
226
Popular Tags