UTF8.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:9k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.io;
  19. import java.io.IOException;
  20. import java.io.DataInput;
  21. import java.io.DataOutput;
  22. import org.apache.commons.logging.*;
  23. /** A WritableComparable for strings that uses the UTF8 encoding.
  24.  * 
  25.  * <p>Also includes utilities for efficiently reading and writing UTF-8.
  26.  *
  27.  * @deprecated replaced by Text
  28.  */
  29. public class UTF8 implements WritableComparable {
  30.   private static final Log LOG= LogFactory.getLog(UTF8.class);
  31.   private static final DataOutputBuffer OBUF = new DataOutputBuffer();
  32.   private static final DataInputBuffer IBUF = new DataInputBuffer();
  33.   private static final byte[] EMPTY_BYTES = new byte[0];
  34.   private byte[] bytes = EMPTY_BYTES;
  35.   private int length;
  36.   public UTF8() {
  37.     //set("");
  38.   }
  39.   /** Construct from a given string. */
  40.   public UTF8(String string) {
  41.     set(string);
  42.   }
  43.   /** Construct from a given string. */
  44.   public UTF8(UTF8 utf8) {
  45.     set(utf8);
  46.   }
  47.   /** The raw bytes. */
  48.   public byte[] getBytes() {
  49.     return bytes;
  50.   }
  51.   /** The number of bytes in the encoded string. */
  52.   public int getLength() {
  53.     return length;
  54.   }
  55.   /** Set to contain the contents of a string. */
  56.   public void set(String string) {
  57.     if (string.length() > 0xffff/3) {             // maybe too long
  58.       LOG.warn("truncating long string: " + string.length()
  59.                + " chars, starting with " + string.substring(0, 20));
  60.       string = string.substring(0, 0xffff/3);
  61.     }
  62.     length = utf8Length(string);                  // compute length
  63.     if (length > 0xffff)                          // double-check length
  64.       throw new RuntimeException("string too long!");
  65.     if (bytes == null || length > bytes.length)   // grow buffer
  66.       bytes = new byte[length];
  67.     try {                                         // avoid sync'd allocations
  68.       synchronized (OBUF) {
  69.         OBUF.reset();
  70.         writeChars(OBUF, string, 0, string.length());
  71.         System.arraycopy(OBUF.getData(), 0, bytes, 0, length);
  72.       }
  73.     } catch (IOException e) {
  74.       throw new RuntimeException(e);
  75.     }
  76.   }
  77.   /** Set to contain the contents of a string. */
  78.   public void set(UTF8 other) {
  79.     length = other.length;
  80.     if (bytes == null || length > bytes.length)   // grow buffer
  81.       bytes = new byte[length];
  82.     System.arraycopy(other.bytes, 0, bytes, 0, length);
  83.   }
  84.   public void readFields(DataInput in) throws IOException {
  85.     length = in.readUnsignedShort();
  86.     if (bytes == null || bytes.length < length)
  87.       bytes = new byte[length];
  88.     in.readFully(bytes, 0, length);
  89.   }
  90.   /** Skips over one UTF8 in the input. */
  91.   public static void skip(DataInput in) throws IOException {
  92.     int length = in.readUnsignedShort();
  93.     WritableUtils.skipFully(in, length);
  94.   }
  95.   public void write(DataOutput out) throws IOException {
  96.     out.writeShort(length);
  97.     out.write(bytes, 0, length);
  98.   }
  99.   /** Compare two UTF8s. */
  100.   public int compareTo(Object o) {
  101.     UTF8 that = (UTF8)o;
  102.     return WritableComparator.compareBytes(bytes, 0, length,
  103.                                            that.bytes, 0, that.length);
  104.   }
  105.   /** Convert to a String. */
  106.   public String toString() {
  107.     StringBuffer buffer = new StringBuffer(length);
  108.     try {
  109.       synchronized (IBUF) {
  110.         IBUF.reset(bytes, length);
  111.         readChars(IBUF, buffer, length);
  112.       }
  113.     } catch (IOException e) {
  114.       throw new RuntimeException(e);
  115.     }
  116.     return buffer.toString();
  117.   }
  118.   /** Returns true iff <code>o</code> is a UTF8 with the same contents.  */
  119.   public boolean equals(Object o) {
  120.     if (!(o instanceof UTF8))
  121.       return false;
  122.     UTF8 that = (UTF8)o;
  123.     if (this.length != that.length)
  124.       return false;
  125.     else
  126.       return WritableComparator.compareBytes(bytes, 0, length,
  127.                                              that.bytes, 0, that.length) == 0;
  128.   }
  129.   public int hashCode() {
  130.     return WritableComparator.hashBytes(bytes, length);
  131.   }
  132.   /** A WritableComparator optimized for UTF8 keys. */
  133.   public static class Comparator extends WritableComparator {
  134.     public Comparator() {
  135.       super(UTF8.class);
  136.     }
  137.     public int compare(byte[] b1, int s1, int l1,
  138.                        byte[] b2, int s2, int l2) {
  139.       int n1 = readUnsignedShort(b1, s1);
  140.       int n2 = readUnsignedShort(b2, s2);
  141.       return compareBytes(b1, s1+2, n1, b2, s2+2, n2);
  142.     }
  143.   }
  144.   static {                                        // register this comparator
  145.     WritableComparator.define(UTF8.class, new Comparator());
  146.   }
  147.   /// STATIC UTILITIES FROM HERE DOWN
  148.   /// These are probably not used much anymore, and might be removed...
  149.   /** Convert a string to a UTF-8 encoded byte array.
  150.    * @see String#getBytes(String)
  151.    */
  152.   public static byte[] getBytes(String string) {
  153.     byte[] result = new byte[utf8Length(string)];
  154.     try {                                         // avoid sync'd allocations
  155.       synchronized (OBUF) {
  156.         OBUF.reset();
  157.         writeChars(OBUF, string, 0, string.length());
  158.         System.arraycopy(OBUF.getData(), 0, result, 0, OBUF.getLength());
  159.       }
  160.     } catch (IOException e) {
  161.       throw new RuntimeException(e);
  162.     }
  163.     return result;
  164.   }
  165.   /** Read a UTF-8 encoded string.
  166.    *
  167.    * @see DataInput#readUTF()
  168.    */
  169.   public static String readString(DataInput in) throws IOException {
  170.     int bytes = in.readUnsignedShort();
  171.     StringBuffer buffer = new StringBuffer(bytes);
  172.     readChars(in, buffer, bytes);
  173.     return buffer.toString();
  174.   }
  175.   private static void readChars(DataInput in, StringBuffer buffer, int nBytes)
  176.     throws IOException {
  177.     synchronized (OBUF) {
  178.       OBUF.reset();
  179.       OBUF.write(in, nBytes);
  180.       byte[] bytes = OBUF.getData();
  181.       int i = 0;
  182.       while (i < nBytes) {
  183.         byte b = bytes[i++];
  184.         if ((b & 0x80) == 0) {
  185.           buffer.append((char)(b & 0x7F));
  186.         } else if ((b & 0xE0) != 0xE0) {
  187.           buffer.append((char)(((b & 0x1F) << 6)
  188.                                | (bytes[i++] & 0x3F)));
  189.         } else {
  190.           buffer.append((char)(((b & 0x0F) << 12)
  191.                                | ((bytes[i++] & 0x3F) << 6)
  192.                                |  (bytes[i++] & 0x3F)));
  193.         }
  194.       }
  195.     }
  196.   }
  197.   /** Write a UTF-8 encoded string.
  198.    *
  199.    * @see DataOutput#writeUTF(String)
  200.    */
  201.   public static int writeString(DataOutput out, String s) throws IOException {
  202.     if (s.length() > 0xffff/3) {         // maybe too long
  203.       LOG.warn("truncating long string: " + s.length()
  204.                + " chars, starting with " + s.substring(0, 20));
  205.       s = s.substring(0, 0xffff/3);
  206.     }
  207.     int len = utf8Length(s);
  208.     if (len > 0xffff)                             // double-check length
  209.       throw new IOException("string too long!");
  210.       
  211.     out.writeShort(len);
  212.     writeChars(out, s, 0, s.length());
  213.     return len;
  214.   }
  215.   /** Returns the number of bytes required to write this. */
  216.   private static int utf8Length(String string) {
  217.     int stringLength = string.length();
  218.     int utf8Length = 0;
  219.     for (int i = 0; i < stringLength; i++) {
  220.       int c = string.charAt(i);
  221.       if ((c >= 0x0001) && (c <= 0x007F)) {
  222.         utf8Length++;
  223.       } else if (c > 0x07FF) {
  224.         utf8Length += 3;
  225.       } else {
  226.         utf8Length += 2;
  227.       }
  228.     }
  229.     return utf8Length;
  230.   }
  231.   private static void writeChars(DataOutput out,
  232.                                  String s, int start, int length)
  233.     throws IOException {
  234.     final int end = start + length;
  235.     for (int i = start; i < end; i++) {
  236.       int code = s.charAt(i);
  237.       if (code >= 0x01 && code <= 0x7F) {
  238.         out.writeByte((byte)code);
  239.       } else if (code <= 0x07FF) {
  240.         out.writeByte((byte)(0xC0 | ((code >> 6) & 0x1F)));
  241.         out.writeByte((byte)(0x80 |   code       & 0x3F));
  242.       } else {
  243.         out.writeByte((byte)(0xE0 | ((code >> 12) & 0X0F)));
  244.         out.writeByte((byte)(0x80 | ((code >>  6) & 0x3F)));
  245.         out.writeByte((byte)(0x80 |  (code        & 0x3F)));
  246.       }
  247.     }
  248.   }
  249. }