Frames | No Frames |
1: /* Copyright (C) 2005, 2006 Free Software Foundation 2: 3: This file is part of libgcj. 4: 5: This software is copyrighted work licensed under the terms of the 6: Libgcj License. Please consult the file "LIBGCJ_LICENSE" for 7: details. */ 8: 9: package gnu.gcj.convert; 10: 11: import java.nio.ByteBuffer; 12: import java.nio.CharBuffer; 13: import java.nio.charset.Charset; 14: import java.nio.charset.CharsetEncoder; 15: import java.nio.charset.CodingErrorAction; 16: import java.nio.charset.CoderResult; 17: import gnu.java.nio.charset.EncodingHelper; 18: 19: /** 20: * Adaptor class that allow any {@link Charset} to be used 21: * as a UnicodeToBytes converter. 22: */ 23: public class CharsetToBytesAdaptor extends UnicodeToBytes 24: { 25: /** 26: * The CharsetEncoder that does all the work. 27: */ 28: private final CharsetEncoder encoder; 29: 30: /** 31: * ByteBuffer wrapper for this.buf. 32: */ 33: private ByteBuffer outBuf; 34: 35: /** 36: * True if we've told the CharsetEncoder that there are no more 37: * characters available. 38: */ 39: private boolean closedEncoder; 40: 41: /** 42: * True if there are bytes pending in the encoder. 43: */ 44: private boolean hasBytes; 45: 46: /** 47: * True if we're finished. 48: */ 49: private boolean finished; 50: 51: /** 52: * Create a new CharsetToBytesAdaptor for the given Charset. 53: * 54: * @param cs The Charset. 55: */ 56: public CharsetToBytesAdaptor(Charset cs) 57: { 58: this(cs.newEncoder()); 59: } 60: 61: /** 62: * Create a new CharsetToBytesAdaptor for the given CharsetEncoder. 63: * 64: * @param enc The CharsetEncoder. 65: */ 66: public CharsetToBytesAdaptor(CharsetEncoder enc) 67: { 68: encoder = enc; 69: // Use default replacments on bad input so that we don't have to 70: // deal with errors. 71: encoder.onMalformedInput(CodingErrorAction.REPLACE); 72: encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 73: } 74: 75: /** 76: * Return the encoder's name. The backing Charset's name is 77: * returned. 78: * 79: * @return The name. 80: */ 81: public String getName() 82: { 83: return EncodingHelper.getOldCanonical(encoder.charset().name()); 84: } 85: 86: public int write (char[] inbuffer, int inpos, int inlength) 87: { 88: // Wrap the char array so it can be used by the encoder. 89: CharBuffer b = CharBuffer.wrap(inbuffer, inpos, inlength); 90: write(b); 91: return b.position() - inpos; // Number of chars consumed. 92: } 93: 94: public int write (String str, int inpos, int inlength, char work) 95: { 96: // Wrap the String so it can be used by the encoder. 97: CharBuffer b = CharBuffer.wrap(str, inpos, inlength); 98: write(b); 99: return b.position() - inpos; // Number of chars consumed. 100: } 101: 102: /** 103: * Encode as much of inBuf as will fit in buf. The number of 104: * chars consumed is reflected by the new position of inBuf. The 105: * output is put in buf and count is incremented by the number of 106: * bytes written. 107: * 108: * @param inBuf The input. 109: */ 110: private void write(CharBuffer inBuf) 111: { 112: // Reuse existing outBuf if it is still wrapping the same array 113: // it was created with. 114: if (outBuf == null || !outBuf.hasArray() || outBuf.array() != buf) 115: outBuf = ByteBuffer.wrap(buf); 116: 117: // Set the current position. 118: outBuf.position(count); 119: 120: // Do the conversion. 121: CoderResult result = encoder.encode(inBuf, outBuf, closedEncoder); 122: hasBytes = result == CoderResult.OVERFLOW; 123: if (closedEncoder) 124: { 125: result = encoder.flush(outBuf); 126: if (result == CoderResult.UNDERFLOW) 127: finished = true; 128: else 129: hasBytes = true; 130: } 131: 132: // Mark the new end of buf. 133: count = outBuf.position(); 134: } 135: 136: /** 137: * Check for cached output in the converter. 138: * 139: * @return true if there is cached output that has not been 140: * written to buf. 141: */ 142: public boolean havePendingBytes() 143: { 144: return hasBytes; 145: } 146: 147: public void setFinished() 148: { 149: closedEncoder = true; 150: } 151: 152: // These aren't cached. 153: public void done() 154: { 155: } 156: }