ClassFileNameHandler { @Nonnull static String shortenPathComponent(@Nonnull String pathComponent, int bytesToRemove) { bytesToRemove++; int[] codePoints; try { IntBuffer intBuffer = ByteBuffer.wrap(pathComponent.getBytes("UTF-32BE")).asIntBuffer(); codePoints = new int[intBuffer.limit()]; intBuffer.get(codePoints); } catch (UnsupportedEncodingException ex) { throw new RuntimeException(ex); } int midPoint = codePoints.length/2; int firstEnd = midPoint; int secondStart = midPoint+1; int bytesRemoved = utf8Length(codePoints[midPoint]); if (((codePoints.length % 2) == 0) && bytesRemoved < bytesToRemove) { bytesRemoved += utf8Length(codePoints[secondStart]); secondStart++; } while ((bytesRemoved < bytesToRemove) && (firstEnd > 0 || secondStart < codePoints.length)) { if (firstEnd > 0) { firstEnd--; bytesRemoved += utf8Length(codePoints[firstEnd]); } if (bytesRemoved < bytesToRemove && secondStart < codePoints.length) { bytesRemoved += utf8Length(codePoints[secondStart]); secondStart++; } } StringBuilder sb = new StringBuilder(); for (int i=0; i<firstEnd; i++) { sb.appendCodePoint(codePoints[i]); } sb.append('#'); for (int i=secondStart; i<codePoints.length; i++) { sb.appendCodePoint(codePoints[i]); } return sb.toString(); } ClassFileNameHandler(File path, String fileExtension);  ClassFileNameHandler(File path, String fileExtension, boolean caseSensitive,
                                boolean modifyWindowsReservedFilenames); File getUniqueFilenameForClass(String className);  }
@Test public void test1ByteEncodings() { StringBuilder sb = new StringBuilder(); for (int i=0; i<100; i++) { sb.append((char)i); } String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 5); Assert.assertEquals(95, result.getBytes(UTF8).length); Assert.assertEquals(95, result.length()); }
@Test public void test2ByteEncodings() { StringBuilder sb = new StringBuilder(); for (int i=0x80; i<0x80+100; i++) { sb.append((char)i); } String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 4); Assert.assertEquals(200, sb.toString().getBytes(UTF8).length); Assert.assertEquals(195, result.getBytes(UTF8).length); Assert.assertEquals(98, result.length()); result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 5); Assert.assertEquals(200, sb.toString().getBytes(UTF8).length); Assert.assertEquals(195, result.getBytes(UTF8).length); Assert.assertEquals(98, result.length()); }
@Test public void test3ByteEncodings() { StringBuilder sb = new StringBuilder(); for (int i=0x800; i<0x800+100; i++) { sb.append((char)i); } String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 6); Assert.assertEquals(300, sb.toString().getBytes(UTF8).length); Assert.assertEquals(292, result.getBytes(UTF8).length); Assert.assertEquals(98, result.length()); result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 7); Assert.assertEquals(300, sb.toString().getBytes(UTF8).length); Assert.assertEquals(292, result.getBytes(UTF8).length); Assert.assertEquals(98, result.length()); }
@Test public void test4ByteEncodings() { StringBuilder sb = new StringBuilder(); for (int i=0x10000; i<0x10000+100; i++) { sb.appendCodePoint(i); } String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 8); Assert.assertEquals(400, sb.toString().getBytes(UTF8).length); Assert.assertEquals(389, result.getBytes(UTF8).length); Assert.assertEquals(195, result.length()); result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 7); Assert.assertEquals(400, sb.toString().getBytes(UTF8).length); Assert.assertEquals(393, result.getBytes(UTF8).length); Assert.assertEquals(197, result.length()); }