1 /***************************************************************************
2                           netfilecontrol.cpp  -  Automatic downloading + uploading of data files
3                              -------------------
4     begin                : di aug 30 2005
5     copyright            : (C) 2005 by CJP
6     email                : cornware-cjp@users.sourceforge.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include <cstdio>
19 
20 #include "netfilecontrol.h"
21 
22 #include "clientnet.h"
23 #include "filechunk.h"
24 #include "datafile.h"
25 #include "netmessages.h"
26 
CNetFileControl()27 CNetFileControl::CNetFileControl() : CFileControl(false)
28 {
29 	m_OriginalFileControl = theFileControl;
30 	theFileControl = this;
31 	m_Network = NULL;
32 }
33 
~CNetFileControl()34 CNetFileControl::~CNetFileControl()
35 {
36 	theFileControl = m_OriginalFileControl;
37 }
38 
setNetwork(CClientNet * net)39 void CNetFileControl::setNetwork(CClientNet *net)
40 {
41 	m_Network = net;
42 }
43 
getLongFilename(const CString & shortName)44 CString CNetFileControl::getLongFilename(const CString &shortName)
45 {
46 	CString localfile = m_OriginalFileControl->getLongFilename(shortName);
47 
48 	//TODO: check if this is the same file as on the server
49 	if(localfile != "") return localfile;
50 
51 	//Just in cases when there is no network available (should not happen here)
52 	if(m_Network == NULL)
53 		return "";
54 
55 	//File transfer over network
56 	int retID = m_Network->sendTextMessage(CString(USNET_GET) + shortName); //requesting the file
57 	if(retID > 0) //It has the file
58 	{
59 		CFileChunk theChunk;
60 
61 		printf("Downloading file %s\n", shortName.c_str());
62 
63 		//Downloading the first chunk
64 		while(theChunk.m_Filename != shortName)
65 		{
66 			//the first chunk, timeout of 5 seconds
67 			CMessageBuffer *buf = m_Network->receiveExpectedData(CMessageBuffer::fileChunk, 5000);
68 
69 			if(buf == NULL)
70 			{
71 				printf("  Warning: server didn't send file %s\n", shortName.c_str());
72 				return ""; //server didn't send any chunk
73 			}
74 
75 			m_Network->sendConfirmation(*buf, 0);
76 
77 			theChunk.setBuffer(*buf);
78 			delete buf;
79 		}
80 
81 		//File properties
82 		unsigned int fileSize = theChunk.m_FileSize;
83 		unsigned int numChunks = fileSize / FILECHUNK_SIZE;
84 		if(FILECHUNK_SIZE * numChunks < fileSize) numChunks++; //there is a last, smaller chunk
85 
86 		//The data buffer
87 		vector<CBinBuffer> receivedBuffers;
88 		receivedBuffers.resize(numChunks);
89 		receivedBuffers[theChunk.m_ChunkID] = theChunk.m_Data;
90 		unsigned int numReceived = 1;
91 
92 		//Downloading the other chunks
93 		while(numReceived < numChunks)
94 		{
95 			CMessageBuffer *buf = m_Network->receiveExpectedData(CMessageBuffer::fileChunk, 5000);
96 
97 			if(buf == NULL)
98 			{
99 				printf("  Warning: downloading of file %s has stopped\n", shortName.c_str());
100 				return ""; //didn't receive any chunks anymore
101 			}
102 
103 			m_Network->sendConfirmation(*buf, 0);
104 
105 			theChunk.setBuffer(*buf);
106 			delete buf;
107 
108 			if(theChunk.m_Filename != shortName) continue; //not a chunk for this file
109 
110 			if(receivedBuffers[theChunk.m_ChunkID].size() == 0) //we receive this chunk for the first time
111 			{
112 				receivedBuffers[theChunk.m_ChunkID] = theChunk.m_Data;
113 				numReceived++;
114 				printf("Downloading %s (%d / %d)\r", shortName.c_str(), numReceived, numChunks);
115 			}
116 		}
117 
118 		printf("Downloading %s finished, saving...\n", shortName.c_str());
119 
120 		//Saving the file
121 		CDataFile theFile(shortName, true);
122 		for(unsigned int i=0; i < receivedBuffers.size(); i++)
123 			theFile.writeBytes(receivedBuffers[i]);
124 
125 		return theFile.useExtern();
126 	}
127 
128 	return "";
129 }
130