#include "stdafx.h" #include "arcz.h" #include "util.h" const unsigned char CTarArcFile_Compress::MAGIC_1 = '\037'; /* First byte of compressed file */ const unsigned char CTarArcFile_Compress::MAGIC_2 = '\235'; /* Second byte of compressed file */ // static const int C::HSIZE = 1 << 17; /* 131072 */ static const int BITS = 16; static const int INIT_BITS = 9; static const int BIT_MASK = 0x1f; static const int BLOCK_MODE = 0x80; /* Block compresssion if table is full and compression rate is dropping flush tables*/ static const int FIRST = 257; static const int CLEAR = 256; CTarArcFile_Compress::CTarArcFile_Compress() { m_pFile = NULL; } CTarArcFile_Compress::~CTarArcFile_Compress() { if(m_pFile){fclose(m_pFile);} } bool CTarArcFile_Compress::open(const char *arcfile, const char *mode, int /*compress_level*/) { m_arcfile = arcfile; /* only decompress implemented */ if(strchr(mode,'w')){return false;} m_pFile = fopen(arcfile, "rb"); if(m_pFile)setvbuf(m_pFile,NULL,_IOFBF,1024*1024); m_insize = m_rsize = 0; m_insize = m_rsize = fread(m_inbuf, 1, BUFSIZ, m_pFile); char magic[2]; memcpy(magic, m_inbuf, 2); //if(fread(magic, 1, 2, m_pFile) !=2){return false;} //m_insize += 2; m_rsize += 2; if(magic[0] != (char)MAGIC_1 || magic[1] != (char)MAGIC_2){return false;} char buf[1]; memcpy(buf, m_inbuf+2, 1); //if(fread(buf, 1, 1, m_pFile) != 1){return false;} //m_insize += 1; m_rsize +=1; m_maxbits = buf[0] & BIT_MASK; if(m_maxbits > BITS){return false;} m_block_mode = ((buf[0] & BLOCK_MODE) != 0); m_eof = false; m_n_bits = INIT_BITS; m_maxcode = (1< 0){ size64 in_avail; in_avail = m_strstream.rdbuf()->in_avail(); if(in_avail == 0){ if(!readonce()){break;} m_strstream.peek(); // buffer underflow } in_avail = m_strstream.rdbuf()->in_avail(); size64 n = min(in_avail, size); m_strstream.read((char*)buf, (size_t)n); //TODO:size lost nread += n; size -= n; buf = (void*)((char*)buf + n); } return nread; } bool CTarArcFile_Compress::eof() { if(m_eof){ if(m_strstream.eof()){ return true; } } return false; } bool CTarArcFile_Compress::readonce() { resetbuf: m_insize -= m_posbits/8; memmove(m_inbuf, m_inbuf + m_posbits/8, m_insize); m_posbits = 0; if(m_insize < sizeof(m_inbuf) - BUFSIZ){ m_rsize = fread(m_inbuf + m_insize, 1, BUFSIZ, m_pFile); m_insize += m_rsize; } int inbits; if(m_rsize>0){ inbits = (m_insize-m_insize%m_n_bits)*8; }else{ inbits = (m_insize*8)-(m_n_bits-1); } while(inbits > m_posbits){ if(m_free_ent > m_maxcode){ m_posbits = (m_posbits-1)+((m_n_bits*8)-(m_posbits-1+(m_n_bits*8))%(m_n_bits*8)); m_n_bits++; if(m_n_bits == m_maxbits){ m_maxcode = 1 << m_maxbits; }else{ m_maxcode = (1 << m_n_bits) - 1; } goto resetbuf; } // input() // input(inbuf, posbits, code, n_bits, bitmask); /*@3 = (*(long*)(&@1[@2>>3]) >> (@2&0x7)) & @5; @2 += @4;*/ int code; { int bitmask = (1<> (m_posbits&7)) & bitmask; m_posbits += m_n_bits; } if(m_oldcode == -1){ // outbuf[outpos++] = (unsigned char)(code); m_strstream.put((unsigned char)code); m_oldcode = code; m_finchar = (int) code; continue; } if(code == CLEAR && m_block_mode){ memset(m_codetab, 0, 256); m_free_ent = FIRST - 1; int tmp = (m_posbits-1) + (m_n_bits*8); m_posbits = tmp - tmp%(m_n_bits*8); m_n_bits = INIT_BITS; m_maxcode = (1 << m_n_bits) - 1; goto resetbuf; } int incode = code; unsigned char *stackp = m_htab + sizeof(m_htab); if(code > m_free_ent){ return false; }else if(code == m_free_ent){ /* Special case for KwKwK string. */ //m_posbits -= m_n_bits; // p = &inbuf[posbits/8]; * --stackp = (unsigned char)m_finchar; code = m_oldcode; } while((unsigned int)code >= (unsigned)256){ *--stackp = m_htab[code]; code = m_codetab[code]; } * --stackp = (unsigned char)(m_finchar = m_htab[code] ); m_strstream.write((char*)stackp, m_htab + sizeof(m_htab) - stackp); /* if(outpos + (i=(de_stack - stackp)) > OBUFSIZ){ do{ if( i > OBUFSIZ - outpos){ i = OBUFSIZ - outpos; } memcpy(outbuf+outpos, stackp, i); if(outpos >= OBUFSIZ){ m_stream.write(m_outbuf, outpos); outpos = 0; } stackp += i; }while((i=(de_stack - stackp))>0); }else{ memcpy(outbuf + outpos, stackp, i); outpos += i; } */ if(m_free_ent < (1<2 && stricmp(fname.substr(fname.length()-2).c_str(),".z") == 0){ return fname.substr(0, fname.length()-2); } return fname + "_extracted"; }