// 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.  

#include <stdio.h>
#include "debdiff.h"

char quotebuf[1024];

char *quote(char *s) {
	char *o;
	int i;
	
	o = quotebuf;
	
	for (i = 0; i<512; i++) {
		switch(*s) {
		case '\\':
			*o++ = '\\';
			*o++ = '\\';
			break;
		case '"':
			*o++ = '\\';
			*o++ = '"';
			break;
		case '\n':
			*o++ = '\\';
			*o++ = '\n';
		default:
			*o++ = *s;
		}

		if (!*s) return quotebuf;
		s++;
	}

	*o = 0;
	return NULL;
}

FILE *fdevnull() {
	static FILE *dn = NULL;
	if (dn) return dn;

	dn = fopen("/dev/null", "w");

	return dn;
}

// Copy data directly into the debdiff.
void straightdata(FILE *of, GFILE *gf) {
	int l;
	int lr;
	char buf[1024];

	gf->seek(0);

	fprintf(of, "data %d\n", gf->finfo->size);

	lr = gf->finfo->size;
	
	while (l = gf->read(buf, 1, (lr > 1024) ? 1024 : lr)) {
		lr -= l;
		fwrite(buf, 1, l, of);
	}
}

// Prints out a command to set the member of interest. Returns the length
// of the output command.
void moi(FILE *f, char *arpart, char *tarpart) {
	fprintf(f, "moi \"%s\"", quote(arpart));
	if (tarpart) fprintf(f, " \"%s\"", quote(tarpart));
	fprintf(f, "\n");
}


// Outputs a bdiff of the two GFILEs given as arguments to the output
// FILE. bdiff_init must have been called already. (Probably in main.)
void writebdiff(FILE *of, GFILE *from, GFILE *to) {
	fprintf(of, "bdiff\n");
	bdiff(from, to, of);
}

// Output a command to copy data directly into the debpatch output,
// Return the length. (from is 

// int copyin(FILE *of, GFILE *from, char *arpart, char *tarpart) {
// 	int hl;

// 	if (!of) of = fdevnull();

// 	hl = moi(of, arpart, tarpart);
// 	hl += fprintf(of, "copy\n");

// 	return hl;
// }

// #define BBB_BLOCK_SIZE 256

// Block-by-block storage of a file. This only copies blocks that
// differ to the stream. It's efficient on files that only change a
// little bit, for example a gzip header date change. Best case
// is l/512 + 1, worst is l + l/512 + 4, I think.
//
// This is worst case in some common cases, like inserting a character.
// However, it comes close to best case in certain common circumstances
// in a deb. (Like the same data being gzipped with 2 timestamps.)

// int blockbyblock(FILE *of, GFILE *from, char *arp, char *tarp,
// 		 GFILE *to) {
// 	int l;
// 	char fromb[BBB_BLOCK_SIZE];
// 	char tob[BBB_BLOCK_SIZE];
// 	int froml;
// 	int tol;
// 	int i;
// 	int same;

	
// 	if (!of) of = fdevnull();

// 	l = moi(of, arp, tarp);
// 	l += fprintf(of, "bbb\n");

// 	from->seek(0);
// 	to->seek(0);
	
// 	while (1) {
// 		froml = from->read(fromb, 1, BBB_BLOCK_SIZE);
// 		tol = to->read(tob, 1, BBB_BLOCK_SIZE);

// 		if (tol == 0) {
// 			l += fprintf(of, "z"); // end of bbb.
// 			return l;
// 		}

// 		if (froml != tol) {
// 			l += fprintf(of, "d%d\n"); // include x bytes of data.
// 			l += fwrite(tob, 1, tol, of);
// 			continue;
// 		}

// 		same = 1;

// 		for (i = 0; i < tol; i++) {
// 			if (tob[i] != fromb[i]) {
// 				same = 0;
// 				break;
// 			}
// 		}

// 		if (same) {
// 			l += fprintf(of, "c"); // copy block.
// 		} else {
// 			l += fprintf(of, "b"); // include one block of data.
// 			l += fwrite(tob, 1, tol, of);
// 		}
// 	}
// }
	
		       
			
	
	
