// ddiff/dpatch - manipulate differences between debian packages.
// Copyright 2000 Tom Rothamel <tom-ddiff@onegeek.org>
//
// This program 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.
//
// This program 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.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  

#ifndef GENFILE_H
#define GENFILE_H

// A list of tar header blocks associated with the current file.
struct TarBlock {
	TarBlock *next;
	char data[512];
};

// Information about the files contained in an archive, broken out so that
// it can be passed around to other modules.
struct FINFO {
	// Common Members
	char *name;
	long size;    			  

	// Only used for ar-archives.
	long mtime;	
	int uid;
	int gid;
	int mode;

	// Only used for tar-archives.
	TarBlock *tar;
	char type;

	// Only used for gzip files.
	char *hdr;
	int hl;	
	int method;
	int extra;
	
	FINFO();
      	~FINFO();
};

// A generic file, with methods that sorta resemble the stdio methods.
struct GFILE {
	// This is only really set if we're a gfarchive. Don't rely
	// on it otherwise.
	FINFO *finfo;

	// like the corresponding stdio functions.
	virtual char *gets(char *, int) = 0;
	virtual size_t read(void *, size_t, size_t) = 0;
	virtual void seek(long) = 0;
	virtual void skip(long) = 0;
	virtual long tell() = 0;

	// Duplicate this gfile. Please note that this will loose the
	// stored in finfo.
	virtual GFILE *dup() = 0;
	
	GFILE();
	virtual ~GFILE();
};

// A garchive attempts to represent the structure of a GFILE. As new
// members are accessed, the GARCHIVE acts like a GFILE for them.
struct GARCHIVE : public GFILE {
	virtual void reset() = 0;
	/* Member returns 1 if there is another member, 0 if not. */
	virtual int member() = 0;	

	int findfwd(char *);
	int find(char *);
};

// gfarchive.cc
GARCHIVE *open_gfarchive(GFILE *);

// gfgzip.cc
GFILE *open_gfgzip(GFILE *);

// gfpipe.cc
extern void (*on_gfpipe)();
GFILE *open_gfpipe(char *, GFILE *);

// gfstdio.cc
GFILE *open_gfstdio(char *);

// gftar.cc
GARCHIVE *open_gftar(GFILE *);

// gfutil.cc
char *extrstr(char *, char *, int);
int extrint(char *, int);
int extroct(char *, int);
long extrlong(char *, int);


#endif
