View | Details | Raw Unified | Return to bug 149028 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/util/Util.java (-85 / +40 lines)
Lines 155-187 Link Here
155
155
156
		return contents;
156
		return contents;
157
	}
157
	}
158
	/*
158
	
159
	 * NIO support to get input stream as char array.
160
	 * Not used as with JDK 1.4.2 this support is slower than standard IO one...
161
	 * Keep it as comment for future in case of next JDK versions improve performance
162
	 * in this area...
163
	public static char[] getInputStreamAsCharArray(FileInputStream stream, int length, String encoding)
164
		throws IOException {
165
		
166
		FileChannel channel = stream.getChannel();
167
		int size = (int)channel.size();
168
		if (length >= 0 && length < size) size = length;
169
		Charset charset = encoding==null?systemCharset:Charset.forName(encoding);
170
		if (charset != null) {
171
			MappedByteBuffer bbuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
172
		    CharsetDecoder decoder = charset.newDecoder();
173
		    CharBuffer buffer = decoder.decode(bbuffer);
174
		    char[] contents = new char[buffer.limit()];
175
		    buffer.get(contents);
176
		    return contents;
177
		}
178
		throw new UnsupportedCharsetException(SYSTEM_FILE_ENCODING);
179
	}
180
	*/
181
	/**
159
	/**
182
	 * Returns the given input stream's contents as a character array.
160
	 * Returns the given input stream's contents as a character array.
183
	 * If a length is specified (ie. if length != -1), only length chars
161
	 * If a length is specified (ie. if length != -1), this represents the number of bytes in the stream.
184
	 * are returned. Otherwise all chars in the stream are returned.
185
	 * Note this doesn't close the stream.
162
	 * Note this doesn't close the stream.
186
	 * @throws IOException if a problem occured reading the stream.
163
	 * @throws IOException if a problem occured reading the stream.
187
	 */
164
	 */
Lines 197-269 Link Here
197
			reader =  new InputStreamReader(stream);
174
			reader =  new InputStreamReader(stream);
198
		}
175
		}
199
		char[] contents;
176
		char[] contents;
177
		int totalRead = 0;
200
		if (length == -1) {
178
		if (length == -1) {
201
			contents = CharOperation.NO_CHAR;
179
			contents = CharOperation.NO_CHAR;
202
			int contentsLength = 0;
180
		} else {
203
			int amountRead = -1;
181
			// length is a good guess when the encoding produces less or the same amount of characters than the file length
204
			do {
182
			contents = new char[length]; // best guess
205
				int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
183
		}
206
184
185
		while (true) {
186
			int amountRequested;
187
			if (totalRead < length) {
188
				// until known length is met, reuse same array sized eagerly
189
				amountRequested = length - totalRead;
190
			} else {
191
				// reading beyond known length
192
				int current = reader.read(); 
193
				if (current < 0) break;
194
				
195
				amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
196
				
207
				// resize contents if needed
197
				// resize contents if needed
208
				if (contentsLength + amountRequested > contents.length) {
198
				if (totalRead + 1 + amountRequested > contents.length)
209
					System.arraycopy(
199
					System.arraycopy(contents, 	0, 	contents = new char[totalRead + 1 + amountRequested], 0, totalRead);
210
						contents,
200
				
211
						0,
201
				// add current character
212
						contents = new char[contentsLength + amountRequested],
202
				contents[totalRead++] = (char) current; // coming from totalRead==length
213
						0,
214
						contentsLength);
215
				}
216
217
				// read as many chars as possible
218
				amountRead = reader.read(contents, contentsLength, amountRequested);
219
220
				if (amountRead > 0) {
221
					// remember length of contents
222
					contentsLength += amountRead;
223
				}
224
			} while (amountRead != -1);
225
226
			// Do not keep first character for UTF-8 BOM encoding
227
			int start = 0;
228
			if (contentsLength > 0 && UTF_8.equals(encoding)) {
229
				if (contents[0] == 0xFEFF) { // if BOM char then skip
230
					contentsLength--;
231
					start = 1;
232
				}
233
			}
234
			// resize contents if necessary
235
			if (contentsLength < contents.length) {
236
				System.arraycopy(
237
					contents,
238
					start,
239
					contents = new char[contentsLength],
240
					0,
241
					contentsLength);
242
			}
243
		} else {
244
			contents = new char[length];
245
			int len = 0;
246
			int readSize = 0;
247
			while ((readSize != -1) && (len != length)) {
248
				// See PR 1FMS89U
249
				// We record first the read size. In this case len is the actual read size.
250
				len += readSize;
251
				readSize = reader.read(contents, len, length - len);
252
			}
203
			}
253
			// Do not keep first character for UTF-8 BOM encoding
204
			// read as many chars as possible
254
			int start = 0;
205
			int amountRead = reader.read(contents, totalRead, amountRequested);
255
			if (length > 0 && UTF_8.equals(encoding)) {
206
			if (amountRead < 0) break;
256
				if (contents[0] == 0xFEFF) { // if BOM char then skip
207
			totalRead += amountRead;
257
					len--;
208
		}
258
					start = 1;
209
259
				}
210
		// Do not keep first character for UTF-8 BOM encoding
211
		int start = 0;
212
		if (totalRead > 0 && UTF_8.equals(encoding)) {
213
			if (contents[0] == 0xFEFF) { // if BOM char then skip
214
				totalRead--;
215
				start = 1;
260
			}
216
			}
261
			// See PR 1FMS89U
262
			// Now we need to resize in case the default encoding used more than one byte for each
263
			// character
264
			if (len != length)
265
				System.arraycopy(contents, start, (contents = new char[len]), 0, len);
266
		}
217
		}
218
		
219
		// resize contents if necessary
220
		if (totalRead < contents.length)
221
			System.arraycopy(contents, start, contents = new char[totalRead], 	0, 	totalRead);
267
222
268
		return contents;
223
		return contents;
269
	}
224
	}
(-)src/org/eclipse/jdt/core/tests/model/EncodingTests.java (+45 lines)
Lines 12-17 Link Here
12
12
13
import java.io.File;
13
import java.io.File;
14
import java.io.IOException;
14
import java.io.IOException;
15
import java.io.InputStream;
15
import java.io.UnsupportedEncodingException;
16
import java.io.UnsupportedEncodingException;
16
17
17
import junit.framework.Test;
18
import junit.framework.Test;
Lines 672-677 Link Here
672
		}
673
		}
673
	}
674
	}
674
675
676
	/*
677
	 * Ensures that an encoding that a file using an encoding producing more charaters than the file size can
678
	 * be correctly read.
679
	 * (regression test for bug 149028 Limiting number of characters to read with the file size is invalid.)
680
	 */
681
	public void test034() throws CoreException, IOException {
682
		try {
683
			// Create file
684
			IFile file = createFile("/Encoding/Test34.txt", "acegikm");
685
			
686
			// Read file using a transformation where a character is read and the next alphabetical character is
687
			// automaticaly added
688
			final InputStream fileStream = file.getContents();
689
			try {
690
				InputStream in = new InputStream() {
691
					int current = -1;
692
					public int read() throws IOException {
693
						int result;
694
						if (current != -1) {
695
							result = current;
696
							current = -1;
697
						} else {
698
							result = fileStream.read();
699
							if (result == -1)
700
								return -1;
701
							current = result + 1;
702
						}
703
						return result;
704
					}
705
				};
706
				char[] result = org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsCharArray(in, (int) file.getLocation().toFile().length(), "UTF-8");
707
				assertSourceEquals(
708
					"Unexpected source",
709
					"abcdefghijklmn",
710
					new String(result)					
711
				);
712
			} finally {
713
				fileStream.close();
714
			}
715
		} finally {
716
			deleteFile("Encoding/Test34.txt");
717
		}
718
	}	
719
	
675
	/**
720
	/**
676
	 * Bug 66898: refactor-rename: encoding is not preserved
721
	 * Bug 66898: refactor-rename: encoding is not preserved
677
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=66898"
722
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=66898"

Return to bug 149028