1 /*
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
26 package java.util.zip;
27
28 import java.nio.ByteBuffer;
29 import java.nio.CharBuffer;
30 import java.nio.charset.Charset;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.charset.CharsetDecoder;
33 import java.nio.charset.CharsetEncoder;
34 import java.nio.charset.CoderResult;
35 import java.nio.charset.CodingErrorAction;
36 import java.util.Arrays;
37 import sun.nio.cs.ArrayDecoder;
38 import sun.nio.cs.ArrayEncoder;
39
40 /**
41 * Utility class for zipfile name and comment decoding and encoding
42 */
43
44 final class ZipCoder {
45
46 String toString(byte[] ba, int off, int length) {
47 CharsetDecoder cd = decoder().reset();
48 int len = (int)(length * cd.maxCharsPerByte());
49 char[] ca = new char[len];
50 if (len == 0)
51 return new String(ca);
52 // UTF-8 only for now. Other ArrayDeocder only handles
53 // CodingErrorAction.REPLACE mode. ZipCoder uses
54 // REPORT mode.
55 if (isUTF8 && cd instanceof ArrayDecoder) {
56 int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca);
57 if (clen == -1) // malformed
58 throw new IllegalArgumentException("MALFORMED");
59 return new String(ca, 0, clen);
60 }
61 ByteBuffer bb = ByteBuffer.wrap(ba, off, length);
62 CharBuffer cb = CharBuffer.wrap(ca);
63 CoderResult cr = cd.decode(bb, cb, true);
64 if (!cr.isUnderflow())
65 throw new IllegalArgumentException(cr.toString());
66 cr = cd.flush(cb);
67 if (!cr.isUnderflow())
68 throw new IllegalArgumentException(cr.toString());
69 return new String(ca, 0, cb.position());
70 }
71
72 String toString(byte[] ba, int length) {
73 return toString(ba, 0, length);
74 }
75
76 String toString(byte[] ba) {
77 return toString(ba, 0, ba.length);
78 }
79
80 byte[] getBytes(String s) {
81 CharsetEncoder ce = encoder().reset();
82 char[] ca = s.toCharArray();
83 int len = (int)(ca.length * ce.maxBytesPerChar());
84 byte[] ba = new byte[len];
85 if (len == 0)
86 return ba;
87 // UTF-8 only for now. Other ArrayDeocder only handles
88 // CodingErrorAction.REPLACE mode.
89 if (isUTF8 && ce instanceof ArrayEncoder) {
90 int blen = ((ArrayEncoder)ce).encode(ca, 0, ca.length, ba);
91 if (blen == -1) // malformed
92 throw new IllegalArgumentException("MALFORMED");
93 return Arrays.copyOf(ba, blen);
94 }
95 ByteBuffer bb = ByteBuffer.wrap(ba);
96 CharBuffer cb = CharBuffer.wrap(ca);
97 CoderResult cr = ce.encode(cb, bb, true);
98 if (!cr.isUnderflow())
99 throw new IllegalArgumentException(cr.toString());
100 cr = ce.flush(bb);
|
1 /*
2 * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
26 package java.util.zip;
27
28 import java.nio.ByteBuffer;
29 import java.nio.CharBuffer;
30 import java.nio.charset.Charset;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.charset.CharsetDecoder;
33 import java.nio.charset.CharsetEncoder;
34 import java.nio.charset.CoderResult;
35 import java.nio.charset.CodingErrorAction;
36 import java.util.Arrays;
37 import sun.nio.cs.ArrayDecoder;
38 import sun.nio.cs.ArrayEncoder;
39
40 /**
41 * Utility class for zipfile name and comment decoding and encoding
42 */
43
44 final class ZipCoder {
45
46 private static boolean isASCII(byte[] ba, int off, int len) {
47 for (int i = off; i < off + len; i++) {
48 if (ba[i] < 0)
49 return false;
50 }
51 return true;
52 }
53
54 private static boolean hasReplaceChar(byte[] ba) {
55 for (int i = 0; i < ba.length; i++) {
56 if (ba[i] == (byte)'?')
57 return true;
58 }
59 return false;
60 }
61
62 String toString(byte[] ba, int off, int length) {
63
64 // fastpath for UTF-8 cs and ascii only name, leverage the
65 // compact string impl to avoid the unnecessary char[] copy/
66 // paste. A temporary workaround before we have better approach,
67 // such as a String constructor that throws exception for
68 // malformed and/or unmappable characters, instead of silently
69 // replacing with repl char
70 if (isUTF8 && isASCII(ba, off, length)) {
71 return new String(ba, off, length, cs);
72 }
73
74 CharsetDecoder cd = decoder().reset();
75 int len = (int)(length * cd.maxCharsPerByte());
76 char[] ca = new char[len];
77 if (len == 0)
78 return new String(ca);
79 // UTF-8 only for now. Other ArrayDeocder only handles
80 // CodingErrorAction.REPLACE mode. ZipCoder uses
81 // REPORT mode.
82 if (isUTF8 && cd instanceof ArrayDecoder) {
83 int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca);
84 if (clen == -1) // malformed
85 throw new IllegalArgumentException("MALFORMED");
86 return new String(ca, 0, clen);
87 }
88 ByteBuffer bb = ByteBuffer.wrap(ba, off, length);
89 CharBuffer cb = CharBuffer.wrap(ca);
90 CoderResult cr = cd.decode(bb, cb, true);
91 if (!cr.isUnderflow())
92 throw new IllegalArgumentException(cr.toString());
93 cr = cd.flush(cb);
94 if (!cr.isUnderflow())
95 throw new IllegalArgumentException(cr.toString());
96 return new String(ca, 0, cb.position());
97 }
98
99 String toString(byte[] ba, int length) {
100 return toString(ba, 0, length);
101 }
102
103 String toString(byte[] ba) {
104 return toString(ba, 0, ba.length);
105 }
106
107 byte[] getBytes(String s) {
108 if (isUTF8) {
109 // fastpath for UTF8. should only occur when the string
110 // has malformed surrogates. A postscan should still be
111 // faster and use less memory.
112 byte[] ba = s.getBytes(cs);
113 if (!hasReplaceChar(ba)) {
114 return ba;
115 }
116 }
117 CharsetEncoder ce = encoder().reset();
118 char[] ca = s.toCharArray();
119 int len = (int)(ca.length * ce.maxBytesPerChar());
120 byte[] ba = new byte[len];
121 if (len == 0)
122 return ba;
123 // UTF-8 only for now. Other ArrayDeocder only handles
124 // CodingErrorAction.REPLACE mode.
125 if (isUTF8 && ce instanceof ArrayEncoder) {
126 int blen = ((ArrayEncoder)ce).encode(ca, 0, ca.length, ba);
127 if (blen == -1) // malformed
128 throw new IllegalArgumentException("MALFORMED");
129 return Arrays.copyOf(ba, blen);
130 }
131 ByteBuffer bb = ByteBuffer.wrap(ba);
132 CharBuffer cb = CharBuffer.wrap(ca);
133 CoderResult cr = ce.encode(cb, bb, true);
134 if (!cr.isUnderflow())
135 throw new IllegalArgumentException(cr.toString());
136 cr = ce.flush(bb);
|