diff --git a/src/com/owncloud/android/lib/common/network/ChunkFromFileChannelRequestEntity.java b/src/com/owncloud/android/lib/common/network/ChunkFromFileChannelRequestEntity.java index fae35224d3..e5d9eacfe0 100644 --- a/src/com/owncloud/android/lib/common/network/ChunkFromFileChannelRequestEntity.java +++ b/src/com/owncloud/android/lib/common/network/ChunkFromFileChannelRequestEntity.java @@ -24,6 +24,8 @@ package com.owncloud.android.lib.common.network; +import org.apache.commons.httpclient.methods.RequestEntity; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -35,10 +37,6 @@ import java.util.Iterator; import java.util.Set; -import org.apache.commons.httpclient.methods.RequestEntity; - -import com.owncloud.android.lib.common.utils.Log_OC; - /** * A RequestEntity that represents a PIECE of a file. @@ -56,12 +54,12 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres private final File mFile; private long mOffset; private long mTransferred; + private long mFileSize; Set mDataTransferListeners = new HashSet(); private ByteBuffer mBuffer = ByteBuffer.allocate(4096); - public ChunkFromFileChannelRequestEntity( - final FileChannel channel, final String contentType, long chunkSize, final File file - ) { + public ChunkFromFileChannelRequestEntity(final FileChannel channel, final String contentType, long chunkSize, + final File file, long fileSize) { super(); if (channel == null) { throw new IllegalArgumentException("File may not be null"); @@ -75,6 +73,7 @@ public ChunkFromFileChannelRequestEntity( mFile = file; mOffset = 0; mTransferred = 0; + this.mFileSize = fileSize; } public void setOffset(long offset) { @@ -83,7 +82,13 @@ public void setOffset(long offset) { public long getContentLength() { try { - return Math.min(mChunkSize, mChannel.size() - mOffset); + long size; + if (mFileSize > 0) { + size = mFileSize; + } else { + size = mChannel.size(); + } + return Math.min(mChunkSize, size - mOffset); } catch (IOException e) { return mChunkSize; } @@ -124,14 +129,19 @@ public void setmTransferred(long value) { } public void writeRequest(final OutputStream out) throws IOException { - int readCount = 0; + int readCount; Iterator it = null; try { mChannel.position(mOffset); - long size = mFile.length(); - if (size == 0) size = -1; - long maxCount = Math.min(mOffset + mChunkSize, mChannel.size()); + + if (mFileSize == 0) { + mFileSize = mFile.length(); + } + + if (mFileSize == 0) mFileSize = -1; + + long maxCount = Math.min(mOffset + mChunkSize, Math.max(mChannel.size(), mFileSize)); while (mChannel.position() < maxCount) { readCount = mChannel.read(mBuffer); try { @@ -147,7 +157,7 @@ public void writeRequest(final OutputStream out) throws IOException { synchronized (mDataTransferListeners) { it = mDataTransferListeners.iterator(); while (it.hasNext()) { - it.next().onTransferProgress(readCount, mTransferred, size, mFile.getAbsolutePath()); + it.next().onTransferProgress(readCount, mTransferred, mFileSize, mFile.getAbsolutePath()); } } } diff --git a/src/com/owncloud/android/lib/common/network/FileRequestEntity.java b/src/com/owncloud/android/lib/common/network/FileRequestEntity.java index a79e5043ad..dc44b1708a 100644 --- a/src/com/owncloud/android/lib/common/network/FileRequestEntity.java +++ b/src/com/owncloud/android/lib/common/network/FileRequestEntity.java @@ -25,6 +25,8 @@ package com.owncloud.android.lib.common.network; +import org.apache.commons.httpclient.methods.RequestEntity; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -37,10 +39,6 @@ import java.util.Iterator; import java.util.Set; -import org.apache.commons.httpclient.methods.RequestEntity; - -import com.owncloud.android.lib.common.utils.Log_OC; - /** @@ -51,12 +49,14 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer final File mFile; final String mContentType; + final long mFileSize; Set mDataTransferListeners = new HashSet(); - public FileRequestEntity(final File file, final String contentType) { + public FileRequestEntity(final File file, final String contentType, long fileSize) { super(); this.mFile = file; this.mContentType = contentType; + this.mFileSize = fileSize; if (file == null) { throw new IllegalArgumentException("File may not be null"); } @@ -64,7 +64,11 @@ public FileRequestEntity(final File file, final String contentType) { @Override public long getContentLength() { - return mFile.length(); + if (mFileSize > 0) { + return mFileSize; + } else { + return mFile.length(); + } } @Override @@ -108,7 +112,7 @@ public void writeRequest(final OutputStream out) throws IOException { FileChannel channel = raf.getChannel(); Iterator it = null; long transferred = 0; - long size = mFile.length(); + long size = getContentLength(); if (size == 0) size = -1; try { while ((readResult = channel.read(tmp)) >= 0) { diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index a2f16068cc..a2a1e23dbc 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -57,8 +57,9 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation private Context mContext; public ChunkedUploadRemoteFileOperation(Context context, String storagePath, String remotePath, - String mimeType, String requiredEtag, String fileLastModifTimestamp) { - super(storagePath, remotePath, mimeType, requiredEtag, fileLastModifTimestamp); + String mimeType, String requiredEtag, String fileLastModifTimestamp, + long fileSize) { + super(storagePath, remotePath, mimeType, requiredEtag, fileLastModifTimestamp, fileSize); mContext = context; } @@ -84,7 +85,7 @@ protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOExcep try { raf = new RandomAccessFile(file, "r"); channel = raf.getChannel(); - mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file); + mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file, mFileSize); synchronized (mDataTransferListeners) { ((ProgressiveDataTransferer)mEntity) .addDatatransferProgressListeners(mDataTransferListeners); @@ -93,10 +94,17 @@ protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOExcep long offset = 0; String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + chunkId + "-" ; - long totalLength = file.length(); + long totalLength; + + if (mFileSize > 0) { + totalLength = mFileSize; + } else { + totalLength = file.length(); + } + long chunkCount = (long) Math.ceil((double)totalLength / CHUNK_SIZE); String chunkSizeStr = String.valueOf(CHUNK_SIZE); - String totalLengthStr = String.valueOf(file.length()); + String totalLengthStr = String.valueOf(totalLength); for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { if (successfulChunks.contains(String.valueOf(chunkIndex + "_" + getDateAsString()))){ ((ChunkFromFileChannelRequestEntity) mEntity).setmTransferred(offset); diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 6b9b2ac8c8..e730b00e17 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -66,6 +66,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected String mFileLastModifTimestamp; protected PutMethod mPutMethod = null; protected String mRequiredEtag = null; + protected long mFileSize = 0; protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); protected Set mDataTransferListeners = new HashSet(); @@ -86,6 +87,13 @@ public UploadRemoteFileOperation(String localPath, String remotePath, String mim mRequiredEtag = requiredEtag; } + public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType, String requiredEtag, + String fileLastModifTimestamp, long size) { + this(localPath, remotePath, mimeType, fileLastModifTimestamp); + mRequiredEtag = requiredEtag; + mFileSize = size; + } + @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; @@ -138,7 +146,12 @@ protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOExcep try { File f = new File(mLocalPath); - mEntity = new FileRequestEntity(f, mMimeType); + + if (mFileSize == 0) { + mFileSize = f.length(); + } + + mEntity = new FileRequestEntity(f, mMimeType, mFileSize); synchronized (mDataTransferListeners) { ((ProgressiveDataTransferer)mEntity) .addDatatransferProgressListeners(mDataTransferListeners); @@ -146,8 +159,8 @@ protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOExcep if (mRequiredEtag != null && mRequiredEtag.length() > 0) { mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\""); } - mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length())); - mPutMethod.addRequestHeader(OC_X_OC_MTIME_HEADER, mFileLastModifTimestamp); + mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(mFileSize)); + mPutMethod.addRequestHeader(OC_X_OC_MTIME_HEADER, mFileLastModifTimestamp); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); diff --git a/test_client/src/main/java/com/owncloud/android/lib/testclient/TestActivity.java b/test_client/src/main/java/com/owncloud/android/lib/testclient/TestActivity.java index 0db227e777..276c7f8fd1 100644 --- a/test_client/src/main/java/com/owncloud/android/lib/testclient/TestActivity.java +++ b/test_client/src/main/java/com/owncloud/android/lib/testclient/TestActivity.java @@ -267,10 +267,11 @@ public static RemoteOperationResult uploadFile(Context context, String storagePa String fileLastModifTimestamp = getFileLastModifTimeStamp(storagePath); UploadRemoteFileOperation uploadOperation; + long fileSize = (new File(storagePath)).length(); - if ((new File(storagePath)).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE) { + if (fileSize > ChunkedUploadRemoteFileOperation.CHUNK_SIZE) { uploadOperation = new ChunkedUploadRemoteFileOperation( - context, storagePath, remotePath, mimeType, requiredEtag, fileLastModifTimestamp + context, storagePath, remotePath, mimeType, requiredEtag, fileLastModifTimestamp, fileSize ); } else { uploadOperation = new UploadRemoteFileOperation(