// Path: src/main/java/net/utp4j/data/bytes/UnsignedTypesUtil.java
// public static final long MAX_UINT = 4294967295L;
// 
// Path: src/main/java/net/utp4j/data/bytes/UnsignedTypesUtil.java
// public static int longToUint(long longvalue) {
// 	if (longvalue > MAX_UINT) {
// 		throw new ByteOverflowException(getExceptionText(MAX_UINT, longvalue));
// 	} else if (longvalue < 0) {
// 		throw new SignedNumberException(getExceptionText(MAX_UINT, longvalue));
// 	}
// 	return (int) (longvalue & 0xFFFFFFFF);
// }
// 
// Path: src/main/java/net/utp4j/data/bytes/UnsignedTypesUtil.java
// public final class UnsignedTypesUtil {
// 
// 	public static final long MAX_UBYTE = 255;
// 	public static final long MAX_USHORT = 65535;
// 	public static final long MAX_UINT = 4294967295L;
// 
// 		
// 	public static byte longToUbyte(long longvalue) {
// 		if (longvalue > MAX_UBYTE) {
// 			throw new ByteOverflowException(getExceptionText(MAX_UBYTE, longvalue));
// 		} else if (longvalue < 0) {
// 			throw new SignedNumberException(getExceptionText(MAX_UBYTE, longvalue));
// 		}
// 		return (byte) (longvalue & 0xFF);
// 	}
// 	
// 	public static short longToUshort(long longvalue) {
// 		if (longvalue > MAX_USHORT) {
// 			throw new ByteOverflowException(getExceptionText(MAX_USHORT, longvalue));
// 		} else if (longvalue < 0) {
// 			throw new SignedNumberException(getExceptionText(MAX_USHORT, longvalue));
// 		}
// 		return (short) (longvalue & 0xFFFF);
// 	}
// 	
// 	public static int longToUint(long longvalue) {
// 		if (longvalue > MAX_UINT) {
// 			throw new ByteOverflowException(getExceptionText(MAX_UINT, longvalue));
// 		} else if (longvalue < 0) {
// 			throw new SignedNumberException(getExceptionText(MAX_UINT, longvalue));
// 		}
// 		return (int) (longvalue & 0xFFFFFFFF);
// 	}
// 	
// 	private static String getExceptionText(long max, long actual) {
// 		return "Cannot convert to unsigned type. " +
// 				"Possible values [0, " + max +  "] but got " + actual + ".";
// 	}
// 	
// 	public static short bytesToUshort(byte first, byte second) {
// 		short value = (short)( ((first & 0xFF) << 8) | (second & 0xFF) );
// 		return value;
// 	}
// 	
// 	public static int bytesToUint(byte first, byte second, byte third, byte fourth) {
// 		int firstI = (first & 0xFF) << 24;
// 		int secondI = (second & 0xFF) << 16;
// 		int thirdI = (third & 0xFF) << 8;
// 		int fourthI = (fourth & 0xFF);
// 		
// 		return firstI | secondI | thirdI | fourthI;
// 
// 		
// 	}
// 	
// 
// 	
//  }
// 
// Path: src/main/java/net/utp4j/data/bytes/exceptions/ByteOverflowException.java
// public class ByteOverflowException extends RuntimeException {
// 	
// 	private static final long serialVersionUID = -2545130698255742704L;
// 
// 	public ByteOverflowException(String message) {
// 		super(message);
// 	}
// 	
// 	public ByteOverflowException() {
// 		super("Overflow happened.");
// 	}
// }


import static net.utp4j.data.bytes.UnsignedTypesUtil.MAX_UINT;
import static net.utp4j.data.bytes.UnsignedTypesUtil.longToUint;
import net.utp4j.data.bytes.UnsignedTypesUtil;
import net.utp4j.data.bytes.exceptions.ByteOverflowException;

/* Copyright 2013 Ivan Iljkic
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package net.utp4j.data;

/**
 * Implements micro second accuracy timestamps for uTP headers and to measure time elapsed. 
 * @author Ivan Iljkic (i.iljkic@gmail.com)
 *
 */
public class MicroSecondsTimeStamp {

	private static long initDateMillis = System.currentTimeMillis();
	private static long startNs = System.nanoTime();
	
	/**
	 * Returns a uTP time stamp for packet headers. 
	 * @return timestamp
	 */
	public int utpTimeStamp() {
		int returnStamp;
		//TODO: if performance issues, try bitwise & operator since constant MAX_UINT equals 0xFFFFFF
		// (see http://en.wikipedia.org/wiki/Modulo_operation#Performance_issues )
		long stamp = timeStamp() % UnsignedTypesUtil.MAX_UINT;
		try {
			returnStamp  = longToUint(stamp);

// Path: src/main/java/net/utp4j/data/bytes/UnsignedTypesUtil.java
// public static final long MAX_UINT = 4294967295L;
// 
// Path: src/main/java/net/utp4j/data/bytes/UnsignedTypesUtil.java
// public static int longToUint(long longvalue) {
// 	if (longvalue > MAX_UINT) {
// 		throw new ByteOverflowException(getExceptionText(MAX_UINT, longvalue));
// 	} else if (longvalue < 0) {
// 		throw new SignedNumberException(getExceptionText(MAX_UINT, longvalue));
// 	}
// 	return (int) (longvalue & 0xFFFFFFFF);
// }
// 
// Path: src/main/java/net/utp4j/data/bytes/UnsignedTypesUtil.java
// public final class UnsignedTypesUtil {
// 
// 	public static final long MAX_UBYTE = 255;
// 	public static final long MAX_USHORT = 65535;
// 	public static final long MAX_UINT = 4294967295L;
// 
// 		
// 	public static byte longToUbyte(long longvalue) {
// 		if (longvalue > MAX_UBYTE) {
// 			throw new ByteOverflowException(getExceptionText(MAX_UBYTE, longvalue));
// 		} else if (longvalue < 0) {
// 			throw new SignedNumberException(getExceptionText(MAX_UBYTE, longvalue));
// 		}
// 		return (byte) (longvalue & 0xFF);
// 	}
// 	
// 	public static short longToUshort(long longvalue) {
// 		if (longvalue > MAX_USHORT) {
// 			throw new ByteOverflowException(getExceptionText(MAX_USHORT, longvalue));
// 		} else if (longvalue < 0) {
// 			throw new SignedNumberException(getExceptionText(MAX_USHORT, longvalue));
// 		}
// 		return (short) (longvalue & 0xFFFF);
// 	}
// 	
// 	public static int longToUint(long longvalue) {
// 		if (longvalue > MAX_UINT) {
// 			throw new ByteOverflowException(getExceptionText(MAX_UINT, longvalue));
// 		} else if (longvalue < 0) {
// 			throw new SignedNumberException(getExceptionText(MAX_UINT, longvalue));
// 		}
// 		return (int) (longvalue & 0xFFFFFFFF);
// 	}
// 	
// 	private static String getExceptionText(long max, long actual) {
// 		return "Cannot convert to unsigned type. " +
// 				"Possible values [0, " + max +  "] but got " + actual + ".";
// 	}
// 	
// 	public static short bytesToUshort(byte first, byte second) {
// 		short value = (short)( ((first & 0xFF) << 8) | (second & 0xFF) );
// 		return value;
// 	}
// 	
// 	public static int bytesToUint(byte first, byte second, byte third, byte fourth) {
// 		int firstI = (first & 0xFF) << 24;
// 		int secondI = (second & 0xFF) << 16;
// 		int thirdI = (third & 0xFF) << 8;
// 		int fourthI = (fourth & 0xFF);
// 		
// 		return firstI | secondI | thirdI | fourthI;
// 
// 		
// 	}
// 	
// 
// 	
//  }
// 
// Path: src/main/java/net/utp4j/data/bytes/exceptions/ByteOverflowException.java
// public class ByteOverflowException extends RuntimeException {
// 	
// 	private static final long serialVersionUID = -2545130698255742704L;
// 
// 	public ByteOverflowException(String message) {
// 		super(message);
// 	}
// 	
// 	public ByteOverflowException() {
// 		super("Overflow happened.");
// 	}
// }


// Path: src/main/java/net/utp4j/data/MicroSecondsTimeStamp.java
import static net.utp4j.data.bytes.UnsignedTypesUtil.MAX_UINT;
import static net.utp4j.data.bytes.UnsignedTypesUtil.longToUint;
import net.utp4j.data.bytes.UnsignedTypesUtil;
import net.utp4j.data.bytes.exceptions.ByteOverflowException;

/* Copyright 2013 Ivan Iljkic
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package net.utp4j.data;

/**
 * Implements micro second accuracy timestamps for uTP headers and to measure time elapsed. 
 * @author Ivan Iljkic (i.iljkic@gmail.com)
 *
 */
public class MicroSecondsTimeStamp {

	private static long initDateMillis = System.currentTimeMillis();
	private static long startNs = System.nanoTime();
	
	/**
	 * Returns a uTP time stamp for packet headers. 
	 * @return timestamp
	 */
	public int utpTimeStamp() {
		int returnStamp;
		//TODO: if performance issues, try bitwise & operator since constant MAX_UINT equals 0xFFFFFF
		// (see http://en.wikipedia.org/wiki/Modulo_operation#Performance_issues )
		long stamp = timeStamp() % UnsignedTypesUtil.MAX_UINT;
		try {
			returnStamp  = longToUint(stamp);

		} catch (ByteOverflowException exp) {
