src/share/classes/sun/io/CharToByteDBCS_ASCII.java

Print this page




   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 package sun.io;
  26 




  27 public abstract class CharToByteDBCS_ASCII extends CharToByteConverter
  28 {
  29 
  30     private char highHalfZoneCode;
  31     private byte[] outputByte = new byte[2];
  32 
  33     protected short index1[];
  34     protected String index2;
  35     protected String index2a;
  36     protected int   mask1;
  37     protected int   mask2;
  38     protected int   shift;
  39 









  40     /**
  41       * flush out any residual data and reset the buffer state
  42       */
  43     public int flush(byte [] output, int outStart, int outEnd)
  44         throws MalformedInputException, ConversionBufferFullException
  45     {
  46 
  47        if (highHalfZoneCode != 0) {
  48           reset();
  49           badInputLength = 0;
  50           throw new MalformedInputException();
  51        }
  52 
  53        reset();
  54        return 0;
  55     }
  56 
  57     /**
  58      * Character conversion
  59      */
  60     public int convert(char[] input, int inOff, int inEnd,
  61                        byte[] output, int outOff, int outEnd)
  62         throws UnknownCharacterException, MalformedInputException,
  63                ConversionBufferFullException
  64     {
  65         char    inputChar;
  66         int     inputSize;
  67 
  68         byteOff = outOff;
  69         charOff = inOff;
  70 
  71         while(charOff < inEnd) {
  72 
  73            int   index;
  74            int   theBytes;
  75            int   spaceNeeded;
  76 
  77            if (highHalfZoneCode == 0) {
  78               inputChar = input[charOff];
  79               inputSize = 1;
  80            } else {
  81               inputChar = highHalfZoneCode;
  82               inputSize = 0;
  83               highHalfZoneCode = 0;
  84            }
  85 
  86 
  87            // Is this a high surrogate?
  88            if(inputChar >= '\ud800' && inputChar <= '\udbff') {
  89               // Is this the last character of the input?
  90               if (charOff + inputSize >= inEnd) {
  91                  highHalfZoneCode = inputChar;
  92                  charOff += inputSize;
  93                  break;
  94               }
  95 
  96               // Is there a low surrogate following?
  97               inputChar = input[charOff + inputSize];
  98               if (inputChar >= '\udc00' && inputChar <= '\udfff') {
  99 
 100                  // We have a valid surrogate pair.  Too bad we don't do
 101                  // surrogates.  Is substitution enabled?
 102                  if (subMode) {
 103                     if (subBytes.length == 1) {
 104                        outputByte[0] = 0x00;
 105                        outputByte[1] = subBytes[0];
 106                     }
 107                     else {
 108                        outputByte[0] = subBytes[0];
 109                        outputByte[1] = subBytes[1];
 110                     }
 111 
 112                     inputSize++;
 113                  } else {
 114                     badInputLength = 2;
 115                     throw new UnknownCharacterException();
 116                  }
 117               } else {
 118 
 119                  // We have a malformed surrogate pair
 120                  badInputLength = 1;
 121                  throw new MalformedInputException();
 122               }
 123            }
 124 
 125            // Is this an unaccompanied low surrogate?
 126            else
 127               if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') {
 128                  badInputLength = 1;
 129                  throw new MalformedInputException();
 130               } else {
 131 
 132                  // We have a valid character, get the bytes for it
 133                  index = index1[((inputChar & mask1) >> shift)] + (inputChar & mask2);
 134                  if (index < 15000)
 135                    theBytes = (int)(index2.charAt(index));
 136                  else
 137                    theBytes = (int)(index2a.charAt(index-15000));
 138                  outputByte[0] = (byte)((theBytes & 0x0000ff00)>>8);
 139                  outputByte[1] = (byte)(theBytes & 0x000000ff);
 140               }
 141 
 142            // if there was no mapping - look for substitution characters
 143            if (outputByte[0] == 0x00 && outputByte[1] == 0x00
 144                              && inputChar != '\u0000')
 145            {
 146               if (subMode) {
 147                  if (subBytes.length == 1) {
 148                     outputByte[0] = 0x00;
 149                     outputByte[1] = subBytes[0];
 150                  } else {
 151                     outputByte[0] = subBytes[0];
 152                     outputByte[1] = subBytes[1];
 153                  }
 154               } else {
 155                 badInputLength = 1;
 156                 throw new UnknownCharacterException();
 157               }



 158            }
 159 
 160            if (outputByte[0] == 0x00)
 161               spaceNeeded = 1;
 162            else
 163               spaceNeeded = 2;
 164 
 165            if (byteOff + spaceNeeded > outEnd)
 166               throw new ConversionBufferFullException();
 167 
 168            if (spaceNeeded == 1)
 169               output[byteOff++] = outputByte[1];
 170            else {
 171               output[byteOff++] = outputByte[0];
 172               output[byteOff++] = outputByte[1];
 173            }
 174 
 175            charOff += inputSize;
 176         }
 177 
 178         return byteOff - outOff;
 179     }
 180 
 181     /**
 182      * Resets converter to its initial state.
 183      */
 184     public void reset() {
 185        charOff = byteOff = 0;
 186        highHalfZoneCode = 0;
 187     }
 188 
 189     /**
 190      * Returns the maximum number of bytes needed to convert a char.
 191      */
 192     public int getMaxBytesPerChar() {
 193         return 2;
 194     }
 195 
 196 
 197     /**
 198      * Returns true if the given character can be converted to the
 199      * target character encoding.
 200      */
 201     public boolean canConvert(char ch) {
 202        int  index;
 203        int  theBytes;
 204 
 205        index = index1[((ch & mask1) >> shift)] + (ch & mask2);
 206        if (index < 15000)
 207          theBytes = (int)(index2.charAt(index));
 208        else
 209          theBytes = (int)(index2a.charAt(index-15000));
 210 
 211        if (theBytes != 0)
 212          return (true);
 213 
 214        // only return true if input char was unicode null - all others are
 215        //     undefined
 216        return( ch == '\u0000');
 217 
 218     }
 219 
 220 }


   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 package sun.io;
  26 
  27 import sun.nio.cs.Surrogate;
  28 import sun.nio.cs.ext.DoubleByte;
  29 import static sun.nio.cs.CharsetMapping.*;
  30 
  31 public abstract class CharToByteDBCS_ASCII extends CharToByteConverter
  32 {
  33 
  34     private char highHalfZoneCode;
  35     private byte[] outputByte = new byte[2];
  36 
  37     private DoubleByte.Encoder enc;





  38 
  39     public CharToByteDBCS_ASCII(DoubleByte.Encoder enc) {
  40         super();
  41         this.enc = enc;
  42     }
  43 
  44     int encodeChar(char c) {
  45         return enc.encodeChar(c);
  46     }
  47 
  48     /**
  49       * flush out any residual data and reset the buffer state
  50       */
  51     public int flush(byte [] output, int outStart, int outEnd)
  52         throws MalformedInputException, ConversionBufferFullException
  53     {
  54 
  55        if (highHalfZoneCode != 0) {
  56           reset();
  57           badInputLength = 0;
  58           throw new MalformedInputException();
  59        }
  60 
  61        reset();
  62        return 0;
  63     }
  64 
  65     /**
  66      * Character conversion
  67      */
  68     public int convert(char[] input, int inOff, int inEnd,
  69                        byte[] output, int outOff, int outEnd)
  70         throws UnknownCharacterException, MalformedInputException,
  71                ConversionBufferFullException
  72     {
  73         char    inputChar;
  74         int     inputSize;
  75 
  76         byteOff = outOff;
  77         charOff = inOff;
  78 
  79         while(charOff < inEnd) {

  80             int   index;
  81             int   theBytes;
  82             int   spaceNeeded;
  83 
  84             if (highHalfZoneCode == 0) {
  85                 inputChar = input[charOff];
  86                 inputSize = 1;
  87             } else {
  88                 inputChar = highHalfZoneCode;
  89                 inputSize = 0;
  90                 highHalfZoneCode = 0;
  91             }
  92 

  93             // Is this a high surrogate?
  94             if (Surrogate.isHigh(inputChar)) {
  95                 // Is this the last character of the input?
  96                 if (charOff + inputSize >= inEnd) {
  97                     highHalfZoneCode = inputChar;
  98                     charOff += inputSize;
  99                     break;
 100                 }
 101 
 102                 // Is there a low surrogate following?
 103                 inputChar = input[charOff + inputSize];
 104                 if (Surrogate.isLow(inputChar)) {

 105                     // We have a valid surrogate pair.  Too bad we don't do
 106                     // surrogates.  Is substitution enabled?
 107                     if (subMode) {
 108                         if (subBytes.length == 1) {
 109                             outputByte[0] = 0x00;
 110                             outputByte[1] = subBytes[0];
 111                         }
 112                         else {
 113                             outputByte[0] = subBytes[0];
 114                             outputByte[1] = subBytes[1];
 115                         }

 116                         inputSize++;
 117                     } else {
 118                         badInputLength = 2;
 119                         throw new UnknownCharacterException();
 120                     }
 121                  } else {

 122                      // We have a malformed surrogate pair
 123                      badInputLength = 1;
 124                      throw new MalformedInputException();
 125                  }
 126             }

 127             // Is this an unaccompanied low surrogate?
 128             else if (Surrogate.isLow(inputChar)) {

 129                 badInputLength = 1;
 130                 throw new MalformedInputException();
 131             } else {
 132 
 133                 // We have a valid character, get the bytes for it
 134                 theBytes = encodeChar(inputChar);
 135                 if (theBytes == UNMAPPABLE_ENCODING) {







 136                     // if there was no mapping - look for substitution characters



 137                     if (subMode) {
 138                         if (subBytes.length == 1) {
 139                             outputByte[0] = 0x00;
 140                             outputByte[1] = subBytes[0];
 141                         } else {
 142                             outputByte[0] = subBytes[0];
 143                             outputByte[1] = subBytes[1];
 144                         }
 145                     } else {
 146                         badInputLength = 1;
 147                         throw new UnknownCharacterException();
 148                     }
 149                 } else {
 150                     outputByte[0] = (byte)(theBytes >>8);
 151                     outputByte[1] = (byte)theBytes;
 152                 }
 153             }
 154             if (outputByte[0] == 0x00)
 155                 spaceNeeded = 1;
 156             else
 157                 spaceNeeded = 2;
 158 
 159             if (byteOff + spaceNeeded > outEnd)
 160                 throw new ConversionBufferFullException();
 161 
 162             if (spaceNeeded == 1)
 163                 output[byteOff++] = outputByte[1];
 164             else {
 165                 output[byteOff++] = outputByte[0];
 166                 output[byteOff++] = outputByte[1];
 167             }
 168 
 169             charOff += inputSize;
 170         }

 171         return byteOff - outOff;
 172     }
 173 
 174     /**
 175      * Resets converter to its initial state.
 176      */
 177     public void reset() {
 178        charOff = byteOff = 0;
 179        highHalfZoneCode = 0;
 180     }
 181 
 182     /**
 183      * Returns the maximum number of bytes needed to convert a char.
 184      */
 185     public int getMaxBytesPerChar() {
 186         return 2;
 187     }
 188 

 189     /**
 190      * Returns true if the given character can be converted to the
 191      * target character encoding.
 192      */
 193     public boolean canConvert(char c) {
 194         return encodeChar(c) != UNMAPPABLE_ENCODING;    















 195     }

 196 }