Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
ライブエディター
未変更行を折りたたむ
折り返しなし
レイアウト
分割
統合
比較精度
スマート
単語
文字
シンタックスハイライト
構文を選択
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
Vul4j-8_diff
作成日
3 年前
差分は期限切れになりません
クリア
エクスポート
共有
説明
55 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
217 行
すべてコピー
24 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
199 行
すべてコピー
/*
/*
* Licensed to the Apache Software Foundation (ASF) under one
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* with the License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing,
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* specific language governing permissions and limitations
* under the License.
* under the License.
*/
*/
package org.apache.commons.compress.archivers.zip;
package org.apache.commons.compress.archivers.zip;
import java.io.IOException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CodingErrorAction;
/**
/**
* A ZipEncoding, which uses a java.nio {@link
* A ZipEncoding, which uses a java.nio {@link
* java.nio.charset.Charset Charset} to encode names.
* java.nio.charset.Charset Charset} to encode names.
* <p>The methods of this class are reentrant.</p>
* <p>The methods of this class are reentrant.</p>
* @Immutable
* @Immutable
*/
*/
class NioZipEncoding implements ZipEncoding, CharsetAccessor {
class NioZipEncoding implements ZipEncoding, CharsetAccessor {
private final Charset charset;
private final Charset charset;
private final boolean useReplacement;
private final boolean useReplacement;
private static final char REPLACEMENT = '?';
private static final char REPLACEMENT = '?';
private static final byte[] REPLACEMENT_BYTES = { (byte) REPLACEMENT };
private static final byte[] REPLACEMENT_BYTES = { (byte) REPLACEMENT };
private static final String REPLACEMENT_STRING = String.valueOf(REPLACEMENT);
private static final String REPLACEMENT_STRING = String.valueOf(REPLACEMENT);
private static final char[] HEX_CHARS = new char[] {
private static final char[] HEX_CHARS = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
};
/**
/**
* Construct an NioZipEncoding using the given charset.
* Construct an NioZipEncoding using the given charset.
* @param charset The character set to use.
* @param charset The character set to use.
* @param useReplacement should invalid characters be replaced, or reported.
* @param useReplacement should invalid characters be replaced, or reported.
*/
*/
NioZipEncoding(final Charset charset, boolean useReplacement) {
NioZipEncoding(final Charset charset, boolean useReplacement) {
this.charset = charset;
this.charset = charset;
this.useReplacement = useReplacement;
this.useReplacement = useReplacement;
}
}
@Override
@Override
public Charset getCharset() {
public Charset getCharset() {
return charset;
return charset;
}
}
/**
/**
* @see ZipEncoding#canEncode(java.lang.String)
* @see ZipEncoding#canEncode(java.lang.String)
*/
*/
@Override
@Override
public boolean canEncode(final String name) {
public boolean canEncode(final String name) {
final CharsetEncoder enc = newEncoder();
final CharsetEncoder enc = newEncoder();
return enc.canEncode(name);
return enc.canEncode(name);
}
}
コピー
コピー済み
コピー
コピー済み
/**
@Override
* @see ZipEncoding#encode(java.lang.String)
public ByteBuffer encode(final String name) {
*/
final CharsetEncoder enc = newEncoder();
@Override
final CharBuffer cb = CharBuffer.wrap(name);
public ByteBuffer encode(final String name) {
CharBuffer tmp = null;
final CharsetEncoder enc = newEncoder();
ByteBuffer out = ByteBuffer.allocate(estimateInitialBufferSize(enc, cb.remaining()));
CoderResult res = null;
final CharBuffer cb = CharBuffer.wrap(name);
while (cb.remaining() > 0
|| (
res = enc.encode(cb, out, false)
).isOverflow()) {
CharBuffer tmp = null;
if (res != null &&
(res.isUnmappable() || res.isMalformed()
)) {
ByteBuffer out = ByteBuffer.allocate(estimateInitialBufferSize(enc, cb.remaining()));
int spaceForSurrogate = estimateIncrementalEncodingSize(enc, 6 * res.length());
if (spaceForSurrogate > out.remaining()) {
while (cb.remaining() > 0
) {
int charCount = 0;
final CoderResult
res = enc.encode(cb, out, false)
;
for (int i = cb.position()
; i < cb.limit(); i++) {
charCount += !enc.canEncode(cb.get(i)) ? 6 : 1;
if
(res.isUnmappable() || res.isMalformed()
) {
// write the unmappable characters in utf-16
// pseudo-URL encoding style to ByteBuffer.
int spaceForSurrogate = estimateIncrementalEncodingSize(enc, 6 * res.length());
if (spaceForSurrogate > out.remaining()) {
// if the destination buffer isn't over sized, assume that the presence of one
// unmappable character makes it likely that there will be more. Find all the
// un-encoded characters and allocate space based on those estimates.
int charCount = 0;
for (int i = cb.position()
; i < cb.limit(); i++) {
charCount += !enc.canEncode(cb.get(i)) ? 6 : 1;
}
int totalExtraSpace = estimateIncrementalEncodingSize(enc, charCount);
out = ZipEncodingHelper.growBufferBy(out, totalExtraSpace - out.remaining());
}
if (tmp == null) {
tmp = CharBuffer.allocate(6);
}
for (int i = 0; i < res.length(); ++i) {
out = encodeFully(enc, encodeSurrogate(tmp, cb.get()), out);
}
}
コピー
コピー済み
コピー
コピー済み
int
totalExtraSpace
= estimateIncrementalEncodingSize(enc,
charCount
);
} else if (res.isOverflow()) {
out = ZipEncodingHelper.growBufferBy(out,
totalExtraSpace - out.remaining());
int
increment
= estimateIncrementalEncodingSize(enc,
cb.remaining()
);
}
out = ZipEncodingHelper.growBufferBy(out,
increment);
if (tmp == null) {
tmp = CharBuffer.allocate(6);
}
for (int i = 0; i < res.length(); ++i) {
out = encodeFully(enc, encodeSurrogate(tmp, cb.get()), out);
}
}
コピー
コピー済み
コピー
コピー済み
} else if (res != null && res.isOverflow()) {
int increment = estimateIncrementalEncodingSize(enc, cb.remaining());
out = ZipEncodingHelper.growBufferBy(out, increment);
}
}
コピー
コピー済み
コピー
コピー済み
// tell the encoder we are done
enc.encode(cb, out, true);
// may have caused underflow, but that's been ignored traditionally
out.limit(out.position());
out.rewind();
return out;
}
}
コピー
コピー済み
コピー
コピー済み
enc.encode(cb, out, true);
out.limit(out.position());
out.rewind();
return out;
}
/**
/**
* @see
* @see
* ZipEncoding#decode(byte[])
* ZipEncoding#decode(byte[])
*/
*/
@Override
@Override
public String decode(final byte[] data) throws IOException {
public String decode(final byte[] data) throws IOException {
return newDecoder()
return newDecoder()
.decode(ByteBuffer.wrap(data)).toString();
.decode(ByteBuffer.wrap(data)).toString();
}
}
private static ByteBuffer encodeFully(CharsetEncoder enc, CharBuffer cb, ByteBuffer out) {
private static ByteBuffer encodeFully(CharsetEncoder enc, CharBuffer cb, ByteBuffer out) {
ByteBuffer o = out;
ByteBuffer o = out;
while (cb.hasRemaining()) {
while (cb.hasRemaining()) {
CoderResult result = enc.encode(cb, o, false);
CoderResult result = enc.encode(cb, o, false);
if (result.isOverflow()) {
if (result.isOverflow()) {
int increment = estimateIncrementalEncodingSize(enc, cb.remaining());
int increment = estimateIncrementalEncodingSize(enc, cb.remaining());
o = ZipEncodingHelper.growBufferBy(o, increment);
o = ZipEncodingHelper.growBufferBy(o, increment);
}
}
}
}
return o;
return o;
}
}
private static CharBuffer encodeSurrogate(CharBuffer cb, char c) {
private static CharBuffer encodeSurrogate(CharBuffer cb, char c) {
cb.position(0).limit(6);
cb.position(0).limit(6);
cb.put('%');
cb.put('%');
cb.put('U');
cb.put('U');
cb.put(HEX_CHARS[(c >> 12) & 0x0f]);
cb.put(HEX_CHARS[(c >> 12) & 0x0f]);
cb.put(HEX_CHARS[(c >> 8) & 0x0f]);
cb.put(HEX_CHARS[(c >> 8) & 0x0f]);
cb.put(HEX_CHARS[(c >> 4) & 0x0f]);
cb.put(HEX_CHARS[(c >> 4) & 0x0f]);
cb.put(HEX_CHARS[c & 0x0f]);
cb.put(HEX_CHARS[c & 0x0f]);
cb.flip();
cb.flip();
return cb;
return cb;
}
}
private CharsetEncoder newEncoder() {
private CharsetEncoder newEncoder() {
if (useReplacement) {
if (useReplacement) {
return charset.newEncoder()
return charset.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(REPLACEMENT_BYTES);
.replaceWith(REPLACEMENT_BYTES);
} else {
} else {
return charset.newEncoder()
return charset.newEncoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
.onUnmappableCharacter(CodingErrorAction.REPORT);
}
}
}
}
private CharsetDecoder newDecoder() {
private CharsetDecoder newDecoder() {
if (!useReplacement) {
if (!useReplacement) {
return this.charset.newDecoder()
return this.charset.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
.onUnmappableCharacter(CodingErrorAction.REPORT);
} else {
} else {
return charset.newDecoder()
return charset.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(REPLACEMENT_STRING);
.replaceWith(REPLACEMENT_STRING);
}
}
}
}
/**
/**
* Estimate the initial encoded size (in bytes) for a character buffer.
* Estimate the initial encoded size (in bytes) for a character buffer.
* <p>
* <p>
* The estimate assumes that one character consumes uses the maximum length encoding,
* The estimate assumes that one character consumes uses the maximum length encoding,
* whilst the rest use an average size encoding. This accounts for any BOM for UTF-16, at
* whilst the rest use an average size encoding. This accounts for any BOM for UTF-16, at
* the expense of a couple of extra bytes for UTF-8 encoded ASCII.
* the expense of a couple of extra bytes for UTF-8 encoded ASCII.
* </p>
* </p>
*
*
* @param enc encoder to use for estimates
* @param enc encoder to use for estimates
* @param charChount number of characters in string
* @param charChount number of characters in string
* @return estimated size in bytes.
* @return estimated size in bytes.
*/
*/
private static int estimateInitialBufferSize(CharsetEncoder enc, int charChount) {
private static int estimateInitialBufferSize(CharsetEncoder enc, int charChount) {
float first = enc.maxBytesPerChar();
float first = enc.maxBytesPerChar();
float rest = (charChount - 1) * enc.averageBytesPerChar();
float rest = (charChount - 1) * enc.averageBytesPerChar();
return (int) Math.ceil(first + rest);
return (int) Math.ceil(first + rest);
}
}
/**
/**
* Estimate the size needed for remaining characters
* Estimate the size needed for remaining characters
*
*
* @param enc encoder to use for estimates
* @param enc encoder to use for estimates
* @param charCount number of characters remaining
* @param charCount number of characters remaining
* @return estimated size in bytes.
* @return estimated size in bytes.
*/
*/
private static int estimateIncrementalEncodingSize(CharsetEncoder enc, int charCount) {
private static int estimateIncrementalEncodingSize(CharsetEncoder enc, int charCount) {
return (int) Math.ceil(charCount * enc.averageBytesPerChar());
return (int) Math.ceil(charCount * enc.averageBytesPerChar());
}
}
}
}
保存された差分
原文
ファイルを開く
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.commons.compress.archivers.zip; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * A ZipEncoding, which uses a java.nio {@link * java.nio.charset.Charset Charset} to encode names. * <p>The methods of this class are reentrant.</p> * @Immutable */ class NioZipEncoding implements ZipEncoding, CharsetAccessor { private final Charset charset; private final boolean useReplacement; private static final char REPLACEMENT = '?'; private static final byte[] REPLACEMENT_BYTES = { (byte) REPLACEMENT }; private static final String REPLACEMENT_STRING = String.valueOf(REPLACEMENT); private static final char[] HEX_CHARS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * Construct an NioZipEncoding using the given charset. * @param charset The character set to use. * @param useReplacement should invalid characters be replaced, or reported. */ NioZipEncoding(final Charset charset, boolean useReplacement) { this.charset = charset; this.useReplacement = useReplacement; } @Override public Charset getCharset() { return charset; } /** * @see ZipEncoding#canEncode(java.lang.String) */ @Override public boolean canEncode(final String name) { final CharsetEncoder enc = newEncoder(); return enc.canEncode(name); } /** * @see ZipEncoding#encode(java.lang.String) */ @Override public ByteBuffer encode(final String name) { final CharsetEncoder enc = newEncoder(); final CharBuffer cb = CharBuffer.wrap(name); CharBuffer tmp = null; ByteBuffer out = ByteBuffer.allocate(estimateInitialBufferSize(enc, cb.remaining())); while (cb.remaining() > 0) { final CoderResult res = enc.encode(cb, out, false); if (res.isUnmappable() || res.isMalformed()) { // write the unmappable characters in utf-16 // pseudo-URL encoding style to ByteBuffer. int spaceForSurrogate = estimateIncrementalEncodingSize(enc, 6 * res.length()); if (spaceForSurrogate > out.remaining()) { // if the destination buffer isn't over sized, assume that the presence of one // unmappable character makes it likely that there will be more. Find all the // un-encoded characters and allocate space based on those estimates. int charCount = 0; for (int i = cb.position() ; i < cb.limit(); i++) { charCount += !enc.canEncode(cb.get(i)) ? 6 : 1; } int totalExtraSpace = estimateIncrementalEncodingSize(enc, charCount); out = ZipEncodingHelper.growBufferBy(out, totalExtraSpace - out.remaining()); } if (tmp == null) { tmp = CharBuffer.allocate(6); } for (int i = 0; i < res.length(); ++i) { out = encodeFully(enc, encodeSurrogate(tmp, cb.get()), out); } } else if (res.isOverflow()) { int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); out = ZipEncodingHelper.growBufferBy(out, increment); } } // tell the encoder we are done enc.encode(cb, out, true); // may have caused underflow, but that's been ignored traditionally out.limit(out.position()); out.rewind(); return out; } /** * @see * ZipEncoding#decode(byte[]) */ @Override public String decode(final byte[] data) throws IOException { return newDecoder() .decode(ByteBuffer.wrap(data)).toString(); } private static ByteBuffer encodeFully(CharsetEncoder enc, CharBuffer cb, ByteBuffer out) { ByteBuffer o = out; while (cb.hasRemaining()) { CoderResult result = enc.encode(cb, o, false); if (result.isOverflow()) { int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); o = ZipEncodingHelper.growBufferBy(o, increment); } } return o; } private static CharBuffer encodeSurrogate(CharBuffer cb, char c) { cb.position(0).limit(6); cb.put('%'); cb.put('U'); cb.put(HEX_CHARS[(c >> 12) & 0x0f]); cb.put(HEX_CHARS[(c >> 8) & 0x0f]); cb.put(HEX_CHARS[(c >> 4) & 0x0f]); cb.put(HEX_CHARS[c & 0x0f]); cb.flip(); return cb; } private CharsetEncoder newEncoder() { if (useReplacement) { return charset.newEncoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith(REPLACEMENT_BYTES); } else { return charset.newEncoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); } } private CharsetDecoder newDecoder() { if (!useReplacement) { return this.charset.newDecoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); } else { return charset.newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith(REPLACEMENT_STRING); } } /** * Estimate the initial encoded size (in bytes) for a character buffer. * <p> * The estimate assumes that one character consumes uses the maximum length encoding, * whilst the rest use an average size encoding. This accounts for any BOM for UTF-16, at * the expense of a couple of extra bytes for UTF-8 encoded ASCII. * </p> * * @param enc encoder to use for estimates * @param charChount number of characters in string * @return estimated size in bytes. */ private static int estimateInitialBufferSize(CharsetEncoder enc, int charChount) { float first = enc.maxBytesPerChar(); float rest = (charChount - 1) * enc.averageBytesPerChar(); return (int) Math.ceil(first + rest); } /** * Estimate the size needed for remaining characters * * @param enc encoder to use for estimates * @param charCount number of characters remaining * @return estimated size in bytes. */ private static int estimateIncrementalEncodingSize(CharsetEncoder enc, int charCount) { return (int) Math.ceil(charCount * enc.averageBytesPerChar()); } }
変更されたテキスト
ファイルを開く
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.commons.compress.archivers.zip; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * A ZipEncoding, which uses a java.nio {@link * java.nio.charset.Charset Charset} to encode names. * <p>The methods of this class are reentrant.</p> * @Immutable */ class NioZipEncoding implements ZipEncoding, CharsetAccessor { private final Charset charset; private final boolean useReplacement; private static final char REPLACEMENT = '?'; private static final byte[] REPLACEMENT_BYTES = { (byte) REPLACEMENT }; private static final String REPLACEMENT_STRING = String.valueOf(REPLACEMENT); private static final char[] HEX_CHARS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * Construct an NioZipEncoding using the given charset. * @param charset The character set to use. * @param useReplacement should invalid characters be replaced, or reported. */ NioZipEncoding(final Charset charset, boolean useReplacement) { this.charset = charset; this.useReplacement = useReplacement; } @Override public Charset getCharset() { return charset; } /** * @see ZipEncoding#canEncode(java.lang.String) */ @Override public boolean canEncode(final String name) { final CharsetEncoder enc = newEncoder(); return enc.canEncode(name); } @Override public ByteBuffer encode(final String name) { final CharsetEncoder enc = newEncoder(); final CharBuffer cb = CharBuffer.wrap(name); CharBuffer tmp = null; ByteBuffer out = ByteBuffer.allocate(estimateInitialBufferSize(enc, cb.remaining())); CoderResult res = null; while (cb.remaining() > 0 || (res = enc.encode(cb, out, false)).isOverflow()) { if (res != null && (res.isUnmappable() || res.isMalformed())) { int spaceForSurrogate = estimateIncrementalEncodingSize(enc, 6 * res.length()); if (spaceForSurrogate > out.remaining()) { int charCount = 0; for (int i = cb.position(); i < cb.limit(); i++) { charCount += !enc.canEncode(cb.get(i)) ? 6 : 1; } int totalExtraSpace = estimateIncrementalEncodingSize(enc, charCount); out = ZipEncodingHelper.growBufferBy(out, totalExtraSpace - out.remaining()); } if (tmp == null) { tmp = CharBuffer.allocate(6); } for (int i = 0; i < res.length(); ++i) { out = encodeFully(enc, encodeSurrogate(tmp, cb.get()), out); } } else if (res != null && res.isOverflow()) { int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); out = ZipEncodingHelper.growBufferBy(out, increment); } } enc.encode(cb, out, true); out.limit(out.position()); out.rewind(); return out; } /** * @see * ZipEncoding#decode(byte[]) */ @Override public String decode(final byte[] data) throws IOException { return newDecoder() .decode(ByteBuffer.wrap(data)).toString(); } private static ByteBuffer encodeFully(CharsetEncoder enc, CharBuffer cb, ByteBuffer out) { ByteBuffer o = out; while (cb.hasRemaining()) { CoderResult result = enc.encode(cb, o, false); if (result.isOverflow()) { int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); o = ZipEncodingHelper.growBufferBy(o, increment); } } return o; } private static CharBuffer encodeSurrogate(CharBuffer cb, char c) { cb.position(0).limit(6); cb.put('%'); cb.put('U'); cb.put(HEX_CHARS[(c >> 12) & 0x0f]); cb.put(HEX_CHARS[(c >> 8) & 0x0f]); cb.put(HEX_CHARS[(c >> 4) & 0x0f]); cb.put(HEX_CHARS[c & 0x0f]); cb.flip(); return cb; } private CharsetEncoder newEncoder() { if (useReplacement) { return charset.newEncoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith(REPLACEMENT_BYTES); } else { return charset.newEncoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); } } private CharsetDecoder newDecoder() { if (!useReplacement) { return this.charset.newDecoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); } else { return charset.newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith(REPLACEMENT_STRING); } } /** * Estimate the initial encoded size (in bytes) for a character buffer. * <p> * The estimate assumes that one character consumes uses the maximum length encoding, * whilst the rest use an average size encoding. This accounts for any BOM for UTF-16, at * the expense of a couple of extra bytes for UTF-8 encoded ASCII. * </p> * * @param enc encoder to use for estimates * @param charChount number of characters in string * @return estimated size in bytes. */ private static int estimateInitialBufferSize(CharsetEncoder enc, int charChount) { float first = enc.maxBytesPerChar(); float rest = (charChount - 1) * enc.averageBytesPerChar(); return (int) Math.ceil(first + rest); } /** * Estimate the size needed for remaining characters * * @param enc encoder to use for estimates * @param charCount number of characters remaining * @return estimated size in bytes. */ private static int estimateIncrementalEncodingSize(CharsetEncoder enc, int charCount) { return (int) Math.ceil(charCount * enc.averageBytesPerChar()); } }
違いを見つける