summaryrefslogtreecommitdiff
path: root/protocols/Tox/src/tox_transfer.h
blob: 640a4f1305b1826432dbd32470dfa5a033ecae77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef _TOX_TRANSFERS_H_
#define _TOX_TRANSFERS_H_

struct FileTransferParam
{
	PROTOFILETRANSFERSTATUS pfts;
	FILE *hFile;
	uint32_t friendNumber;
	uint32_t fileNumber;
	uint64_t transferNumber;

	TOX_FILE_KIND transferType;

	FileTransferParam(uint32_t friendNumber, uint32_t fileNumber, const wchar_t *fileName, uint64_t fileSize)
	{
		hFile = nullptr;
		this->friendNumber = friendNumber;
		this->fileNumber = fileNumber;
		transferNumber = (((int64_t)friendNumber) << 32) | ((int64_t)fileNumber);

		pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
		pfts.flags = PFTS_UNICODE;
		pfts.hContact = NULL;
		pfts.totalFiles = 1;
		pfts.ptszFiles = (wchar_t**)mir_alloc(sizeof(wchar_t*)*(pfts.totalFiles + 1));
		pfts.ptszFiles[0] = pfts.tszCurrentFile = mir_wstrdup(fileName);
		pfts.ptszFiles[pfts.totalFiles] = nullptr;
		pfts.totalBytes = pfts.currentFileSize = fileSize;
		pfts.totalProgress = pfts.currentFileProgress = 0;
		pfts.currentFileNumber = 0;
		pfts.currentFileTime = now();
		pfts.tszWorkingDir = nullptr;

		transferType = TOX_FILE_KIND_DATA;
	}

	bool OpenFile(const wchar_t *mode)
	{
		hFile = _wfopen(pfts.tszCurrentFile, mode);
		return hFile != nullptr;
	}

	void ChangeName(const wchar_t *fileName)
	{
		pfts.ptszFiles[0] = replaceStrW(pfts.tszCurrentFile, fileName);
	}

	uint8_t GetDirection() const
	{
		return (pfts.flags & PFTS_SENDING) ? 0 : 1;
	}

	~FileTransferParam()
	{
		if (pfts.tszWorkingDir != nullptr)
			mir_free(pfts.tszWorkingDir);
		mir_free(pfts.pszFiles[0]);
		mir_free(pfts.pszFiles);
		if (hFile != nullptr)
		{
			fclose(hFile);
			hFile = nullptr;
		}
	}
};

struct AvatarTransferParam : public FileTransferParam
{
	uint8_t hash[TOX_HASH_LENGTH];

	AvatarTransferParam(uint32_t friendNumber, uint32_t fileNumber, const wchar_t *fileName, uint64_t fileSize)
		: FileTransferParam(friendNumber, fileNumber, fileName, fileSize)
	{
		transferType = TOX_FILE_KIND_AVATAR;
	}
};

class CTransferList
{
private:
	std::map<int64_t, FileTransferParam*> transfers;

public:
	size_t Count() const
	{
		return transfers.size();
	}

	void Add(FileTransferParam *transfer)
	{
		if (transfers.find(transfer->transferNumber) == transfers.end())
			transfers[transfer->transferNumber] = transfer;
	}

	FileTransferParam* Get(uint32_t friendNumber, uint32_t fileNumber)
	{
		int64_t transferNumber = (((int64_t)friendNumber) << 32) | ((int64_t)fileNumber);
		if (transfers.find(transferNumber) != transfers.end())
			return transfers.at(transferNumber);
		return nullptr;
	}

	FileTransferParam* GetAt(size_t index)
	{
		if (index < Count()) {
			auto it = transfers.begin();
			std::advance(it, index);
			return it->second;
		}
		return nullptr;
	}

	void Remove(FileTransferParam *transfer)
	{
		if (transfer == nullptr)
			return;
		transfers.erase(transfer->transferNumber);
		delete transfer;
	}
};

#endif //_TOX_TRANSFERS_H_