home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2007 April / PCpro_2007_04.ISO / files / dsl / jNetTool.exe / gnu / inet / Punycode.class (.txt) < prev    next >
Encoding:
Java Class File  |  2005-06-05  |  3.2 KB  |  199 lines

  1. package gnu.inet;
  2.  
  3. public class Punycode {
  4.    static final int TMIN = 1;
  5.    static final int TMAX = 26;
  6.    static final int BASE = 36;
  7.    static final int INITIAL_N = 128;
  8.    static final int INITIAL_BIAS = 72;
  9.    static final int DAMP = 700;
  10.    static final int SKEW = 38;
  11.    static final char DELIMITER = '-';
  12.  
  13.    public static String encode(String input) throws PunycodeException {
  14.       int n = 128;
  15.       int delta = 0;
  16.       int bias = 72;
  17.       StringBuffer output = new StringBuffer();
  18.       int b = 0;
  19.  
  20.       for(int i = 0; i < input.length(); ++i) {
  21.          char c = input.charAt(i);
  22.          if (isBasic(c)) {
  23.             output.append(c);
  24.             ++b;
  25.          }
  26.       }
  27.  
  28.       if (b > 0) {
  29.          output.append('-');
  30.       }
  31.  
  32.       for(int h = b; h < input.length(); ++n) {
  33.          int m = Integer.MAX_VALUE;
  34.  
  35.          for(int i = 0; i < input.length(); ++i) {
  36.             int c = input.charAt(i);
  37.             if (c >= n && c < m) {
  38.                m = c;
  39.             }
  40.          }
  41.  
  42.          if (m - n > (Integer.MAX_VALUE - delta) / (h + 1)) {
  43.             throw new PunycodeException(PunycodeException.OVERFLOW);
  44.          }
  45.  
  46.          delta += (m - n) * (h + 1);
  47.          n = m;
  48.  
  49.          for(int j = 0; j < input.length(); ++j) {
  50.             int c = input.charAt(j);
  51.             if (c < n) {
  52.                ++delta;
  53.                if (delta == 0) {
  54.                   throw new PunycodeException(PunycodeException.OVERFLOW);
  55.                }
  56.             }
  57.  
  58.             if (c == n) {
  59.                int q = delta;
  60.                int k = 36;
  61.  
  62.                while(true) {
  63.                   int t;
  64.                   if (k <= bias) {
  65.                      t = 1;
  66.                   } else if (k >= bias + 26) {
  67.                      t = 26;
  68.                   } else {
  69.                      t = k - bias;
  70.                   }
  71.  
  72.                   if (q < t) {
  73.                      output.append((char)digit2codepoint(q));
  74.                      bias = adapt(delta, h + 1, h == b);
  75.                      delta = 0;
  76.                      ++h;
  77.                      break;
  78.                   }
  79.  
  80.                   output.append((char)digit2codepoint(t + (q - t) % (36 - t)));
  81.                   q = (q - t) / (36 - t);
  82.                   k += 36;
  83.                }
  84.             }
  85.          }
  86.  
  87.          ++delta;
  88.       }
  89.  
  90.       return output.toString();
  91.    }
  92.  
  93.    public static String decode(String input) throws PunycodeException {
  94.       int n = 128;
  95.       int i = 0;
  96.       int bias = 72;
  97.       StringBuffer output = new StringBuffer();
  98.       int d = input.lastIndexOf(45);
  99.       if (d > 0) {
  100.          for(int j = 0; j < d; ++j) {
  101.             char c = input.charAt(j);
  102.             if (!isBasic(c)) {
  103.                throw new PunycodeException(PunycodeException.BAD_INPUT);
  104.             }
  105.  
  106.             output.append(c);
  107.          }
  108.  
  109.          ++d;
  110.       } else {
  111.          d = 0;
  112.       }
  113.  
  114.       label53:
  115.       while(d < input.length()) {
  116.          int oldi = i;
  117.          int w = 1;
  118.  
  119.          for(int k = 36; d != input.length(); k += 36) {
  120.             int c = input.charAt(d++);
  121.             int digit = codepoint2digit(c);
  122.             if (digit > (Integer.MAX_VALUE - i) / w) {
  123.                throw new PunycodeException(PunycodeException.OVERFLOW);
  124.             }
  125.  
  126.             i += digit * w;
  127.             int t;
  128.             if (k <= bias) {
  129.                t = 1;
  130.             } else if (k >= bias + 26) {
  131.                t = 26;
  132.             } else {
  133.                t = k - bias;
  134.             }
  135.  
  136.             if (digit < t) {
  137.                bias = adapt(i - oldi, output.length() + 1, oldi == 0);
  138.                if (i / (output.length() + 1) > Integer.MAX_VALUE - n) {
  139.                   throw new PunycodeException(PunycodeException.OVERFLOW);
  140.                }
  141.  
  142.                n += i / (output.length() + 1);
  143.                i %= output.length() + 1;
  144.                output.insert(i, (char)n);
  145.                ++i;
  146.                continue label53;
  147.             }
  148.  
  149.             w *= 36 - t;
  150.          }
  151.  
  152.          throw new PunycodeException(PunycodeException.BAD_INPUT);
  153.       }
  154.  
  155.       return output.toString();
  156.    }
  157.  
  158.    public static final int adapt(int delta, int numpoints, boolean first) {
  159.       if (first) {
  160.          delta /= 700;
  161.       } else {
  162.          delta /= 2;
  163.       }
  164.  
  165.       delta += delta / numpoints;
  166.  
  167.       int k;
  168.       for(k = 0; delta > 455; k += 36) {
  169.          delta /= 35;
  170.       }
  171.  
  172.       return k + 36 * delta / (delta + 38);
  173.    }
  174.  
  175.    public static final boolean isBasic(char c) {
  176.       return c < 128;
  177.    }
  178.  
  179.    public static final int digit2codepoint(int d) throws PunycodeException {
  180.       if (d < 26) {
  181.          return d + 97;
  182.       } else if (d < 36) {
  183.          return d - 26 + 48;
  184.       } else {
  185.          throw new PunycodeException(PunycodeException.BAD_INPUT);
  186.       }
  187.    }
  188.  
  189.    public static final int codepoint2digit(int c) throws PunycodeException {
  190.       if (c - 48 < 10) {
  191.          return c - 48 + 26;
  192.       } else if (c - 97 < 26) {
  193.          return c - 97;
  194.       } else {
  195.          throw new PunycodeException(PunycodeException.BAD_INPUT);
  196.       }
  197.    }
  198. }
  199.