content: package org.flashtool.flashsystem.io;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import org.flashtool.flashsystem.CommandPacket;
  import org.flashtool.flashsystem.S1Command;
  import org.flashtool.flashsystem.S1Packet;
  import org.flashtool.flashsystem.X10FlashException;
  import org.flashtool.libusb.LibUsbException;
  import org.flashtool.system.OS;
  
  import lombok.extern.slf4j.Slf4j;
  
  @Slf4j
  public class USBFlash {
  
  	private static int buffersize=512*1024;
  	private static int readbuffer=512*1024;
  	
  	public static void setUSBBufferSize(int size) {
  		buffersize=size;
  	}
  
  	public static int getUSBBufferSize() {
  		return buffersize;
  	}
  	
  	public static void open(String pid) throws IOException, Exception {
  		if (OS.getName().equals("windows")) {
  			USBFlashWin32.windowsOpen(pid);
  		}
  		else {
  			USBFlashLinux.linuxOpen(pid);
  		}
  	}
  
  	public static void close() {
      	if (OS.getName().equals("windows")) {
      		USBFlashWin32.windowsClose();
      	}
      	else
      		USBFlashLinux.linuxClose();
      }
  
  	public static S1Packet writeS1(S1Packet p) throws IOException,X10FlashException {
  		write(p.getHeaderWithChecksum());
  		if (p.getDataLength()>0) {
  			long totalread=0;
  			ByteArrayInputStream in = new ByteArrayInputStream(p.getDataArray());
  			while (totalread<p.getDataLength()) {
  				long remaining = p.getDataLength()-totalread;
  				long bufsize=(remaining<buffersize)?remaining:buffersize;
  				byte[] buf = new byte[(int)bufsize];
  				int read = in.read(buf);
  				write(buf);
  				totalread+=read;
  			}
  			in.close();
  		}
  		write(p.getCRC32());
  		return readS1Reply();
  	}
  
  	public static void write(byte[] array) throws IOException,X10FlashException {
  		if (OS.getName().equals("windows")) {
  			USBFlashWin32.windowsWrite(array);
  		}
  		else {
  			USBFlashLinux.linuxWrite(array);
  		}
  	}
  
      public static  S1Packet readS1Reply() throws X10FlashException, IOException
      {
      	byte[] read=null;
      	S1Packet p=new S1Packet("".getBytes());
      	while (p.hasMoreToRead()) {
      		try {
      			read = read(readbuffer);
      		} catch (LibUsbException e) {
      			read=null;
      		}
      		if (read != null)
      			p.addData(read);
      	}
  		p.validate();
  		return p;
      }
  
      public static  CommandPacket readCommandReply(boolean withOK) throws X10FlashException, IOException
      {
      	log.debug("Reading packet from phone");
      	byte[] read=null;
      	CommandPacket p = new CommandPacket("".getBytes(),withOK);
      	while (p.hasMoreToRead()) {
      		try {
      			read = read(readbuffer);
      		} catch (LibUsbException e) {
      			read=null;
      		}
      		if (read != null)
      			p.addData(read);
      	}
  		log.debug("IN : " + p);
  		return p;
  		//lastflags = p.getFlags();
      }
  
  	private static byte[] read(int length)  throws LibUsbException, IOException,X10FlashException {
  		if (OS.getName().equals("windows")) {
  			return USBFlashWin32.windowsRead(length);
  		}
  		else {
  			return USBFlashLinux.linuxRead(length);
  		}
  	}
  
  }