⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 token.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Routines used by the file-transfer code. * * Copyright (C) 1996 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2003-2008 Wayne Davison * * 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 3 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, visit the http://fsf.org website. */#include "rsync.h"#include "ifuncs.h"#include "zlib/zlib.h"extern int do_compression;extern int module_id;extern int def_compress_level;extern char *skip_compress;static int compression_level, per_file_default_level;struct suffix_tree {	struct suffix_tree *sibling;	struct suffix_tree *child;	char letter, word_end;};static char *match_list;static struct suffix_tree *suftree;static void add_suffix(struct suffix_tree **prior, char ltr, const char *str){	struct suffix_tree *node, *newnode;	if (ltr == '[') {		const char *after = strchr(str, ']');		/* Just skip bogus character classes. */		if (!after++)			return;		while ((ltr = *str++) != ']')			add_suffix(prior, ltr, after);		return;	}	for (node = *prior; node; prior = &node->sibling, node = node->sibling) {		if (node->letter == ltr) {			if (*str)				add_suffix(&node->child, *str, str+1);			else				node->word_end = 1;			return;		}		if (node->letter > ltr)			break;	}	if (!(newnode = new(struct suffix_tree)))		out_of_memory("add_suffix");	newnode->sibling = node;	newnode->child = NULL;	newnode->letter = ltr;	*prior = newnode;	if (*str) {		add_suffix(&newnode->child, *str, str+1);		newnode->word_end = 0;	} else		newnode->word_end = 1;}static void add_nocompress_suffixes(const char *str){	char *buf, *t;	const char *f = str;	if (!(buf = new_array(char, strlen(f) + 1)))		out_of_memory("add_nocompress_suffixes");	while (*f) {		if (*f == '/') {			f++;			continue;		}		t = buf;		do {			if (isUpper(f))				*t++ = toLower(f);			else				*t++ = *f;		} while (*++f != '/' && *f);		*t++ = '\0';		fprintf(stderr, "adding `%s'\n", buf);		add_suffix(&suftree, *buf, buf+1);	}	free(buf);}static void init_set_compression(void){	const char *f;	char *t, *start;	if (skip_compress)		add_nocompress_suffixes(skip_compress);	/* A non-daemon transfer skips the default suffix list if the	 * user specified --skip-compress. */	if (skip_compress && module_id < 0)		f = "";	else		f = lp_dont_compress(module_id);	if (!(match_list = t = new_array(char, strlen(f) + 2)))		out_of_memory("set_compression");	per_file_default_level = def_compress_level;	while (*f) {		if (*f == ' ') {			f++;			continue;		}		start = t;		do {			if (isUpper(f))				*t++ = toLower(f);			else				*t++ = *f;		} while (*++f != ' ' && *f);		*t++ = '\0';		if (t - start == 1+1 && *start == '*') {			/* Optimize a match-string of "*". */			*match_list = '\0';			suftree = NULL;			per_file_default_level = 0;			break;		}		/* Move *.foo items into the stuffix tree. */		if (*start == '*' && start[1] == '.' && start[2]		 && !strpbrk(start+2, ".?*")) {			add_suffix(&suftree, start[2], start+3);			t = start;		}	}	*t++ = '\0';}/* determine the compression level based on a wildcard filename list */void set_compression(const char *fname){	const struct suffix_tree *node;	const char *s;	char ltr;	if (!do_compression)		return;	if (!match_list)		init_set_compression();	compression_level = per_file_default_level;	if (!*match_list && !suftree)		return;	if ((s = strrchr(fname, '/')) != NULL)		fname = s + 1;	for (s = match_list; *s; s += strlen(s) + 1) {		if (iwildmatch(s, fname)) {			compression_level = 0;			return;		}	}	if (!(node = suftree) || !(s = strrchr(fname, '.'))	 || s == fname || !(ltr = *++s))		return;	while (1) {		while (node->letter != ltr) {			if (node->letter > ltr)				return;			if (!(node = node->sibling))				return;		}		if ((ltr = *++s) == '\0') {			if (node->word_end)				compression_level = 0;			return;		}		if (!(node = node->child))			return;	}}/* non-compressing recv token */static int32 simple_recv_token(int f, char **data){	static int32 residue;	static char *buf;	int32 n;	if (!buf) {		buf = new_array(char, CHUNK_SIZE);		if (!buf)			out_of_memory("simple_recv_token");	}	if (residue == 0) {		int32 i = read_int(f);		if (i <= 0)			return i;		residue = i;	}	*data = buf;	n = MIN(CHUNK_SIZE,residue);	residue -= n;	read_buf(f,buf,n);	return n;}/* non-compressing send token */static void simple_send_token(int f, int32 token, struct map_struct *buf,			      OFF_T offset, int32 n){	if (n > 0) {		int32 len = 0;		while (len < n) {			int32 n1 = MIN(CHUNK_SIZE, n-len);			write_int(f, n1);			write_buf(f, map_ptr(buf, offset+len, n1), n1);			len += n1;		}	}	/* a -2 token means to send data only and no token */	if (token != -2)		write_int(f, -(token+1));}/* Flag bytes in compressed stream are encoded as follows: */#define END_FLAG	0	/* that's all folks */#define TOKEN_LONG	0x20	/* followed by 32-bit token number */#define TOKENRUN_LONG	0x21	/* ditto with 16-bit run count */#define DEFLATED_DATA	0x40	/* + 6-bit high len, then low len byte */#define TOKEN_REL	0x80	/* + 6-bit relative token number */#define TOKENRUN_REL	0xc0	/* ditto with 16-bit run count */#define MAX_DATA_COUNT	16383	/* fit 14 bit count into 2 bytes with flags *//* zlib.h says that if we want to be able to compress something in a single * call, avail_out must be at least 0.1% larger than avail_in plus 12 bytes. * We'll add in 0.1%+16, just to be safe (and we'll avoid floating point, * to ensure that this is a compile-time value). */#define AVAIL_OUT_SIZE(avail_in_size) ((avail_in_size)*1001/1000+16)/* For coding runs of tokens */static int32 last_token = -1;static int32 run_start;static int32 last_run_end;/* Deflation state */static z_stream tx_strm;/* Output buffer */static char *obuf;/* We want obuf to be able to hold both MAX_DATA_COUNT+2 bytes as well as * AVAIL_OUT_SIZE(CHUNK_SIZE) bytes, so make sure that it's large enough. */#if MAX_DATA_COUNT+2 > AVAIL_OUT_SIZE(CHUNK_SIZE)#define OBUF_SIZE	(MAX_DATA_COUNT+2)#else#define OBUF_SIZE	AVAIL_OUT_SIZE(CHUNK_SIZE)#endif/* Send a deflated token */static voidsend_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,		    int32 nb, int32 toklen){	int32 n, r;	static int init_done, flush_pending;	if (last_token == -1) {		/* initialization */		if (!init_done) {			tx_strm.next_in = NULL;			tx_strm.zalloc = NULL;			tx_strm.zfree = NULL;			if (deflateInit2(&tx_strm, compression_level,					 Z_DEFLATED, -15, 8,					 Z_DEFAULT_STRATEGY) != Z_OK) {				rprintf(FERROR, "compression init failed\n");				exit_cleanup(RERR_STREAMIO);			}			if ((obuf = new_array(char, OBUF_SIZE)) == NULL)				out_of_memory("send_deflated_token");			init_done = 1;		} else			deflateReset(&tx_strm);		last_run_end = 0;		run_start = token;		flush_pending = 0;	} else if (last_token == -2) {		run_start = token;	} else if (nb != 0 || token != last_token + 1		   || token >= run_start + 65536) {		/* output previous run */		r = run_start - last_run_end;

⌨️ 快捷键说明

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