diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java index 190556efc44..65261db4abe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FileCharArray.java @@ -54,6 +54,17 @@ public class FileCharArray extends LazyCharArray { char[] buf= extractChars(charBuffer); return new CharArray(buf); } + + private static char[] extractChars(CharBuffer charBuffer) { + if (charBuffer.hasArray() && charBuffer.arrayOffset() == 0) { + char[] buf = charBuffer.array(); + if (buf.length == charBuffer.remaining()) + return buf; + } + char[] buf = new char[charBuffer.remaining()]; + charBuffer.get(buf); + return buf; + } private String fFileName; private String fCharSet; @@ -88,7 +99,7 @@ public class FileCharArray extends LazyCharArray { } @Override - protected long readChunkData(long fileOffset, CharBuffer dest) throws IOException { + protected char[] readChunkData(long fileOffset, long[] fileEndOffsetHolder) throws IOException { assert fChannel != null; final Charset charset = Charset.forName(fCharSet); final CharsetDecoder decoder = charset.newDecoder().onMalformedInput(CodingErrorAction.REPLACE) @@ -96,29 +107,30 @@ public class FileCharArray extends LazyCharArray { int needBytes = (int) (CHUNK_SIZE * (double) decoder.averageCharsPerByte()); // avoid rounding errors. final ByteBuffer in = ByteBuffer.allocate(needBytes); + final CharBuffer dest= CharBuffer.allocate(CHUNK_SIZE); - int total= 0; boolean endOfInput= false; - while(total < CHUNK_SIZE && !endOfInput) { + while(dest.position() < CHUNK_SIZE && !endOfInput) { fChannel.position(fileOffset); in.clear(); int count= fChannel.read(in); if (count == -1) { - return fileOffset; + break; } endOfInput= count < in.capacity(); - total+= count; in.flip(); decoder.decode(in, dest, endOfInput); fileOffset+= in.position(); } - return fileOffset; + fileEndOffsetHolder[0]= fileOffset; + dest.flip(); + return extractChars(dest); } @Override - protected void rereadChunkData(long fileOffset, long fileEndOffset, CharBuffer dest) { + protected void rereadChunkData(long fileOffset, long fileEndOffset, char[] dest) { FileInputStream fis; try { fis = new FileInputStream(fFileName); @@ -128,7 +140,7 @@ public class FileCharArray extends LazyCharArray { } try { FileChannel channel = fis.getChannel(); - decode(channel, fileOffset, fileEndOffset, dest); + decode(channel, fileOffset, fileEndOffset, CharBuffer.wrap(dest)); } catch (IOException e) { // File cannot be read } finally { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LazyCharArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LazyCharArray.java index 30d73f6ef32..5b82731a3f0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LazyCharArray.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LazyCharArray.java @@ -11,7 +11,6 @@ package org.eclipse.cdt.internal.core.parser.scanner; import java.lang.ref.SoftReference; -import java.nio.CharBuffer; import java.util.ArrayList; import java.util.List; @@ -23,20 +22,6 @@ public abstract class LazyCharArray extends AbstractCharArray { private final static int CHUNK_BITS= 16; // 2^16 == 64K protected final static int CHUNK_SIZE= 1 << CHUNK_BITS; - /** - * Utility method to extract char[] out of CharBuffer. - */ - protected static char[] extractChars(CharBuffer charBuffer) { - if (charBuffer.hasArray() && charBuffer.arrayOffset() == 0) { - char[] buf = charBuffer.array(); - if (buf.length == charBuffer.remaining()) - return buf; - } - char[] buf = new char[charBuffer.remaining()]; - charBuffer.get(buf); - return buf; - } - protected static class Chunk { final int fDataLength; final long fFileOffset; @@ -77,7 +62,8 @@ public abstract class LazyCharArray extends AbstractCharArray { if (fLength >= 0) return offset < fLength; - return offset < fChunks.size() << CHUNK_BITS; + assert offset < fChunks.size() << CHUNK_BITS; + return true; } private void readUpTo(int offset) { @@ -140,23 +126,22 @@ public abstract class LazyCharArray extends AbstractCharArray { final int chunkCount = fChunks.size(); long fileOffset= chunkCount == 0 ? 0 : fChunks.get(chunkCount-1).fFileEndOffset; try { - CharBuffer dest= CharBuffer.allocate(CHUNK_SIZE); for (int i = chunkCount; i <= chunkOffset; i++) { - dest.clear(); - long fileEndOffset= readChunkData(fileOffset, dest); - dest.flip(); - final int charCount= dest.remaining(); + long[] fileEndOffset= {0}; + char[] data= readChunkData(fileOffset, fileEndOffset); + final int charCount= data.length; if (charCount == 0) { fLength= fChunks.size() * CHUNK_SIZE; break; } // New chunk - Chunk chunk= new Chunk(fileOffset, fileEndOffset, extractChars(dest)); + Chunk chunk= new Chunk(fileOffset, fileEndOffset[0], data); fChunks.add(chunk); if (charCount < CHUNK_SIZE) { fLength= (fChunks.size()-1) * CHUNK_SIZE + charCount; break; } + fileOffset= fileEndOffset[0]; } } catch (Exception e) { // File cannot be read @@ -170,16 +155,8 @@ public abstract class LazyCharArray extends AbstractCharArray { } private char[] loadChunkData(Chunk chunk) { - CharBuffer dest= CharBuffer.allocate(chunk.fDataLength); - rereadChunkData(chunk.fFileOffset, chunk.fFileEndOffset, dest); - dest.flip(); - char[] result= extractChars(dest); - if (result.length != chunk.fDataLength) { - // In case the file changed - char[] copy= new char[chunk.fDataLength]; - System.arraycopy(result, 0, copy, 0, Math.min(result.length, copy.length)); - result= copy; - } + char[] result= new char[chunk.fDataLength]; + rereadChunkData(chunk.fFileOffset, chunk.fFileEndOffset, result); chunk.fData= new SoftReference(result); return result; } @@ -188,11 +165,11 @@ public abstract class LazyCharArray extends AbstractCharArray { * Read the chunk data at the given source offset and provide the end-offset in the * source. */ - protected abstract long readChunkData(long sourceOffset, CharBuffer dest) throws Exception; + protected abstract char[] readChunkData(long sourceOffset, long[] sourceEndOffsetHolder) throws Exception; /** * Read the chunk data at the given source range. In case the source range no longer (fully) exists, * read as much as possible. */ - protected abstract void rereadChunkData(long fileOffset, long fileEndOffset, CharBuffer dest); + protected abstract void rereadChunkData(long fileOffset, long fileEndOffset, char[] dest); }