content: package com.alibaba.fastjson.serializer;
  
  import java.nio.ByteBuffer;
  import java.nio.CharBuffer;
  import java.nio.charset.CharacterCodingException;
  import java.nio.charset.Charset;
  import java.nio.charset.CharsetEncoder;
  import java.nio.charset.CoderResult;
  import java.nio.charset.CodingErrorAction;
  
  import com.alibaba.fastjson.JSONException;
  import com.alibaba.fastjson.util.ThreadLocalCache;
  
  public class SerialWriterStringEncoder {
  
  	private final CharsetEncoder encoder;
  
  	public SerialWriterStringEncoder(Charset cs) {
  		this(cs.newEncoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE));
  	}
  	
  	public SerialWriterStringEncoder(CharsetEncoder encoder) {
  	    this.encoder = encoder;
  	}
  
  	public byte[] encode(char[] chars, int off, int len) {
  		if (len == 0) {
  			return new byte[0];
  		}
  
  		encoder.reset();
  
  		int bytesLength = scale(len, encoder.maxBytesPerChar());
  
  		byte[] bytes = ThreadLocalCache.getBytes(bytesLength);
  
  		return encode(chars, off, len, bytes);
  	}
  
  	public CharsetEncoder getEncoder() {
  		return encoder;
  	}
  
  	public byte[] encode(char[] chars, int off, int len, byte[] bytes) {
  		ByteBuffer byteBuf = ByteBuffer.wrap(bytes);
  
  		CharBuffer charBuf = CharBuffer.wrap(chars, off, len);
  		try {
  			CoderResult cr = encoder.encode(charBuf, byteBuf, true);
  			if (!cr.isUnderflow()) {
  				cr.throwException();
  			}
  			cr = encoder.flush(byteBuf);
  			if (!cr.isUnderflow()) {
  				cr.throwException();
  			}
  		} catch (CharacterCodingException x) {
  			// Substitution is always enabled,
  			// so this shouldn't happen
  			throw new JSONException(x.getMessage(), x);
  		}
  
  		int bytesLength = byteBuf.position();
  		byte[] copy = new byte[bytesLength];
  		System.arraycopy(bytes, 0, copy, 0, bytesLength);
  		return copy;
  	}
  
  	private static int scale(int len, float expansionFactor) {
  		// We need to perform double, not float, arithmetic; otherwise
  		// we lose low order bits when len is larger than 2**24.
  		return (int) (len * (double) expansionFactor);
  	}
  
  }
  