1 23 package org.archive.io; 24 25 import java.io.BufferedReader ; 26 import java.io.BufferedWriter ; 27 import java.io.File ; 28 import java.io.FileInputStream ; 29 import java.io.FileNotFoundException ; 30 import java.io.FileOutputStream ; 31 import java.io.IOException ; 32 import java.io.InputStreamReader ; 33 import java.io.OutputStreamWriter ; 34 import java.io.Writer ; 35 import java.nio.ByteBuffer ; 36 import java.nio.CharBuffer ; 37 import java.nio.channels.FileChannel ; 38 import java.nio.charset.Charset ; 39 import java.nio.charset.CharsetDecoder ; 40 import java.nio.charset.CoderResult ; 41 import java.nio.charset.CodingErrorAction ; 42 import java.util.logging.Level ; 43 import java.util.logging.Logger ; 44 45 85 public class MultiByteReplayCharSequence implements ReplayCharSequence { 86 87 protected static Logger logger = 88 Logger.getLogger(MultiByteReplayCharSequence.class.getName()); 89 90 100 private static final String WRITE_ENCODING = "UTF-16BE"; 101 102 107 private CharBuffer content = null; 108 109 114 private File decodedFile = null; 115 116 117 137 public MultiByteReplayCharSequence(byte[] buffer, long size, 138 long responseBodyStart, String encoding) 139 throws IOException { 140 super(); 141 this.content = decodeInMemory(buffer, size, responseBodyStart, 142 encoding); 143 } 144 145 156 public MultiByteReplayCharSequence( 157 ReplayInputStream contentReplayInputStream, 158 String backingFilename, 159 String characterEncoding) 160 throws IOException { 161 super(); 162 this.content = decodeToFile(contentReplayInputStream, 163 backingFilename, characterEncoding); 164 } 165 166 192 private CharBuffer decodeToFile(ReplayInputStream inStream, 193 String backingFilename, String encoding) 194 throws IOException { 195 196 CharBuffer charBuffer = null; 197 198 BufferedReader reader = new BufferedReader ( 199 new InputStreamReader (inStream,encoding)); 200 201 this.decodedFile = new File (backingFilename + "." + WRITE_ENCODING); 202 BufferedWriter writer = new BufferedWriter ( 203 new OutputStreamWriter ( 204 new FileOutputStream (this.decodedFile), 205 WRITE_ENCODING)); 206 207 int c; 208 while((c = reader.read())>=0) { 209 writer.write(c); 210 } 211 writer.close(); 212 213 charBuffer = getReadOnlyMemoryMappedBuffer(this.decodedFile). 214 asCharBuffer(); 215 216 return charBuffer; 217 } 218 219 240 private CharBuffer decodeInMemory(byte[] buffer, long size, 241 long responseBodyStart, String encoding) 242 { 243 ByteBuffer bb = ByteBuffer.wrap(buffer); 244 bb.position((int)responseBodyStart); 246 bb.limit((int)size); 248 return (Charset.forName(encoding)).decode(bb).asReadOnlyBuffer(); 249 } 250 251 258 private ByteBuffer getReadOnlyMemoryMappedBuffer(File file) 259 throws IOException { 260 261 ByteBuffer bb = null; 262 FileInputStream in = null; 263 FileChannel c = null; 264 assert file.exists(): "No file " + file.getAbsolutePath(); 265 266 try { 267 in = new FileInputStream (file); 268 c = in.getChannel(); 269 bb = c.map(FileChannel.MapMode.READ_ONLY, 0, c.size()). 272 asReadOnlyBuffer(); 273 } 274 275 finally { 276 if (c != null && c.isOpen()) { 277 c.close(); 278 } 279 if (in != null) { 280 in.close(); 281 } 282 } 283 284 return bb; 285 } 286 287 private void deleteFile(File fileToDelete) { 288 deleteFile(fileToDelete, null); 289 } 290 291 private void deleteFile(File fileToDelete, final Exception e) { 292 if (e != null) { 293 logger.severe("Deleting " + fileToDelete + " because of " 296 + e.toString()); 297 } 298 if (fileToDelete != null && fileToDelete.exists()) { 299 fileToDelete.delete(); 300 } 301 } 302 303 public void close() 304 { 305 this.content = null; 306 deleteFile(this.decodedFile); 307 this.decodedFile = null; 311 } 312 313 protected void finalize() throws Throwable 314 { 315 super.finalize(); 316 close(); 318 } 319 320 public int length() 321 { 322 return this.content.limit(); 323 } 324 325 public char charAt(int index) 326 { 327 return this.content.get(index); 328 } 329 330 public CharSequence subSequence(int start, int end) { 331 return new CharSubSequence(this, start, end); 332 } 333 334 public String toString() { 335 StringBuffer sb = new StringBuffer (length()); 336 for (int i = 0;i<length();i++) { 338 sb.append(charAt(i)); 339 } 340 return sb.toString(); 341 } 342 } | Popular Tags |