/src/main/java/com/alibaba/fastjson/serializer/SerialWriterStringEncoder.java
Java | 75 lines | 54 code | 17 blank | 4 comment | 4 complexity | 79cc82892f4d8a4713046eb3e0928424 MD5 | raw file
1package com.alibaba.fastjson.serializer;
2
3import java.nio.ByteBuffer;
4import java.nio.CharBuffer;
5import java.nio.charset.CharacterCodingException;
6import java.nio.charset.Charset;
7import java.nio.charset.CharsetEncoder;
8import java.nio.charset.CoderResult;
9import java.nio.charset.CodingErrorAction;
10
11import com.alibaba.fastjson.JSONException;
12import com.alibaba.fastjson.util.ThreadLocalCache;
13
14public class SerialWriterStringEncoder {
15
16 private final CharsetEncoder encoder;
17
18 public SerialWriterStringEncoder(Charset cs) {
19 this(cs.newEncoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE));
20 }
21
22 public SerialWriterStringEncoder(CharsetEncoder encoder) {
23 this.encoder = encoder;
24 }
25
26 public byte[] encode(char[] chars, int off, int len) {
27 if (len == 0) {
28 return new byte[0];
29 }
30
31 encoder.reset();
32
33 int bytesLength = scale(len, encoder.maxBytesPerChar());
34
35 byte[] bytes = ThreadLocalCache.getBytes(bytesLength);
36
37 return encode(chars, off, len, bytes);
38 }
39
40 public CharsetEncoder getEncoder() {
41 return encoder;
42 }
43
44 public byte[] encode(char[] chars, int off, int len, byte[] bytes) {
45 ByteBuffer byteBuf = ByteBuffer.wrap(bytes);
46
47 CharBuffer charBuf = CharBuffer.wrap(chars, off, len);
48 try {
49 CoderResult cr = encoder.encode(charBuf, byteBuf, true);
50 if (!cr.isUnderflow()) {
51 cr.throwException();
52 }
53 cr = encoder.flush(byteBuf);
54 if (!cr.isUnderflow()) {
55 cr.throwException();
56 }
57 } catch (CharacterCodingException x) {
58 // Substitution is always enabled,
59 // so this shouldn't happen
60 throw new JSONException(x.getMessage(), x);
61 }
62
63 int bytesLength = byteBuf.position();
64 byte[] copy = new byte[bytesLength];
65 System.arraycopy(bytes, 0, copy, 0, bytesLength);
66 return copy;
67 }
68
69 private static int scale(int len, float expansionFactor) {
70 // We need to perform double, not float, arithmetic; otherwise
71 // we lose low order bits when len is larger than 2**24.
72 return (int) (len * (double) expansionFactor);
73 }
74
75}