1 24 25 package com.mckoi.util; 26 27 import java.io.InputStream ; 28 import java.io.IOException ; 29 30 41 42 public abstract class PagedInputStream extends InputStream { 43 44 47 private final int BUFFER_SIZE; 48 49 52 private long position; 53 54 57 private long size; 58 59 62 private long buffer_pos; 63 64 67 private final byte[] buf; 68 69 72 private long mark_position; 73 74 81 public PagedInputStream(int page_size, long total_size) { 82 this.BUFFER_SIZE = page_size; 83 this.position = 0; 84 this.size = total_size; 85 this.mark_position = 0; 86 this.buf = new byte[BUFFER_SIZE]; 87 buffer_pos = -1; 88 } 89 90 99 protected abstract void readPageContent(byte[] buf, long pos, int length) 100 throws IOException ; 101 102 106 private void fillBuffer(long pos) throws IOException { 107 final long read_pos = (pos / BUFFER_SIZE) * BUFFER_SIZE; 108 int to_read = (int) Math.min((long) BUFFER_SIZE, (size - read_pos)); 109 if (to_read > 0) { 110 readPageContent(buf, read_pos, to_read); 111 buffer_pos = read_pos; 112 } 113 } 114 115 117 public int read() throws IOException { 118 if (position >= size) { 119 return -1; 120 } 121 122 if (buffer_pos == -1) { 123 fillBuffer(position); 124 } 125 126 int p = (int) (position - buffer_pos); 127 int v = ((int) buf[p]) & 0x0FF; 128 129 ++position; 130 if (p + 1 >= BUFFER_SIZE) { 132 fillBuffer(buffer_pos + BUFFER_SIZE); 133 } 134 135 return v; 136 } 137 138 public int read(byte[] read_buf, int off, int len) throws IOException { 139 if (len <= 0) { 140 return 0; 141 } 142 143 if (buffer_pos == -1) { 144 fillBuffer(position); 145 } 146 147 int p = (int) (position - buffer_pos); 148 long buffer_end = Math.min(buffer_pos + BUFFER_SIZE, size); 149 int to_read = (int) Math.min((long) len, buffer_end - position); 150 if (to_read <= 0) { 151 return -1; 152 } 153 int has_read = 0; 154 while (to_read > 0) { 155 System.arraycopy(buf, p, read_buf, off, to_read); 156 has_read += to_read; 157 p += to_read; 158 off += to_read; 159 len -= to_read; 160 position += to_read; 161 if (p >= BUFFER_SIZE) { 162 fillBuffer(buffer_pos + BUFFER_SIZE); 163 p -= BUFFER_SIZE; 164 } 165 buffer_end = Math.min(buffer_pos + BUFFER_SIZE, size); 166 to_read = (int) Math.min((long) len, buffer_end - position); 167 } 168 return has_read; 169 } 170 171 public long skip(long n) throws IOException { 172 long act_skip = Math.min(n, size - position); 173 174 if (n < 0) { 175 throw new IOException ("Negative skip"); 176 } 177 position += act_skip; 178 if (buffer_pos == -1 || (position - buffer_pos) > BUFFER_SIZE) { 179 fillBuffer((position / BUFFER_SIZE) * BUFFER_SIZE); 180 } 181 182 return act_skip; 183 } 184 185 public int available() throws IOException { 186 return (int) Math.min((long) Integer.MAX_VALUE, (size - position)); 187 } 188 189 public void close() throws IOException { 190 } 191 192 public void mark(int limit) { 193 mark_position = position; 194 } 195 196 public void reset() { 197 position = mark_position; 198 long fill_pos = (position / BUFFER_SIZE) * BUFFER_SIZE; 199 if (fill_pos != buffer_pos) { 200 try { 201 fillBuffer(fill_pos); 202 } 203 catch (IOException e) { 204 throw new Error (e.getMessage()); 205 } 206 } 207 } 208 209 public boolean markSupported() { 210 return true; 211 } 212 213 } 214 215 | Popular Tags |