zlib.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 485 行

JAVA
485
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Charles Reich */package com.caucho.quercus.lib.zlib;import com.caucho.quercus.QuercusModuleException;import com.caucho.quercus.annotation.NotNull;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.env.*;import com.caucho.quercus.lib.file.FileValue;import com.caucho.quercus.lib.string.StringModule;import com.caucho.util.L10N;import com.caucho.vfs.TempBuffer;import java.io.IOException;import java.io.InputStream;import java.util.logging.Level;import java.util.logging.Logger;import java.util.zip.DataFormatException;import java.util.zip.Deflater;/** * Zlib object oriented API facade */public class Zlib {  private static final Logger log = Logger.getLogger(Zlib.class.getName());  private static final L10N L = new L10N(Zlib.class);  private InputStream _in;  private ZlibOutputStream _gzout;  private FileValue _fileValue;  private boolean _isGZIPInputStream;  /**   * XXX: todo - implement additional read/write modes (a,etc)   *   * Creates and sets GZIP stream if mode is 'w'   * Also creates _fileValue.  All write functions are wrappers around   * the _fileValue functions using the private class GZFileValueWriter to   * compress the byte stream.   *   *   * @param fileName   * @param mode (ie: "w9" or "r7f")   * @param useIncludePath is always on   */  public Zlib(Env env, String filename, String mode, boolean useIncludePath)  {    String filemode = getFileMode(mode);    int compressionLevel = getCompressionLevel(mode);    int compressionStrategy = getCompressionStrategy(mode);    Value val = null;    // FileModule.fopen(env, filename, mode, useIncludePath, null);        if (val != BooleanValue.FALSE)      _fileValue = (FileValue)val;      /*    try {      if (filemode.equals("r")) {        _in = getGZIPInputStream();      }      else if (filemode.equals("w")) {        _gzout = new ZlibOutputStream(_fileValue.getPath().openWrite(),				      compressionLevel,				      compressionStrategy);      }      else if (filemode.equals("a")) {        _gzout = new ZlibOutputStream(_fileValue.getPath().openAppend(),				      compressionLevel,				      compressionStrategy);      }      else if (filemode.equals("x")) {        _gzout = new ZlibOutputStream(_fileValue.getPath().openWrite(),				      compressionLevel,				      compressionStrategy);      }    }    catch (IOException e) {      log.log(Level.FINE, e.getMessage(), e);      env.warning(L.l(e.getMessage()));    }      */  }  /**   * Reads from the input and writes to the gzip stream   * @param s   * @param length # of bytes to compress   * @return # of uncompressed bytes   */  public int gzwrite(Env env, InputStream is, @Optional("-1") int length)  {    if (_fileValue == null) {      env.warning(L.l("file could not be open for writing"));      return -1;    }    TempBuffer tb = TempBuffer.allocate();    byte[] buffer = tb.getBuffer();    int inputSize = 0;    int sublen;    if (length < 0)      length = Integer.MAX_VALUE;    try {      while (length > 0) {	if (buffer.length < length)	  sublen = buffer.length;	else	  sublen = length;	sublen = is.read(buffer, 0, sublen);	if (sublen <= 0)	  break;	_gzout.write(buffer, 0, sublen);		inputSize += sublen;	length -= sublen;      }    }    catch (IOException e) {      log.log(Level.FINE, e.getMessage(), e);      env.warning(L.l(e.getMessage()));    }        TempBuffer.free(tb);    return inputSize;  }  /**   * Closes the gzip stream   * @return true if successful, false otherwise   */  public boolean gzclose()  {    if (_fileValue == null) {      return false;    }    try {      if (_gzout != null) {        _gzout.close();        _gzout = null;      }            if (_in != null) {        _in.close();        _in = null;      }    }    catch (Exception e) {      throw QuercusModuleException.create(e);    }    return true;  }  /**   * alias of gzwrite   * @param env   * @param s   * @param length   * @return # of uncompressed bytes   */  public int gzputs(Env env,		    @NotNull InputStream is,		    @Optional("-1") int length)  {    return gzwrite(env, is, length);  }  /**   *   * @return the next character or BooleanValue.FALSE   */  public Value gzgetc(Env env)  {    try {      int ch = _in.read();      if (ch >= 0)        return env.createString(Character.toString((char) ch));      else	return BooleanValue.FALSE;    } catch (IOException e) {      throw QuercusModuleException.create(e);    }  }  /**   * Gets a (uncompressed) string of up to 'length' bytes read   * from the given file pointer. Reading ends when 'length' bytes   * have been read, on a newline, or on EOF (whichever comes first).   *   * @param length   * @return StringValue   */  @ReturnNullAsFalse  public StringValue gzgets(int length)  {    if (_in == null)      return null;    UnicodeBuilderValue sbv = new UnicodeBuilderValue();    int readChar;    try {      for (int i = 0; i < length - 1; i++) {        readChar = _in.read();	        if (readChar >= 0) {          sbv.append((char) readChar);	            if (readChar == '\n' || readChar == '\r')            break;        } else          break;      }    } catch (Exception e) {      throw QuercusModuleException.create(e);    }    if (sbv.length() > 0)      return sbv;    else      return null;  }  /**   * helper function for ZlibModule.gzfile   * need to have created a Zlib before calling this   *   * @return array of uncompressed lines   * @throws IOException   * @throws DataFormatException   */  public ArrayValue gzfile()  {    Value line;    int oldLength = 0;     ArrayValue array = new ArrayValueImpl();    try {      //read in String BuilderValue's initial capacity      while ((line = gzgets(Integer.MAX_VALUE)) != BooleanValue.FALSE) {        array.put(line);      }      return array;    } catch (Exception e) {      throw QuercusModuleException.create(e);    }  }  /**   * same as gzgets but does not stop at '\n' or '\r'   * @param length   * @return BinaryValue, an empty BinaryValue if no data read   * @throws IOException   * @throws DataFormatException   */  public StringValue gzread(Env env, int length)  {    StringValue sb = env.createBinaryBuilder();    int readChar;    if (_in == null)      return sb;    sb.appendReadAll(_in, length);    return sb;  }  /**   *   * @return true if eof   */  public boolean gzeof()  {    if (_isGZIPInputStream)      return ((GZIPInputStream)_in).isEOS();    else {      try {        _in.mark(1);        int ch = _in.read();        _in.reset();        return (ch == -1);      } catch (IOException e) {        throw new QuercusModuleException(e);      }    }  }  /**   *   * @param length   * @param allowedTags   * @return next line stripping tags   * @throws IOException   * @throws DataFormatException   */  @ReturnNullAsFalse  public StringValue gzgetss(int length,			     @Optional String allowedTags)  {    try {      if (_in == null)        return null;      UnicodeBuilderValue sbv = new UnicodeBuilderValue();      int readChar;      for (int i=0; i < length; i++) {        readChar = _in.read();        if (readChar >= 0) {          sbv.append((char)readChar);          if (readChar == '\n' || readChar == '\r')            break;        } else          break;      }      if (sbv.length() > 0)	return StringModule.strip_tags(sbv, allowedTags);      else	return null;    } catch (Exception e) {      throw QuercusModuleException.create(e);    }  }  /**   * resets to the beginning of the file stream.   *   * @return always true   * @throws IOException   */  public boolean gzrewind()  {    try {      if (_in != null )        _in.close();      _in = getGZIPInputStream();    }    catch (IOException e)    {      throw QuercusModuleException.create(e);    }    return true;  }  /**   * helper function to open file for reading when necessary   *   * @throws IOException   */  protected InputStream getGZIPInputStream()    throws IOException  {    try {      _isGZIPInputStream = true;      return new GZIPInputStream(_fileValue.getPath().openRead());    }    catch (IOException e) {      //GZIPInputStream throws an Exception if not in gzip format      //else open uncompressed stream      _isGZIPInputStream = false;      return _fileValue.getPath().openRead();    }  }  /**   * Helper function to retrieve the filemode closest to the end   * Note: PHP5 unexpectedly fails when 'x' is the mode.   *   * XXX todo: toss a warning if '+' is found (gzip cannot be open for both reading and writing at the same time)   *   */  private String getFileMode(String input)  {    String modifier = "";    String filemode = input.substring(0, 1);    for (int i = 1; i < input.length(); i++ )    {      char ch = input.charAt(i);      switch (ch) {        case 'r':          filemode = "r";          break;        case 'w':          filemode = "w";          break;        case 'a':          filemode = "a";          break;        case 'b':          modifier = "b";          break;        case 't':          modifier = "t";          break;      }    }    return filemode + modifier;  }  /**   * Helper function to retrieve the compression level like how PHP5 does it.   * 	1. finds the compression level nearest to the end and returns that   */  private int getCompressionLevel(String input)  {    for( int i = input.length() - 1; i >= 0; i-- )    {      char ch = input.charAt(i);      if( ch >= '0' && ch <= '9' )        return ch - '0';    }    return Deflater.DEFAULT_COMPRESSION;  }  /**   * Helper function to retrieve the compression strategy like how PHP5 does it.   * 	1. finds the compression strategy nearest to the end and returns that   */  private int getCompressionStrategy(String input)  {    for( int i = input.length() - 1; i >= 0; i-- )    {      char ch = input.charAt(i);      switch (ch) {      case 'f':        return Deflater.FILTERED;      case 'h':        return Deflater.HUFFMAN_ONLY;      }    }    return Deflater.DEFAULT_STRATEGY;  }  public String toString()  {    return "Zlib[]";  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?