All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.zving.preloader.zip.Simple8BitZipEncoding Maven / Gradle / Ivy

There is a newer version: 0.3.0
Show newest version
package com.zving.preloader.zip;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Simple8BitZipEncoding
  implements ZipEncoding
{
  private final char[] highChars;
  private final List reverseMapping;
  
  private static final class Simple8BitChar
    implements Comparable
  {
    public final char unicode;
    public final byte code;
    
    Simple8BitChar(byte code, char unicode)
    {
      this.code = code;
      this.unicode = unicode;
    }
    
    public String toString()
    {
      return "0x" + Integer.toHexString(0xFFFF & this.unicode) + "->0x" + Integer.toHexString(0xFF & this.code);
    }
    
    public int compareTo(Simple8BitChar o)
    {
      return this.unicode - o.unicode;
    }
  }
  
  public Simple8BitZipEncoding(char[] highChars)
  {
    this.highChars = highChars;
    this.reverseMapping = new ArrayList(this.highChars.length);
    
    byte code = Byte.MAX_VALUE;
    for (int i = 0; i < this.highChars.length; i++) {
      this.reverseMapping.add(new Simple8BitChar(code = (byte)(code + 1), this.highChars[i]));
    }
    Collections.sort(this.reverseMapping);
  }
  
  public char decodeByte(byte b)
  {
    if (b >= 0) {
      return (char)b;
    }
    return this.highChars[(128 + b)];
  }
  
  public boolean canEncodeChar(char c)
  {
    if ((c >= 0) && (c < '€')) {
      return true;
    }
    Simple8BitChar r = encodeHighChar(c);
    return r != null;
  }
  
  public boolean pushEncodedChar(ByteBuffer bb, char c)
  {
    if ((c >= 0) && (c < '€'))
    {
      bb.put((byte)c);
      return true;
    }
    Simple8BitChar r = encodeHighChar(c);
    if (r == null) {
      return false;
    }
    bb.put(r.code);
    return true;
  }
  
  private Simple8BitChar encodeHighChar(char c)
  {
    int i0 = 0;
    int i1 = this.reverseMapping.size();
    while (i1 > i0)
    {
      int i = i0 + (i1 - i0) / 2;
      
      Simple8BitChar m = (Simple8BitChar)this.reverseMapping.get(i);
      if (m.unicode == c) {
        return m;
      }
      if (m.unicode < c) {
        i0 = i + 1;
      } else {
        i1 = i;
      }
    }
    if (i0 >= this.reverseMapping.size()) {
      return null;
    }
    Simple8BitChar r = (Simple8BitChar)this.reverseMapping.get(i0);
    if (r.unicode != c) {
      return null;
    }
    return r;
  }
  
  public boolean canEncode(String name)
  {
    for (int i = 0; i < name.length(); i++)
    {
      char c = name.charAt(i);
      if (!canEncodeChar(c)) {
        return false;
      }
    }
    return true;
  }
  
  public ByteBuffer encode(String name)
  {
    ByteBuffer out = ByteBuffer.allocate(name.length() + 6 + (name.length() + 1) / 2);
    for (int i = 0; i < name.length(); i++)
    {
      char c = name.charAt(i);
      if (out.remaining() < 6) {
        out = ZipEncodingHelper.growBuffer(out, out.position() + 6);
      }
      if (!pushEncodedChar(out, c)) {
        ZipEncodingHelper.appendSurrogate(out, c);
      }
    }
    out.limit(out.position());
    out.rewind();
    return out;
  }
  
  public String decode(byte[] data)
    throws IOException
  {
    char[] ret = new char[data.length];
    for (int i = 0; i < data.length; i++) {
      ret[i] = decodeByte(data[i]);
    }
    return new String(ret);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy