CharsetToBytesAdaptor.java 3.7 KB

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