package lesson4;
import java.io.IOException;
public class HuffmanDecode{
    //定义一个数组变量来存放各个字节数据对应的编码
	private Code SaveCode[]=new Code[256];
    private String path;
    
	/**
	 * 构造方法
	 * @param path
	 */
	public HuffmanDecode(String path){
		this.path=path;
	}
	/**
	 * 将一个int转为8个字符的String 
	 * @param n
	 * @return
	 */
	public String IntToString(int n){
		int on=n;
		String s="";
		for (int i=0;i<8;i++){
			if  ((on % 2)==0){
				s='0'+s;
			}else if(on%2==1){
				s='1'+s;
			}
			on=on/2;
		}
		return s;
	}
	
	
	/**
	 * 判断哪一个编码是和ss编码匹配的
	 * @param ss 待匹配字串
	 * @return 字节为i的编码
	 */
	public int equalsMB(String ss){
		for (int i=0;i<256;i++){
			if ((SaveCode[i].n)==ss.length()&&(SaveCode[i].node.equals(ss))){
				return i;
			}
		}
		return -1;  //没有找到匹配的
	}
	
	
	/**
	 * 逐位进行比较,判断多少长度的int匹配字符串s
	 * @param s
	 * @return
	 */
	public int search(String s){
		int n;
		String ss="";
		int num=-1;
		for (n=0;n<s.length();n++){
		    ss=ss+s.charAt(n);
		    num=equalsMB(ss);
		    if (num>=0){	
		    	break;
		    }
		}
		if(n<s.length()){
			return num;
		 }else{
			return -1;
		 }
	}
	
	
	/**
	 * 解压缩
	 */
	public void Decode(){
		try{
			//文件输入流
			java.io.FileInputStream fis=new java.io.FileInputStream(path);
	       //读入文件中的每一个编码的长度
	       for (int i=0;i<256;i++){
	    	   Code hC=new Code();
	    	   hC.n=fis.read();
	    	   hC.node="";
	    	   SaveCode[i]=hC;
	       }
	       System.out.println("编码长度读取完毕");
	       
	       
	       
	       int i=0;
	       int count=0;
	       String coms="";
	       //读SaveCode中0~256字节的的数据
	       while (i<256){
		    	   //当缓存区的编码长度比编码[i]的长度长的时候
		    	   if (coms.length()>=SaveCode[i].n){
			    		  for (int t=0;t<SaveCode[i].n;t++){//SaveCode[i].node取得该编码
			    			  SaveCode[i].node=SaveCode[i].node+coms.charAt(t);
			    		  }
			    		  
			    		  //把coms前这几位去掉
			    		  String coms2="";
			    		  for (int t=SaveCode[i].n;t<coms.length();t++){
			    			  coms2=coms2+coms.charAt(t);
			    		  }
			    		  coms="";
			    		  coms=coms2;//累计的下一个编码,继续的使用
			    		  i++;
		    	   }else{
			    		//如果已经没有写出的话,再度入一个byte转化为01 String
			    	    coms=coms+IntToString(fis.read());
		    	   }
	       }
	       
	     //定义文件输出流
	       String path2 = "";//去掉文件名 尾的stzip后缀
	       for(int k=0;k<path.length()-6;k++)
	    	   path2=path2+path.charAt(k);
		   java.io.FileOutputStream fos=new java.io.FileOutputStream(path2);
		   String rsrg;//存转换成的Sting
		   String compString="";//存要比较的字符串
		   //读入文件,写出文件
		   while(fis.available()>1){
			   if (search(compString)>=0){
				   int cint=search(compString);
				   fos.write(cint);
				   //删掉前n个数据
				   String compString2="";
		    	   for (int t=SaveCode[cint].n;t<compString.length();t++){
		    		  compString2=compString2+compString.charAt(t);
		    	   }
		    	   compString="";
		    	   compString=compString2;
				   
			   }else{//继续读入
				   compString=compString+IntToString(fis.read());
			   }
		   }
		   
		   
		   //处理最后一个字节
		  int cint=fis.read();
		  String compString2="";
		  for (int t=0;t<compString.length()-cint;t++){
			 compString2=compString2+compString.charAt(t);
		  }
		  compString=compString2;
		  
		  
		   //删掉前n个数据
		  while (compString.length()>0){
			   int ccint=search(compString);
			   fos.write(ccint);   
			   compString2="";
	   	       for (int t=SaveCode[ccint].n;t<compString.length();t++){
	   		    compString2=compString2+compString.charAt(t);
	   	       }
	   	       compString="";
	   	       compString=compString2;
		  }
		  		  
		  System.out.println("解码完毕!");
		}catch(Exception ef) {
			ef.printStackTrace();
		}
	}
}