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

📄 arc.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <stdlib.h>#include "timidity.h"#include "common.h"#include "arc.h"#include "strtab.h"#include "zip.h"#include "unlzh.h"#include "explode.h"char *arc_lib_version = ARC_LIB_VERSION;#define GZIP_ASCIIFLAG		(1u<<0)#define GZIP_MULTIPARTFLAG	(1u<<1)#define GZIP_EXTRAFLAG		(1u<<2)#define GZIP_FILEFLAG		(1u<<3)#define GZIP_COMMFLAG		(1u<<4)#define GZIP_ENCFLAG		(1u<<5)#ifndef TRUE#define TRUE			1#endif /* TRUE */#ifndef FALSE#define FALSE			0#endif /* FALSE */#define ABORT			-1ArchiveHandler arc_handler;static MBlockList arc_buffer;typedef struct _ArchiveFileList{    char *archive_name;    ArchiveEntryNode *entry_list;    struct _ArchiveFileList *next;} ArchiveFileList;static ArchiveFileList *arc_filelist = NULL;static struct{    char *ext;    int type;} archive_ext_list[] ={    {".tar",	ARCHIVE_TAR},    {".tar.gz",	ARCHIVE_TGZ},    {".tgz",	ARCHIVE_TGZ},    {".zip",	ARCHIVE_ZIP},    {".neo",	ARCHIVE_ZIP},    {".lzh",	ARCHIVE_LZH},    {".lha",	ARCHIVE_LZH},    {".mime",	ARCHIVE_MIME},    {PATH_STRING, ARCHIVE_DIR},    {NULL, -1}};int skip_gzip_header(URL url){    unsigned char flags;    int m1, method;    /* magic */    m1 = url_getc(url);    if(m1 == 0)    {	url_skip(url, 128 - 1);	m1 = url_getc(url);    }    if(m1 != 0x1f)	return -1;    if(url_getc(url) != 0x8b)	return -1;    /* method */    method = url_getc(url);    switch(method)    {      case 8:			/* deflated */	method = ARCHIVEC_DEFLATED;	break;      default:	return -1;    }    /* flags */    flags = url_getc(url);    if(flags & GZIP_ENCFLAG)	return -1;    /* time */    url_getc(url); url_getc(url); url_getc(url); url_getc(url);    url_getc(url);		/* extra flags */    url_getc(url);		/* OS type */    if(flags & GZIP_MULTIPARTFLAG)    {	/* part number */	url_getc(url); url_getc(url);    }    if(flags & GZIP_EXTRAFLAG)    {	unsigned short len;	int i;	/* extra field */	len = url_getc(url);	len |= ((unsigned short)url_getc(url)) << 8;	for(i = 0; i < len; i++)	    url_getc(url);    }    if(flags & GZIP_FILEFLAG)    {	/* file name */	int c;	do	{	    c = url_getc(url);	    if(c == EOF)		return -1;	} while(c != '\0');    }    if(flags & GZIP_COMMFLAG)    {	/* comment */	int c;	do	{	    c = url_getc(url);	    if(c == EOF)		return -1;	} while(c != '\0');    }    return method;}int parse_gzip_header_bytes(char *gz, long maxparse, int *hdrsiz){    URL url = url_mem_open(gz, maxparse, 0);    int method;    if(!url)	return -1;    method = skip_gzip_header(url);    *hdrsiz = url_tell(url);    url_close(url);    return method;}void (* arc_error_handler)(char *error_message) = NULL;    static void arc_cant_open(char *s){    if(arc_error_handler != NULL)    {	char buff[BUFSIZ];	snprintf(buff, sizeof(buff), "%s: Can't open", s);	arc_error_handler(buff);    }}int get_archive_type(char *archive_name){    int i, len;    char *p;    int archive_name_length, delim;#ifdef SUPPORT_SOCKET    int type = url_check_type(archive_name);    if(type == URL_news_t)	return ARCHIVE_MIME;    if(type == URL_newsgroup_t)	return ARCHIVE_NEWSGROUP;#endif /* SUPPORT_SOCKET */    if(strncmp(archive_name, "mail:", 5) == 0 ||       strncmp(archive_name, "mime:", 5) == 0)	return ARCHIVE_MIME;    if((p = strrchr(archive_name, '#')) != NULL)    {	archive_name_length = p - archive_name;	delim = '#';    }    else    {	archive_name_length = strlen(archive_name);	delim = '\0';    }    for(i = 0; archive_ext_list[i].ext; i++)    {	len = strlen(archive_ext_list[i].ext);	if(len <= archive_name_length &&	   strncasecmp(archive_name + archive_name_length - len,		       archive_ext_list[i].ext, len) == 0 &&	   archive_name[archive_name_length] == delim)	    return archive_ext_list[i].type; /* Found */    }    if(url_check_type(archive_name) == URL_dir_t)	return ARCHIVE_DIR;    return -1;			/* Not found */}static ArchiveFileList *find_arc_filelist(char *basename){    ArchiveFileList *p;    for(p = arc_filelist; p; p = p->next)    {	if(strcmp(basename, p->archive_name) == 0)	    return p;    }    return NULL;}ArchiveEntryNode *arc_parse_entry(URL url, int archive_type){    ArchiveEntryNode *entry_first, *entry_last, *entry;    ArchiveEntryNode *(* next_header_entry)(void);    int gzip_method;    URL orig;    orig = NULL;    switch(archive_type)    {      case ARCHIVE_TAR:	next_header_entry = next_tar_entry;	break;      case ARCHIVE_TGZ:	gzip_method = skip_gzip_header(url);	if(gzip_method != ARCHIVEC_DEFLATED)	{	    url_close(url);	    return NULL;	}	orig = url;	if((url = url_inflate_open(orig, -1, 0)) == NULL)	    return NULL;	next_header_entry = next_tar_entry;	break;      case ARCHIVE_ZIP:	next_header_entry = next_zip_entry;	break;      case ARCHIVE_LZH:	next_header_entry = next_lzh_entry;	break;      case ARCHIVE_MIME:	if(!IS_URL_SEEK_SAFE(url))	{	    orig = url;	    if((url = url_cache_open(orig, 0)) == NULL)		return NULL;	}	next_header_entry = next_mime_entry;	break;      default:	return NULL;    }    arc_handler.isfile = (url->type == URL_file_t);    arc_handler.url = url;    arc_handler.counter = 0;    entry_first = entry_last = NULL;    arc_handler.pos = 0;    while((entry = next_header_entry()) != NULL)    {	if(entry_first != NULL)	    entry_last->next = entry;	else	    entry_first = entry_last = entry;	while(entry_last->next)	    entry_last = entry_last->next;	arc_handler.counter++;    }    url_close(url);    if(orig)	url_close(orig);    return entry_first;		/* Note that NULL if no archive file */}static ArchiveFileList *add_arc_filelist(char *basename, int archive_type){    URL url;    ArchiveFileList *afl;    ArchiveEntryNode *entry;    switch(archive_type)    {      case ARCHIVE_TAR:      case ARCHIVE_TGZ:      case ARCHIVE_ZIP:      case ARCHIVE_LZH:      case ARCHIVE_MIME:	break;      default:	return NULL;    }    if((url = url_open(basename)) == NULL)    {	arc_cant_open(basename);	return NULL;    }    entry = arc_parse_entry(url, archive_type);    afl = (ArchiveFileList *)safe_malloc(sizeof(ArchiveFileList));    afl->archive_name = safe_strdup(basename);    afl->entry_list = entry;    afl->next = arc_filelist;    arc_filelist = afl;    return afl;}static ArchiveFileList *regist_archive(char *archive_filename){    int archive_type;    if((archive_type = get_archive_type(archive_filename)) < 0)	return NULL;		/* Unknown archive */    archive_filename = url_expand_home_dir(archive_filename);    if(find_arc_filelist(archive_filename))	return NULL;		/* Already registerd */    return add_arc_filelist(archive_filename, archive_type);}static int arc_expand_newfile(StringTable *s, ArchiveFileList *afl,			      char *pattern){    ArchiveEntryNode *entry;    char *p;    for(entry = afl->entry_list; entry; entry = entry->next)    {	if(arc_case_wildmat(entry->name, pattern))	{	    p = new_segment(&arc_buffer, strlen(afl->archive_name) +			    strlen(entry->name) + 2);	    strcpy(p, afl->archive_name);	    strcat(p, "#");	    strcat(p, entry->name);	    if(put_string_table(s, p, strlen(p)) == NULL)		return -1;	}    }    return 0;}char **expand_archive_names(int *nfiles_in_out, char **files){    int i, nfiles, arc_type;    char *infile_name;    char *base, *pattern, *p, buff[BUFSIZ];    char *one_file[1];    int one;    ArchiveFileList *afl;    /* Recusive global */    static MBlockList *pool;    static StringTable stab;    static int error_flag = 0;    static int depth = 0;    if(depth == 0)    {	error_flag = 0;	init_string_table(&stab);	pool = &arc_buffer;    }    nfiles = *nfiles_in_out;    for(i = 0; i < nfiles; i++)    {	infile_name = url_expand_home_dir(files[i]);	if((p = strrchr(infile_name, '#')) == NULL)	{	    base = infile_name;	    pattern = "*";	}	else	{	    int len = p - infile_name;	    base = new_segment(pool, len + 1); /* +1 for '\0' */	    memcpy(base, infile_name, len);	    base[len] = '\0';	    pattern = p + 1;	}	if((afl = find_arc_filelist(base)) != NULL)	{	    if(arc_expand_newfile(&stab, afl, pattern) == -1)		goto abort_expand;	    continue;	}	arc_type = get_archive_type(base);	if(arc_type == -1)	{	    if(put_string_table(&stab, infile_name, strlen(infile_name))	       == NULL)		goto abort_expand;	    continue;	}#ifdef SUPPORT_SOCKET	if(arc_type == ARCHIVE_NEWSGROUP)	{	    URL url;	    int len1, len2;	    char *news_prefix;	    if((url = url_newsgroup_open(base)) == NULL)	    {		arc_cant_open(base);		continue;	    }	    strncpy(buff, base, sizeof(buff)-1);	    p = strchr(buff + 7, '/') + 1; /* news://..../ */	    *p = '\0';	    news_prefix = strdup_mblock(pool, buff);	    len1 = strlen(news_prefix);	    while(url_gets(url, buff, sizeof(buff)))	    {		len2 = strlen(buff);		p = (char *)new_segment(pool, len1 + len2 + 1);		strcpy(p, news_prefix);		strcpy(p + len1, buff);		one_file[0] = p;		one = 1;		depth++;		expand_archive_names(&one, one_file);		depth--;	    }	    url_close(url);	    if(error_flag)		goto abort_expand;	    continue;	}#endif /* SUPPORT_SOCKET */	if(arc_type == ARCHIVE_DIR)	{	    URL url;	    int len1, len2;	    if((url = url_dir_open(base)) == NULL)	    {		arc_cant_open(base);		continue;	    }	    if(strncmp(base, "dir:", 4) == 0)		base += 4;	    len1 = strlen(base);	    if(IS_PATH_SEP(base[len1 - 1]))		len1--;	    while(url_gets(url, buff, sizeof(buff)))	    {		if(strcmp(buff, ".") == 0 || strcmp(buff, "..") == 0)		    continue;		len2 = strlen(buff);		p = (char *)new_segment(pool, len1 + len2 + 2);		strcpy(p, base);		p[len1] = PATH_SEP;		strcpy(p + len1 + 1, buff);		one_file[0] = p;		one = 1;		depth++;		expand_archive_names(&one, one_file);		depth--;	    }	    url_close(url);	    if(error_flag)		goto abort_expand;	    continue;	}	if((afl = add_arc_filelist(base, arc_type)) != NULL)	{	    if(arc_expand_newfile(&stab, afl, pattern) == -1)		goto abort_expand;	}    }    if(depth)	return NULL;    *nfiles_in_out = stab.nstring;    reuse_mblock(pool);    return make_string_array(&stab); /* It is possible NULL */  abort_expand:    error_flag = 1;    if(depth)	return NULL;    delete_string_table(&stab);    free_global_mblock();    *nfiles_in_out = 0;    return NULL;}ArchiveEntryNode *new_entry_node(char *name, int len){    ArchiveEntryNode *entry;    entry = (ArchiveEntryNode *)safe_malloc(sizeof(ArchiveEntryNode));    memset(entry, 0, sizeof(ArchiveEntryNode));    entry->name = (char *)safe_malloc(len + 1);    memcpy(entry->name, name, len);    entry->name[len] = '\0';    return entry;}void free_entry_node(ArchiveEntryNode *entry){    free(entry->name);    if(entry->cache != NULL)	free(entry->cache);    free(entry);}static char *compress_buff;long   compress_buff_len;static long arc_compress_func(char *buff, long size, void *user_val){    if(compress_buff_len <= 0)	return 0;    if(size > compress_buff_len)	size = compress_buff_len;    memcpy(buff, compress_buff, size);    compress_buff += size;    compress_buff_len -= size;    return size;}void *arc_compress(void *buff, long bufsiz,		   int compress_level, long *compressed_size){    DeflateHandler compressor;    long allocated, offset, space, nbytes;    char *compressed;    compress_buff = (char *)buff;    compress_buff_len = bufsiz;    compressor = open_deflate_handler(arc_compress_func, NULL,				      compress_level);

⌨️ 快捷键说明

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