summaryrefslogtreecommitdiff
path: root/protocols/Skype/src/skype_transfers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Skype/src/skype_transfers.cpp')
-rw-r--r--protocols/Skype/src/skype_transfers.cpp168
1 files changed, 88 insertions, 80 deletions
diff --git a/protocols/Skype/src/skype_transfers.cpp b/protocols/Skype/src/skype_transfers.cpp
index 222ee0ecf7..920e3c4d99 100644
--- a/protocols/Skype/src/skype_transfers.cpp
+++ b/protocols/Skype/src/skype_transfers.cpp
@@ -4,14 +4,14 @@ wchar_t *CSkypeProto::TransferFailureReasons[] =
{
LPGENW("") /* --- */,
LPGENW("SENDER_NOT_AUTHORISED") /* SENDER_NOT_AUTHORISED */,
- LPGENW("REMOTELY_CANCELLED") /* REMOTELY_CANCELLED */,
- LPGENW("FAILED_READ") /* FAILED_READ */,
- LPGENW("FAILED_REMOTE_READ") /* FAILED_REMOTE_READ */,
- LPGENW("FAILED_WRITE") /* FAILED_WRITE */,
- LPGENW("FAILED_REMOTE_WRITE") /* FAILED_REMOTE_WRITE */,
- LPGENW("REMOTE_DOES_NOT_SUPPORT_FT") /* REMOTE_DOES_NOT_SUPPORT_FT */,
- LPGENW("REMOTE_OFFLINE_FOR_TOO_LONG") /* REMOTE_OFFLINE_FOR_TOO_LONG */,
- LPGENW("TOO_MANY_PARALLEL") /* TOO_MANY_PARALLEL */,
+ LPGENW("REMOTELY_CANCELLED") /* REMOTELY_CANCELLED */,
+ LPGENW("FAILED_READ") /* FAILED_READ */,
+ LPGENW("FAILED_REMOTE_READ") /* FAILED_REMOTE_READ */,
+ LPGENW("FAILED_WRITE") /* FAILED_WRITE */,
+ LPGENW("FAILED_REMOTE_WRITE") /* FAILED_REMOTE_WRITE */,
+ LPGENW("REMOTE_DOES_NOT_SUPPORT_FT") /* REMOTE_DOES_NOT_SUPPORT_FT */,
+ LPGENW("REMOTE_OFFLINE_FOR_TOO_LONG") /* REMOTE_OFFLINE_FOR_TOO_LONG */,
+ LPGENW("TOO_MANY_PARALLEL") /* TOO_MANY_PARALLEL */,
LPGENW("PLACEHOLDER_TIMEOUT") /* PLACEHOLDER_TIMEOUT */
};
@@ -23,47 +23,71 @@ void CSkypeProto::OnTransferChanged(const TransferRef &transfer, int prop)
{
Transfer::FAILUREREASON reason;
- /*SEBinary guid;
+ SEBinary guid;
transfer->GetPropChatmsgGuid(guid);
MessageRef msgRef;
this->GetMessageByGuid(guid, msgRef);
-
- uint oid = msgRef->getOID();*/
- uint oid = transfer->getOID();
+ uint oid = msgRef->getOID();
- SEString data;
- transfer->GetPropPartnerHandle(data);
- HANDLE hContact = this->GetContactBySid(ptrW(::mir_utf8decodeW(data)));
+ uint fOid = transfer->getOID();
Transfer::STATUS status;
transfer->GetPropStatus(status);
switch(status)
{
case Transfer::CONNECTING:
- this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)oid, 0);
+ this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)oid, 0);
break;
case Transfer::TRANSFERRING:
case Transfer::TRANSFERRING_OVER_RELAY:
- this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)oid, 0);
+ this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)oid, 0);
break;
case Transfer::FAILED:
transfer->GetPropFailurereason(reason);
- this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oid, (LPARAM)CSkypeProto::TransferFailureReasons[reason]);
+ this->Log(L"File transfer failed: %s", CSkypeProto::TransferFailureReasons[reason]);
this->transferList.remove_val(transfer);
+ this->transferts[oid].files[fOid].isCanceled = true;
break;
case Transfer::COMPLETED:
- this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)oid, 0);
this->transferList.remove_val(transfer);
+ this->transferts[oid].files[fOid].isCompleted = true;
+ this->transferts[oid].pfts.totalProgress += this->transferts[oid].files[fOid].size - this->transferts[oid].files[fOid].transfered;
break;
case Transfer::CANCELLED:
case Transfer::CANCELLED_BY_REMOTE:
transfer->GetPropFailurereason(reason);
- this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)oid, (LPARAM)CSkypeProto::TransferFailureReasons[reason]);
+ this->Log(L"File transfer cancelled: %s", CSkypeProto::TransferFailureReasons[reason]);
this->transferList.remove_val(transfer);
+ this->transferts[oid].files[fOid].isCanceled = true;
break;
}
+
+ int isNotAll = false;
+ for (auto i = this->transferts[oid].files.begin(); i != this->transferts[oid].files.end(); i++)
+ if ( !(i->second.isCanceled || i->second.isCompleted))
+ {
+ isNotAll = true;
+ break;
+ }
+ if (isNotAll)
+ {
+ SEString data;
+ uint fOid = transfer->getOID();
+ transfer->GetPropBytestransferred(data);
+ Sid::uint64 tb = data.toUInt64();
+ this->transferts[oid].pfts.totalProgress += tb;
+ this->transferts[oid].files[fOid].transfered = tb;
+
+ this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&this->transferts[oid].pfts);
+ }
+ else
+ {
+ this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)oid, 0);
+ delete [] this->transferts[oid].pfts.ptszFiles;
+ this->transferts.erase(this->transferts.find(oid));
+ }
}
break;
@@ -71,30 +95,21 @@ void CSkypeProto::OnTransferChanged(const TransferRef &transfer, int prop)
{
SEString data;
- uint oid = transfer->getOID();
-
- PROTOFILETRANSFERSTATUS pfts = {0};
- pfts.cbSize = sizeof(pfts);
- pfts.flags = PFTS_UTF | PFTS_RECEIVING;
- pfts.totalFiles = 1;
- pfts.currentFileNumber = 0;
-
- transfer->GetPropPartnerHandle(data);
- HANDLE hContact = this->GetContactBySid(ptrW(::mir_utf8decodeW(data)));
- pfts.hContact = hContact;
-
- transfer->GetPropFilename(data);
- pfts.szCurrentFile = ::mir_strdup(data);
+ SEBinary guid;
+ transfer->GetPropChatmsgGuid(guid);
- pfts.pszFiles = &pfts.szCurrentFile;
+ MessageRef msgRef;
+ this->GetMessageByGuid(guid, msgRef);
- transfer->GetPropFilesize(data);
- pfts.totalBytes = pfts.currentFileSize = data.toUInt64();
+ uint oid = msgRef->getOID();
+ uint fOid = transfer->getOID();
transfer->GetPropBytestransferred(data);
- pfts.totalProgress = pfts.currentFileProgress = data.toUInt64();
+ Sid::uint64 tb = data.toUInt64();
+ this->transferts[oid].pfts.totalProgress += tb;
+ this->transferts[oid].files[fOid].transfered = tb;
- this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&pfts);
+ this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&this->transferts[oid].pfts);
}
break;
}
@@ -103,81 +118,74 @@ void CSkypeProto::OnTransferChanged(const TransferRef &transfer, int prop)
void CSkypeProto::OnFileEvent(const ConversationRef &conversation, const MessageRef &message)
{
SEString data;
- //bool isRecvFiles = false;
Transfer::TYPE transferType;
Transfer::STATUS transferStatus;
+ ContactRef author;
+ message->GetPropAuthor(data);
+ this->GetContact(data, author);
+
TransferRefs transfers;
message->GetTransfers(transfers);
- wchar_t **files = new wchar_t*[transfers.size()];
+
+ FileTransferParam ftp;
+ ftp.pfts.flags = PFTS_RECEIVING | PFTS_UNICODE;
+ ftp.pfts.hContact = this->AddContact(author, true);
+ ftp.pfts.totalFiles = transfers.size();
+ ftp.pfts.ptszFiles = new wchar_t*[transfers.size() + 1];
+
+ int nifc = 0;
for (size_t i = 0; i < transfers.size(); i++)
{
auto transfer = transfers[i];
- transfer->GetPropFilename(data);
- files[i] = ::mir_utf8decodeW(data);
-
// For incomings, we need to check for transfer status, just to be sure.
// In some cases, a transfer can appear with STATUS == PLACEHOLDER
// As such transfers cannot be accepted, we will need to just store
// the reference to Transfer Object and then check for further
// status changes in Transfer::OnChange
transfer->GetPropStatus(transferStatus);
- if (transferStatus == Transfer::NEW)
+ if (transferStatus == Transfer::NEW || transferStatus == Transfer::PLACEHOLDER)
{
transfer->GetPropType(transferType);
if (transferType == Transfer::INCOMING)
{
- //isRecvFiles = true;
+ transfer->GetPropFilename(data);
+ ftp.pfts.ptszFiles[nifc++] = ::mir_utf8decodeW(data);
- this->transferList.append(transfer);
transfer.fetch();
+ this->transferList.append(transfer);
+ //transfer.fetch();
- uint timestamp;
- message->GetPropTimestamp(timestamp);
-
- ContactRef author;
- message->GetPropAuthor(data);
- this->GetContact(data, author);
-
- HANDLE hContact = this->AddContact(author, true);
+ transfer->GetPropFilesize(data);
+ Sid::uint64 size = data.toUInt64();
- PROTORECVFILET pre = {0};
- pre.flags = PREF_TCHAR;
- pre.fileCount = (int)transfers.size();
- pre.timestamp = timestamp;
- pre.tszDescription = L"";
- pre.ptszFiles = files;
- pre.lParam = (LPARAM)transfer->getOID();
- ::ProtoChainRecvFile(hContact, &pre);
- }
- else if (transferType == Transfer::PLACEHOLDER)
- {
- this->transferList.append(transfer);
- transfer.fetch();
+ ftp.files.insert(std::make_pair(transfer->getOID(), FileParam(size)));
+ ftp.pfts.totalBytes += size;
}
}
}
- /*files[transfers.size()] = NULL;
- if (isRecvFiles)
+ if (nifc > 0)
{
uint timestamp;
message->GetPropTimestamp(timestamp);
- ContactRef author;
- message->GetPropAuthor(data);
- this->GetContact(data, author);
-
- HANDLE hContact = this->AddContact(author, true);
+ auto oid = message->getOID();
+
+ this->transferts.insert(std::make_pair(oid, ftp));
PROTORECVFILET pre = {0};
pre.flags = PREF_TCHAR;
- pre.fileCount = transfers.size();
+ pre.fileCount = ftp.pfts.totalFiles;
pre.timestamp = timestamp;
pre.tszDescription = L"";
- pre.ptszFiles = files;
- pre.lParam = (LPARAM)message->getOID();
- ::ProtoChainRecvFile(hContact, &pre);
- }*/
+ pre.ptszFiles = ftp.pfts.ptszFiles;
+ pre.lParam = (LPARAM)oid;
+ ::ProtoChainRecvFile(ftp.pfts.hContact, &pre);
+ }
+ else
+ {
+ delete [] ftp.pfts.ptszFiles;
+ }
} \ No newline at end of file