UnicodeEscaper.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.lang3.text.translate;

  18. import java.io.IOException;
  19. import java.io.Writer;

  20. /**
  21.  * Translates code points to their Unicode escaped value.
  22.  *
  23.  * @since 3.0
  24.  * @deprecated As of 3.6, use Apache Commons Text
  25.  * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/translate/UnicodeEscaper.html">
  26.  * UnicodeEscaper</a> instead
  27.  */
  28. @Deprecated
  29. public class UnicodeEscaper extends CodePointTranslator {

  30.     /**
  31.      * Constructs a {@link UnicodeEscaper} above the specified value (exclusive).
  32.      *
  33.      * @param codePoint above which to escape
  34.      * @return the newly created {@link UnicodeEscaper} instance
  35.      */
  36.     public static UnicodeEscaper above(final int codePoint) {
  37.         return outsideOf(0, codePoint);
  38.     }
  39.     /**
  40.      * Constructs a {@link UnicodeEscaper} below the specified value (exclusive).
  41.      *
  42.      * @param codePoint below which to escape
  43.      * @return the newly created {@link UnicodeEscaper} instance
  44.      */
  45.     public static UnicodeEscaper below(final int codePoint) {
  46.         return outsideOf(codePoint, Integer.MAX_VALUE);
  47.     }
  48.     /**
  49.      * Constructs a {@link UnicodeEscaper} between the specified values (inclusive).
  50.      *
  51.      * @param codePointLow above which to escape
  52.      * @param codePointHigh below which to escape
  53.      * @return the newly created {@link UnicodeEscaper} instance
  54.      */
  55.     public static UnicodeEscaper between(final int codePointLow, final int codePointHigh) {
  56.         return new UnicodeEscaper(codePointLow, codePointHigh, true);
  57.     }

  58.     /**
  59.      * Constructs a {@link UnicodeEscaper} outside of the specified values (exclusive).
  60.      *
  61.      * @param codePointLow below which to escape
  62.      * @param codePointHigh above which to escape
  63.      * @return the newly created {@link UnicodeEscaper} instance
  64.      */
  65.     public static UnicodeEscaper outsideOf(final int codePointLow, final int codePointHigh) {
  66.         return new UnicodeEscaper(codePointLow, codePointHigh, false);
  67.     }

  68.     private final int below;

  69.     private final int above;

  70.     private final boolean between;

  71.     /**
  72.      * Constructs a {@link UnicodeEscaper} for all characters.
  73.      */
  74.     public UnicodeEscaper() {
  75.         this(0, Integer.MAX_VALUE, true);
  76.     }

  77.     /**
  78.      * Constructs a {@link UnicodeEscaper} for the specified range. This is
  79.      * the underlying method for the other constructors/builders. The {@code below}
  80.      * and {@code above} boundaries are inclusive when {@code between} is
  81.      * {@code true} and exclusive when it is {@code false}.
  82.      *
  83.      * @param below int value representing the lowest code point boundary
  84.      * @param above int value representing the highest code point boundary
  85.      * @param between whether to escape between the boundaries or outside them
  86.      */
  87.     protected UnicodeEscaper(final int below, final int above, final boolean between) {
  88.         this.below = below;
  89.         this.above = above;
  90.         this.between = between;
  91.     }

  92.     /**
  93.      * Converts the given code point to a hexadecimal string of the form {@code "\\uXXXX"}
  94.      *
  95.      * @param codePoint
  96.      *            a Unicode code point
  97.      * @return the hexadecimal string for the given code point
  98.      *
  99.      * @since 3.2
  100.      */
  101.     protected String toUtf16Escape(final int codePoint) {
  102.         return "\\u" + hex(codePoint);
  103.     }

  104.     /**
  105.      * {@inheritDoc}
  106.      */
  107.     @Override
  108.     public boolean translate(final int codePoint, final Writer out) throws IOException {
  109.         if (between) {
  110.             if (codePoint < below || codePoint > above) {
  111.                 return false;
  112.             }
  113.         } else if (codePoint >= below && codePoint <= above) {
  114.             return false;
  115.         }

  116.         // TODO: Handle potential + sign per various Unicode escape implementations
  117.         if (codePoint > 0xffff) {
  118.             out.write(toUtf16Escape(codePoint));
  119.         } else {
  120.           out.write("\\u");
  121.           out.write(HEX_DIGITS[codePoint >> 12 & 15]);
  122.           out.write(HEX_DIGITS[codePoint >> 8 & 15]);
  123.           out.write(HEX_DIGITS[codePoint >> 4 & 15]);
  124.           out.write(HEX_DIGITS[codePoint & 15]);
  125.         }
  126.         return true;
  127.     }
  128. }