/* HeaderMaker.java
HeaderMaker: Simple header-maker for metafiles
Copyright (C) 2011 Tomáš Hlavnička <hlavntom@fel.cvut.cz>
This file is a part of Jazsync.
Jazsync 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.
Jazsync 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 Jazsync; if not, write to the
Free Software Foundation, Inc.,
59 Temple Place, Suite 330,
Boston, MA 02111-1307
USA
*/
package com.ettrema.zsync;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import com.ettrema.zsync.SHA1;
/**
* Simple class for creating headers for metafile
* @author Tomáš Hlavnička
*/
public class HeaderMaker {
/*
zsync: 0.6.1
Filename: tinycore.iso
MTime: Sat, 06 Mar 2010 09:33:36 +0000
Blocksize: 2048
Length: 11483136
Hash-Lengths: 2,2,5
URL: http://i.iinfo.cz/files/root/240/tinycore.iso
SHA-1: 5944ec77b9b0f2d6b8212d142970117f5801430a
*/
/** Dodelat hlavicky tykajici se komprimovanych streamu
* ++++ Z-URL, Z-Filename, Z-Map2, Recompress, Safe
*/
// private SHA1 sha1;
//
// private int seq_num=1;
// private int rsum_bytes=4;
// private int checksum_bytes=16;
// private long mtime=0;
public HeaderMaker(){
}
/**
* Method builds header from key values
* @return Full header in String format
*/
public Headers getFullHeader(File file, String url, int blocksize, int[] hashLengths){
Headers h = new Headers();
String sha1 = new SHA1(file.toString()).SHA1sum();
if( url == null ) {
url = file.getName();
}
if (!isPowerOfTwo(blocksize)) {
throw new IllegalArgumentException("Blocksize must be a power of 2 (512, 1024, 2048, ...)");
}
init(h, file.lastModified(), file.length(), url, blocksize, hashLengths, sha1);
return h;
}
public Headers getFullHeader(Date lastMod, long fileLength, String url, int blocksize, int[] hashLengths, String sha1){
Headers h = new Headers();
init(h, lastMod.getTime(), fileLength, url, blocksize, hashLengths, sha1);
return h;
}
private void init(Headers h, long lastMod, long fileLength, String url, int blocksize, int[] hashLengths, String sha1) {
h.version = "jazsync";
h.mTime = lastMod;
h.url = url;
h.length = fileLength;
if (isPowerOfTwo(blocksize)) {
h.blocksize = blocksize;
} else {
throw new IllegalArgumentException("Blocksize must be a power of 2 (512, 1024, 2048, ...)");
}
h.setSeqNum(hashLengths[0]);
h.setRsumBytes(hashLengths[1]);
h.setChecksumBytes(hashLengths[2]);
h.sha1 = sha1;
}
public String toString(Headers h) {
String Version="zsync: jazsyncM";
String MTime="MTime: ";
String Blocksize="Blocksize: ";
String Length="Length: ";
String HashLengths="Hash-Lengths: ";
String URL="URL: ";
String SHA1="SHA-1: ";
Blocksize+=h.blocksize;
MTime+=setMTime("EEE, dd MMM yyyy HH:mm:ss Z", h.mTime);
Length+=h.length;
URL+=h.url; //new url
HashLengths+=(h.hashLengths[0]+","+h.hashLengths[1]+","+h.hashLengths[2]);
SHA1+=h.sha1;
StringBuilder sb = new StringBuilder("");
sb.append(Version).append("\n");
sb.append(MTime).append("\n");
sb.append(Blocksize).append("\n");
sb.append(Length).append("\n");
sb.append(HashLengths).append("\n");
sb.append(URL).append("\n");
sb.append(SHA1).append("\n\n");
String header = sb.toString();
return header;
}
/**
* Checks if <code>number</code> is power of two
* @param number Number to be checked
* @return Boolean value
*/
private boolean isPowerOfTwo(int number){
boolean isPowerOfTwo = true;
while(number>1){
if(number%2 != 0){
isPowerOfTwo = false;
break;
} else {
number=number/2;
}
}
return isPowerOfTwo;
}
/**
* Converts time (ms) into formated MTime using <code>dateFormat</code>
* @param dateFormat MTime format
* @return Formated date of MTime
*/
private String setMTime(String dateFormat, long mtime) {
Date date = new Date();
date.setTime(mtime);
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat,Locale.US);
return sdf.format(date);
}
public static class Headers {
public String version;
public long mTime; // lasst mod time in milliseconds
public int blocksize;
public long length;
public final int[] hashLengths = new int[3];
public String url;
public String sha1;
public int getSeqNum() {
return hashLengths[0];
}
public int getRsumButes() {
return hashLengths[1];
}
public int getChecksumBytes() {
return hashLengths[2];
}
public void setSeqNum(int i) {
hashLengths[0] = i;
}
public void setRsumBytes(int i) {
hashLengths[1] = i;
}
public void setChecksumBytes(int i) {
hashLengths[2] = i;
}
}
}