function varargout = gzip(files, varargin)
%GZIP Compress files into the GZIP format.
%   GZIP(FILES) creates GZIP-files from the list of files specified in
%   FILES.
%
%   FILES is a string or cell array of strings containing a list of files
%   or directories to gzip. Paths specified in FILES must be either
%   relative to the current directory or absolute. Directories recursively
%   gzip all of their content.  The output gzipped files are written to the
%   same directory as the input files and with the file extension '.gz'.
%
%   GZIP(FILES,OUTPUTDIR) writes the gzipped file into the directory
%   OUTPUTDIR. OUTPUTDIR is created if it does not exist.
%
%   FILENAMES = GZIP(...) gzips the files and returns the relative path
%   names of the gzipped files into the string cell array, FILENAMES.
%
%   Example
%   -------
%   % gzip all *.m and *.mat files in the current directory and store the
%   % results into the directory 'archive'.
%   gzip({'*.m','*.mat'},'archive');
%
%   See also GUNZIP, TAR, UNTAR, UNZIP, ZIP.

%   Copyright 2004 The MathWorks, Inc.
%   $Revision: 1.1.6.1 $   $Date: 2004/11/23 20:39:48 $


error(nargchk(1,2,nargin,'struct'))
error(nargoutchk(0,1,nargout,'struct'));

% rootDir is always ''
dirs = {'',varargin{:}};

% Check input arguments.
[files, rootDir, outputDir] = checkFilesDirInputs(mfilename, files, dirs{:});

% Get entries
entries = getArchiveEntries('', files, rootDir, mfilename);

% Gzip the files
names = gzipwrite(entries, outputDir);

% Return the names if requested 
if nargout == 1
   varargout{1} = names;
end

%----------------------------------------------------------------------
function gzipFilenames = gzipwrite(entries, outputDir)

% This InterruptibleStreamCopier is unsupported and may change without notice.
streamCopier = ...
   com.mathworks.mlwidgets.io.InterruptibleStreamCopier.getInterruptibleStreamCopier;

% Process entries
gzipFilenames = {};
gzipExt = '.gz';
for i=1:numel(entries)
  filename = entries(i).file;
  [path, baseName ext] = fileparts(filename);
  if isempty(outputDir)
     outputDir = path;
  elseif ~isempty(outputDir) && ~isAbsolute(outputDir) && ~isequal('.',outputDir)
     outputDir = fullfile('.',outputDir);
  end
  gzipFilename = fullfile(outputDir,[ baseName ext gzipExt]);

  % Create input streams
  fileInStream = [];
  try
     javaInFile   = java.io.File(filename);
     fileInStream = java.io.FileInputStream(javaInFile);
  catch
     % Unable to access file
     if ~isempty(fileInStream)
       fileInStream.close;
     end
     eid = sprintf('MATLAB:%s:javaOpenError',mfilename);
     error(eid,'Could not open file "%s" for reading.',filename);
  end

  % Create output streams
  try
     fileOutStream = java.io.FileOutputStream(java.io.File(gzipFilename));
     gzipOutStream = java.util.zip.GZIPOutputStream( fileOutStream );
  catch
     % Not in gzip format
     if ~isempty(fileInStream)
       fileInStream.close;
     end
     eid = sprintf('MATLAB:%s:javaOutputOpenError',mfilename);
     error(eid,'Could not open file "%s" for writing.',gzipFilename);
  end
   
  % gzip the file
  streamCopier.copyStream(fileInStream,gzipOutStream);
  
  % Cleanup and close the streams
  fileInStream.close;
  gzipOutStream.close;
  
  if ispc
     gzipFilenames{end+1} = strrep(gzipFilename,'\','/');
  else
     gzipFilenames{end+1} = gzipFilename;
  end
 end
