/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.core.command.transfer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Iterator; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.xmind.core.command.binary.BinaryStore; import org.xmind.core.command.binary.IBinaryEntry; import org.xmind.core.command.binary.IBinaryStore; /** * This utility class provides constants and convenient methods to * encode/decode/read/write data from/to input/output streams. * * @author Frank Shaka */ public class CommandTransferUtil { public static final String ENCODING = "UTF-8"; //$NON-NLS-1$ public static final String MARKER_PROPERTIES = "[PROPERTIES]"; //$NON-NLS-1$ public static final String MARKER_VALUES = "[VALUES]"; //$NON-NLS-1$ public static final String MARKER_FILES = "[FILES]"; //$NON-NLS-1$ private CommandTransferUtil() { } public static String encode(String str) { try { return URLEncoder.encode(str, ENCODING); } catch (UnsupportedEncodingException e) { return str; } } public static String decode(String str) { try { return URLDecoder.decode(str, ENCODING); } catch (UnsupportedEncodingException e) { return str; } } public static IBinaryStore readFiles(IProgressMonitor monitor, ChunkReader reader) throws IOException { String numFilesStr = reader.readText(); if (numFilesStr == null) // Empty files return null; int numFiles; try { numFiles = Integer.parseInt(numFilesStr, 10); } catch (NumberFormatException e) { throw new IOException( "Invalid format of files number: " + numFilesStr); //$NON-NLS-1$ } monitor.beginTask(null, numFiles); IBinaryStore store = null; String entryName; try { while ((entryName = reader.readText()) != null) { if ("".equals(entryName) || monitor.isCanceled()) //$NON-NLS-1$ break; InputStream chunkStream = reader.openNextChunkAsStream(); if (chunkStream != null) { IProgressMonitor fileMonitor = new SubProgressMonitor( monitor, 1); if (store == null) { store = new BinaryStore(); } store.addEntry(fileMonitor, entryName, chunkStream); if (monitor.isCanceled()) return null; fileMonitor.done(); } } } catch (InterruptedException e) { return null; } return store; } public static void writeFiles(IProgressMonitor monitor, IBinaryStore files, ChunkWriter writer) throws IOException { monitor.beginTask(null, files.size()); writer.writeText(String.valueOf(files.size())); Iterator<String> entryNames = files.entryNames(); while (entryNames.hasNext()) { String entryName = entryNames.next(); IBinaryEntry entry = files.getEntry(entryName); writer.writeText(entryName); if (monitor.isCanceled()) return; if (entry != null && !entryName.endsWith("/")) { //$NON-NLS-1$ InputStream in = entry.openInputStream(); if (monitor.isCanceled()) return; try { OutputStream out = writer.openNextChunkAsStream(); if (monitor.isCanceled()) return; try { byte[] buffer = new byte[4096]; int read; while ((read = in.read(buffer)) > 0) { if (monitor.isCanceled()) return; out.write(buffer, 0, read); } } finally { out.close(); } } finally { in.close(); } } if (monitor.isCanceled()) return; monitor.worked(1); } if (monitor.isCanceled()) return; monitor.done(); } }