Package erjang.driver.zlib

Source Code of erjang.driver.zlib.ZLibDriver

/**
* This file is part of Erjang - A JVM-based Erlang VM
*
* Copyright (c) 2010 by Trifork
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

package erjang.driver.zlib;

import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import com.jcraft.jzlib.CRC32;
import com.jcraft.jzlib.Deflater;
import com.jcraft.jzlib.Inflater;
import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZStream;
import com.jcraft.jzlib.ZStreamException;

import kilim.Pausable;
import kilim.Task;
import erjang.EBinary;
import erjang.EHandle;
import erjang.EPID;
import erjang.EString;
import erjang.NotImplemented;
import erjang.driver.EAsync;
import erjang.driver.EDriver;
import erjang.driver.EDriverInstance;
import erjang.driver.IO;

public class ZLibDriver extends EDriverInstance {

 
 
  // flush argument encoding
  public static final int Z_NO_FLUSH = 0;
  public static final int Z_SYNC_FLUSH = 2;
  public static final int Z_FULL_FLUSH = 3;
  public static final int Z_FINISH = 4;

  // compression level
  public static final int Z_NO_COMPRESSION = 0;
  public static final int Z_BEST_SPEED = 1;
  public static final int Z_BEST_COMPRESSION = 9;
  public static final int Z_DEFAULT_COMPRESSION = (-1);

  // compresssion strategy
  public static final int Z_FILTERED = 1;
  public static final int Z_HUFFMAN_ONLY = 2;
  public static final int Z_DEFAULT_STRATEGY = 0;

  // deflate compression method
  public static final int Z_DEFLATED = 8;

  public static final int Z_NULL = 0;

  public static final int MAX_WBITS = 15;

  // gzip defs (rfc 1952)

  public static final int ID1 = 0x1f;
  public static final int ID2 = 0x8b;

  public static final int FTEXT = 0x01;
  public static final int FHCRC = 0x02;
  public static final int FEXTRA = 0x04;
  public static final int FNAME = 0x08;
  public static final int FCOMMENT = 0x10;
  public static final int RESERVED = 0xE0;

  public static final int OS_MDDOS = 0;
  public static final int OS_AMIGA = 1;
  public static final int OS_OPENVMS = 2;
  public static final int OS_UNIX = 3;
  public static final int OS_VMCMS = 4;
  public static final int OS_ATARI = 5;
  public static final int OS_OS2 = 6;
  public static final int OS_MAC = 7;
  public static final int OS_ZSYS = 8;
  public static final int OS_CPM = 9;
  public static final int OS_TOP20 = 10;
  public static final int OS_NTFS = 11;
  public static final int OS_QDOS = 12;
  public static final int OS_ACORN = 13;
  public static final int OS_UNKNOWN = 255;

  public static final int DEFLATE_INIT = 1;
  public static final int DEFLATE_INIT2 = 2;
  public static final int DEFLATE_SETDICT = 3;
  public static final int DEFLATE_RESET = 4;
  public static final int DEFLATE_END = 5;
  public static final int DEFLATE_PARAMS = 6;
  public static final int DEFLATE = 7;

  public static final int INFLATE_INIT = 8;
  public static final int INFLATE_INIT2 = 9;
  public static final int INFLATE_SETDICT = 10;
  public static final int INFLATE_SYNC = 11;
  public static final int INFLATE_RESET = 12;
  public static final int INFLATE_END = 13;
  public static final int INFLATE = 14;

  public static final int CRC32_0 = 15;
  public static final int CRC32_1 = 16;
  public static final int CRC32_2 = 17;

  public static final int SET_BUFSZ = 18;
  public static final int GET_BUFSZ = 19;
  public static final int GET_QSIZE = 20;

  public static final int ADLER32_1 = 21;
  public static final int ADLER32_2 = 22;

  public static final int CRC32_COMBINE = 23;
  public static final int ADLER32_COMBINE = 24;

  private Inflater inflater;
  private Deflater deflater;

  public ZLibDriver(EDriver driver, EString command) {
    super(driver);
  }
 
  ArrayList<ByteBuffer> inbuf = new ArrayList<ByteBuffer>();

  @Override
  protected void output(EHandle caller, ByteBuffer buf) throws IOException,
      Pausable {
    inbuf.add(buf);
  }
 
  @Override
  protected void outputv(EHandle caller, ByteBuffer[] buf) throws IOException,
      Pausable {
    for (int i = 0; i < buf.length; i++) {
      inbuf.add(buf[i]);
    }
  }
 
  int do_inflate(int flush_mode) throws Pausable {
    int err = JZlib.Z_OK;
   
    read_loop:
    for (int i = 0; err==JZlib.Z_OK && i < inbuf.size(); i++) {
     
      ByteBuffer bb = inbuf.get(i);
     
      inflater.setInput(bb.array(), bb.arrayOffset() + bb.position(), bb.remaining(), true);

      int in_size = bb.remaining();
      ByteBuffer out = ByteBuffer.allocate(1024);       
      do {
        long read_before = inflater.total_in;
        long wrote_before = inflater.total_out;

        inflater.next_out = out.array();
        inflater.next_out_index = out.arrayOffset() + out.position();
        inflater.avail_out = out.remaining();
         
        err = inflater.inflate(flush_mode);

        if (err == JZlib.Z_OK || err == JZlib.Z_STREAM_END) {
       
          long read_after = inflater.total_in;
          long wrote_after = inflater.total_out;
         
          in_size -= (read_after-read_before);
         
          int written = (int) (wrote_after - wrote_before);
          out.position(written);
         
          driver_output(out);
          out = ByteBuffer.allocate(1024);       
        }

      } while(err==JZlib.Z_OK && in_size > 0);
    }
   
    inbuf.clear();
   
    if (flush_mode == Z_FINISH) {
      inflater.free();
    }
   
    return err;
  }
 
  void do_deflate(int flush_mode) throws Pausable {
    int err = JZlib.Z_OK;

    read_loop:
    for (int i = 0; err==JZlib.Z_OK && i < inbuf.size(); i++) {

      ByteBuffer bb = inbuf.get(i);

      deflater.next_in = bb.array();
      deflater.next_in_index = bb.arrayOffset() + bb.position();
      deflater.avail_in = bb.remaining();

  //    inf.setInput(bb.array(), bb.arrayOffset()+bb.position(), bb.limit());

      int in_size = bb.remaining();
      do {
        ByteBuffer out = ByteBuffer.allocate(1024);       

        long read_before = deflater.total_in;
        long wrote_before = deflater.total_out;

        deflater.next_out = out.array();
        deflater.next_out_index = out.arrayOffset() + out.position();
        deflater.avail_out = out.remaining();

        err = deflater.deflate(flush_mode);

        if (err == JZlib.Z_OK || err == JZlib.Z_STREAM_END) {

          long read_after = deflater.total_in;
          long wrote_after = deflater.total_out;

          in_size -= (read_after-read_before);

          int written = (int) (wrote_after - wrote_before);
          out.position(written);

          driver_output(out);

        }

      } while(err==JZlib.Z_OK && in_size > 0);
    }

    inbuf.clear();

    if (flush_mode == Z_FINISH) {
      deflater.free();
    }
  }
 
  @Override
  protected ByteBuffer control(EPID caller, int command, ByteBuffer cmd)
      throws Pausable {

    switch (command) {
    case INFLATE_INIT:
    {
      this.inflater = new Inflater();
      this.inflater.inflateInit(true);
      return reply_ok();
    }
    case INFLATE_INIT2:
    {
      int ws = cmd.getInt();
      this.inflater = new Inflater();
      this.inflater.inflateInit(ws);
      return reply_ok();
    }
    case DEFLATE_INIT2:
    {
      int level = cmd.getInt();
      int method = cmd.getInt();
      int bits = cmd.getInt();
      int memlevel = cmd.getInt();
      int strategy = cmd.getInt();
      this.deflater = new Deflater();
      this.deflater.deflateInit(level, bits, memlevel);
      this.deflater.deflateParams(level, strategy);
      return reply_ok();
    }
    case INFLATE: {
      int flush_mode = cmd.getInt();
      int err = do_inflate(flush_mode);
      if (err == JZlib.Z_NEED_DICT) {
        return reply_need_dict(inflater.getAdler());
      }
      return reply_ok();
    }
    case INFLATE_END: {
      do_inflate(Z_FINISH);
      return reply_ok();
    }
    case DEFLATE: {
      int flush_mode = cmd.getInt();
      do_deflate(flush_mode);
      return reply_ok();
    }
    case DEFLATE_END: {
      do_deflate(Z_FINISH);
      return reply_ok();
    }
    case CRC32_0: {
      if (deflater != null) {
        return reply_int( deflater.getAdler() );
      }
      if (inflater != null) {
        return reply_int( inflater.getAdler() );
      }
      return reply_int(0);
    }
    case CRC32_1: {
      CRC32 crc = new CRC32();
      crc.update(cmd.array(), cmd.arrayOffset()+cmd.position(), cmd.remaining());
      return reply_int((int) crc.getValue());
    }
    case CRC32_2: {
      CRC32 crc = new CRC32();
      long init = cmd.getInt() & 0xffffffffL;
      crc.reset(init);
      crc.update(cmd.array(), cmd.arrayOffset()+cmd.position(), cmd.remaining());
      return reply_int((int) crc.getValue());
    }
    }

    throw new erjang.NotImplemented("command="+command+"; data="+EBinary.make(cmd));
  }

  private ByteBuffer reply_ok() {
    ByteBuffer ok = ByteBuffer.allocate(3);
    ok.put((byte) 0);
    ok.put((byte) 'o');
    ok.put((byte) 'k');
    return ok;
  }

  private ByteBuffer reply_error(String atom) {
    ByteBuffer err = ByteBuffer.allocate(1 + atom.length());
    err.put((byte) 1);
    err.put( atom.getBytes(StandardCharsets.UTF_8) );
    return err;
  }

  private ByteBuffer reply_int(long l) {
    ByteBuffer ok = ByteBuffer.allocate(5);
    ok.put((byte) 2);
    ok.putInt((int)l);
    return ok;
  }

  private ByteBuffer reply_need_dict(long l) {
    ByteBuffer ok = ByteBuffer.allocate(5);
    ok.put((byte) 3);
    ok.putInt((int) l);
    return ok;
  }

  @Override
  protected void readyAsync(EAsync data) throws Pausable {
    data.ready();
  }

}
TOP

Related Classes of erjang.driver.zlib.ZLibDriver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.