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 we're finished. 43: */ 44: private boolean finished; 45: 46: /** 47: * Create a new CharsetToBytesAdaptor for the given Charset. 48: * 49: * @param cs The Charset. 50: */ 51: public CharsetToBytesAdaptor(Charset cs) 52: { 53: this(cs.newEncoder()); 54: } 55: 56: /** 57: * Create a new CharsetToBytesAdaptor for the given CharsetEncoder. 58: * 59: * @param enc The CharsetEncoder. 60: */ 61: public CharsetToBytesAdaptor(CharsetEncoder enc) 62: { 63: encoder = enc; 64: // Use default replacments on bad input so that we don't have to 65: // deal with errors. 66: encoder.onMalformedInput(CodingErrorAction.REPLACE); 67: encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 68: } 69: 70: /** 71: * Return the encoder's name. The backing Charset's name is 72: * returned. 73: * 74: * @return The name. 75: */ 76: public String getName() 77: { 78: return EncodingHelper.getOldCanonical(encoder.charset().name()); 79: } 80: 81: public int write (char[] inbuffer, int inpos, int inlength) 82: { 83: // Wrap the char array so it can be used by the encoder. 84: CharBuffer b = CharBuffer.wrap(inbuffer, inpos, inlength); 85: write(b); 86: return b.position() - inpos; // Number of chars consumed. 87: } 88: 89: public int write (String str, int inpos, int inlength, char work) 90: { 91: // Wrap the String so it can be used by the encoder. 92: CharBuffer b = CharBuffer.wrap(str, inpos, inlength); 93: write(b); 94: return b.position() - inpos; // Number of chars consumed. 95: } 96: 97: /** 98: * Encode as much of inBuf as will fit in buf. The number of 99: * chars consumed is reflected by the new position of inBuf. The 100: * output is put in buf and count is incremented by the number of 101: * bytes written. 102: * 103: * @param inBuf The input. 104: */ 105: private void write(CharBuffer inBuf) 106: { 107: // Reuse existing outBuf if it is still wrapping the same array 108: // it was created with. 109: if (outBuf == null || !outBuf.hasArray() || outBuf.array() != buf) 110: outBuf = ByteBuffer.wrap(buf); 111: 112: // Set the current position. 113: outBuf.position(count); 114: 115: // If we've already said that there is no more input available, 116: // then we simply try to flush again. 117: if (closedEncoder) 118: { 119: CoderResult result = encoder.flush(outBuf); 120: if (result == CoderResult.UNDERFLOW) 121: finished = true; 122: } 123: else 124: { 125: // Do the conversion. If there are no characters to write, 126: // then we are finished. 127: closedEncoder = ! inBuf.hasRemaining(); 128: encoder.encode(inBuf, outBuf, closedEncoder); 129: } 130: 131: // Mark the new end of buf. 132: count = outBuf.position(); 133: } 134: 135: /** 136: * Check for cached output in the converter. 137: * 138: * @return true if there is cached output that has not been 139: * written to buf. 140: */ 141: public boolean havePendingBytes() 142: { 143: return ! finished; 144: } 145: 146: // These aren't cached. 147: public void done() 148: { 149: } 150: }