package ecologylab.generic;
import java.io.UnsupportedEncodingException;
/**
* Help for working with Sun's attrocious drag and drop and clipboard "support".
*
* @author andruid
*/
public class DataTransferTools extends Debug
{
public DataTransferTools()
{
super();
}
static final String EOL = "\r\n";
static final String HTML_CLIPBOARD_FORMAT_HEADER = "Version:1.0"+ EOL +
"StartHTML:00000000000"+ EOL +
"EndHTML:00000000000"+ EOL +
"StartFragment:00000000000"+ EOL +
"EndFragment:00000000000" + EOL ;
static final int HEADER_LENGTH = HTML_CLIPBOARD_FORMAT_HEADER.length();
/**
* surrounds the html with this envelope, ready for
* windows clipboard (jdk support can be made better)
* <pre>
* Version:1.0
* StartHTML:00000000000
* EndHTML:00000000000
* StartFragment:00000000000
* EndFragment:00000000000
* <!--StartFragment-->
* ...
* <!-- EndFragment-- >
* </pre>
* We have to return a byte array 'cause in Windows the html needs to be utf-8
* encoded. And because we have to calculate char-offsets, we encode it here.
* @param html
* @return byte[]
*/
public static byte[] convertToMSCfHtml(String html) throws UnsupportedEncodingException
{
html = "<!--StartFragment-->" + html + "<!--EndFragment-->\r\n\0";
byte[] bHtml = html.getBytes("UTF-8");// encode first 'cause it may grow
int htmlLen = bHtml.length;
StringBuffer buf = new StringBuffer(HTML_CLIPBOARD_FORMAT_HEADER);
setValueInHeader( buf, "StartHTML", HEADER_LENGTH-1);
setValueInHeader( buf, "EndHTML", HEADER_LENGTH + htmlLen-1);
setValueInHeader( buf, "StartFragment", HEADER_LENGTH-1);
setValueInHeader( buf, "EndFragment", HEADER_LENGTH + htmlLen-1);
byte[] bHeader = buf.toString().getBytes("UTF-8");// should stay the same (no nonASCII chars in header)
byte result[] = new byte[HEADER_LENGTH + htmlLen ];
System.arraycopy(bHeader, 0, result, 0, bHeader.length);
System.arraycopy(bHtml, 0, result, bHeader.length, bHtml.length);
return result;
}
/**
* Replaces name+":00000000000" with name+":xxxxxxxxxxx" where xxx... is the '0' padded value.
* Value can't be to long, since maxint can be displayed with 11 digits. If value is below zero
* there is enough place (10 for the digits 1 for sign).<br>
* If the search is not found nothing is done.
* @param src
* @param name
* @param value
*/
private static void setValueInHeader( StringBuffer src, String name, int value)
{
String search = name+":00000000000";
int pos = src.indexOf(search);
if (pos ==-1) return;// not found, do nothing
boolean belowZero = value<0;
if (belowZero) value = -value;
src.replace(pos+search.length()-(value+"").length(), pos+search.length(), value+"");
if (belowZero) src.setCharAt(pos+name.length()+1,'-'); // +1 'cause of ':' in "SearchMe:"
}
}