static int isf_write_gz_header(istream68_z_t * isf) { struct { Byte magic[2]; /* gz header */ Byte method; /* method (Z_DEFLATED) */ Byte flags; /* Xtra,name,comment... */ Byte info[6]; /* time, xflags and OS code */ } header; int i; const char * name = isf->gz_name ? istream68_filename(isf->is) : 0; header.magic[0] = gz_magic[0]; header.magic[1] = gz_magic[1]; header.method = Z_DEFLATED; header.flags = name ? ORIG_NAME : 0; for (i=0; i<sizeof(header.info); ++i) { header.info[i] = 0; } if (istream68_write(isf->is, &header, sizeof(header)) != sizeof(header)) { return -1; } if (name) { const char * s1, * s2; int len; s1 = strrchr(name,'/'); s2 = strrchr(name,'\\'); name = (s1 > name) ? s1+1 : name; name = (s2 > name) ? s2+1 : name; len = strlen(name) + 1; if (istream68_write(isf->is, name, len) != len) { return -1; } } return 0; }
static int isf_close(istream68_t * istream) { istream68_z_t * isf = (istream68_z_t *)istream; int err = -1; TRACE68(zlib_cat,"istream68_z: close(%s) {\n", istream68_filename(istream)); if (isf) { err = isf->is_err; if (isf->deflate) { TRACE68(zlib_cat,"DEFLATED "); isf->deflate = 0; if (!err) { err = isf_deflate_buffer(isf, 1) == -1; } TRACE68(zlib_cat,"in:%d out:%d ", isf->c_stream.total_in,isf->c_stream.total_out); if (isf->gzip) { TRACE68(zlib_cat,"crc:%08X ",isf->c_crc32); } if (!err) { int i, c, t; unsigned char hd[8]; for (i=0, c=isf->c_crc32, t=isf->c_stream.total_in; i<4; ++i, c>>=8, t>>=8) { hd[0+i] = (unsigned char)c; hd[4+i] = (unsigned char)t; } err = istream68_write(isf->is, hd, 8) != 8; } deflateEnd(&isf->c_stream); }
static const char * isf_name(istream68_t * istream) { istream68_z_t * isf = (istream68_z_t *)istream; return (!isf) ? 0 : istream68_filename(isf->is); }
istream68_t * url68_stream_create(const char * url, int mode) { char protocol[16]; char tmp[512]; const int max = sizeof(tmp)-1; istream68_t * isf = 0; int has_protocol; /* in fact protocol:// length */ has_protocol = parse_protocol(protocol, sizeof(protocol), url); if (has_protocol) { if (!strcmp68(protocol, "PASS")) { /* This is special pass thru protocol. It allows to send any other protocol:// or whatever to the default file handler. On some OS with some libC it may be useful. */ url += has_protocol; /* Skip protocol:// part */ has_protocol = 0; /* Allow fallback open */ } else if (!strcmp68(protocol, "RSC68")) { isf = rsc68_create_url(url, mode, 0); } else if (!strcmp68(protocol, "SC68")) { /* sc68://author/hw/title/track:loop */ url += has_protocol; /* Skip protocol:// part */ strncpy(tmp, "rsc68://music/",max); strncpy(tmp+14, url, max-14); tmp[max] = 0; msg68(-1,"url is now [%s]\n",tmp); isf = rsc68_create_url(tmp, mode, 0); } else if (!strcmp68(protocol, "FILE") || !strcmp68(protocol, "LOCAL")) { url += has_protocol; /* Skip protocol:// part */ has_protocol = 0; /* Allow fallback open */ } else if (!strcmp68(protocol, "NULL")) { isf = istream68_null_create(url); } else if (!strcmp68(protocol, "AUDIO")) { url += 5+3; isf = istream68_ao_create(url,mode); } else if (!strcmp68(protocol, "STDIN")) { if (mode != 1) return 0; /* stdin is READ_ONLY */ isf = istream68_fd_create("stdin://",0,1); url = "/dev/stdin"; /* fallback */ has_protocol = 0; /* Allow fallback open */ } else if (!strcmp68(protocol, "STDOUT")) { if (mode != 2) return 0; /* stdout is WRITE_ONLY */ isf = istream68_fd_create("stdout://",1,2); url = "/dev/stdout"; /* fallback */ has_protocol = 0; /* Allow fallback open */ } else if (!strcmp68(protocol, "STDERR")) { if (mode != 2) return 0; /* stderr is WRITE_ONLY */ isf = istream68_fd_create("stderr://",2,2); url = "/dev/stderr"; /* fallback */ has_protocol = 0; /* Allow fallback open */ } else { /* Try cURL for all unknown protocol */ isf = istream68_curl_create(url,mode); } } /* Fallback open only if no protocol (or explicitly allowed) */ if (!has_protocol) { if (!isf) { /* Default open as FILE */ isf = istream68_file_create(url,mode); } if (!isf) { /* Fallback to file descriptor */ isf = istream68_fd_create(url,-1,mode); } } msg68_debug("url68: create url='%s' %c%c => [%s,'%s']\n", strnevernull68(url), (mode&1) ? 'R' : '.', (mode&2) ? 'W' : '.', strok68(!isf), istream68_filename(isf)); return isf; }