| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.ole.win32; |
| |
| import java.io.*; |
| import org.eclipse.swt.internal.win32.*; |
| import org.eclipse.swt.internal.ole.win32.*; |
| |
| final class OleFile { |
| IStorage rootStorage; |
| File file; |
| String streamName; |
| |
| static int READ = 0; |
| static int WRITE = 1; |
| OleFile(File file, String streamName, int mode) { |
| if (file == null || file.isDirectory()) |
| OLE.error(OLE.ERROR_INVALID_ARGUMENT); |
| |
| this.file = file; |
| this.streamName = streamName; |
| |
| if (mode == READ) |
| openForRead(); |
| if (mode == WRITE) |
| openForWrite(); |
| } |
| void dispose() { |
| |
| rootStorage.Release(); |
| rootStorage = null; |
| file = null; |
| streamName = null; |
| } |
| IStorage getRootStorage() { |
| return rootStorage; |
| } |
| private void openForRead() { |
| |
| if (!file.exists()) return; |
| |
| char[] path = (file.getAbsolutePath()+"\0").toCharArray(); |
| if (COM.StgIsStorageFile(path) == COM.S_OK) { |
| readStorageFile(path); |
| } else { |
| readTraditionalFile(path); |
| } |
| |
| } |
| private void openForWrite() { |
| char[] filePath = (file.getAbsolutePath()+"\0").toCharArray(); |
| int[] address = new int[1]; |
| int mode = COM.STGM_TRANSACTED | COM.STGM_READWRITE | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_CREATE; |
| |
| int result = COM.StgCreateDocfile(filePath, mode, 0, address); |
| if (result != COM.S_OK) |
| OLE.error(OLE.ERROR_CANNOT_CREATE_FILE, result); |
| |
| IStorage storage = new IStorage(address[0]); |
| |
| rootStorage = storage; |
| } |
| private void readStorageFile(char[] path) { |
| |
| int mode = COM.STGM_READ | COM.STGM_TRANSACTED | COM.STGM_SHARE_EXCLUSIVE; |
| int[] address = new int[1]; |
| |
| int result = COM.StgOpenStorage(path, 0, mode, 0, 0, address); |
| if (result != COM.S_OK) |
| OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); |
| |
| rootStorage = new IStorage(address[0]); |
| rootStorage.AddRef(); |
| } |
| private void readTraditionalFile(char[] path) { |
| |
| if (streamName == null) OLE.error(OLE.ERROR_NULL_ARGUMENT); |
| |
| int mode = COM.STGM_DIRECT | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_READWRITE | COM.STGM_CREATE; |
| |
| // Create a temporary storage object |
| int[] address = new int[1]; |
| int result = COM.StgCreateDocfile(null, mode | COM.STGM_DELETEONRELEASE, 0, address); |
| if (result != COM.S_OK) |
| OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); |
| rootStorage = new IStorage(address[0]); |
| rootStorage.AddRef(); |
| |
| // Create a stream on the storage object with the name specified in streamName |
| address = new int[1]; |
| result = rootStorage.CreateStream(streamName, mode, 0, 0, address); |
| if (result != COM.S_OK) |
| OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); |
| |
| // Copy over data in file to named stream |
| IStream stream = new IStream(address[0]); |
| stream.AddRef(); |
| try { |
| |
| FileInputStream fileInput = new FileInputStream(file); |
| |
| int increment = 1024*4; |
| byte[] buffer = new byte[increment]; |
| int count = 0; |
| |
| while((count = fileInput.read(buffer)) > 0){ |
| int pv = COM.CoTaskMemAlloc(count); |
| OS.MoveMemory(pv, buffer, count); |
| result = stream.Write(pv, count, null) ; |
| COM.CoTaskMemFree(pv); |
| if (result != COM.S_OK) |
| OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); |
| } |
| stream.Commit(COM.STGC_DEFAULT); |
| |
| fileInput.close(); |
| } catch (IOException err) { |
| OLE.error(OLE.ERROR_CANNOT_OPEN_FILE); |
| } |
| |
| stream.Release(); |
| |
| } |
| } |