blob: 5691c8859cc883114ee5112c3d165d0bbcd9cafe [file] [log] [blame]
package org.eclipse.swt.ole.win32;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved
*/
import java.io.*;
import org.eclipse.swt.*;
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();
}
}