1 28 29 package com.caucho.db.store; 30 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 34 37 public class InodeBlobInputStream extends InputStream { 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 58 public InodeBlobInputStream(Store store, byte []inode, int inodeOffset) 59 { 60 init(store, inode, inodeOffset); 61 } 62 63 68 public InodeBlobInputStream(Inode inode) 69 { 70 init(inode.getStore(), inode.getBuffer(), 0); 71 } 72 73 76 public void init(Store store, byte []inode, int inodeOffset) 77 { 78 if (store == null) 79 throw new NullPointerException (); 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 106 public int read() 107 throws IOException 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 123 public int read(byte []buf, int offset, int length) 124 throws IOException 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 148 public void close() 149 { 150 if (_block != null) { 151 Block block = _block; 152 _block = null; 153 block.free(); 154 } 155 } 156 157 160 public void readBlock() 161 throws IOException 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 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 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 |