mirror of
https://github.com/SFML/SFML.git
synced 2025-02-12 11:28:00 +08:00
Merge branch 'master' of github.com:LaurentGomila/SFML
This commit is contained in:
commit
337df1ea5f
@ -144,7 +144,9 @@ public :
|
|||||||
/// \brief Change the current playing position of the sound
|
/// \brief Change the current playing position of the sound
|
||||||
///
|
///
|
||||||
/// The playing position can be changed when the sound is
|
/// The playing position can be changed when the sound is
|
||||||
/// either paused or playing.
|
/// either paused or playing. Changing the playing position
|
||||||
|
/// when the sound is stopped has no effect, since playing
|
||||||
|
/// the sound would reset its position.
|
||||||
///
|
///
|
||||||
/// \param timeOffset New playing position, from the beginning of the sound
|
/// \param timeOffset New playing position, from the beginning of the sound
|
||||||
///
|
///
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <SFML/Audio/SoundSource.hpp>
|
#include <SFML/Audio/SoundSource.hpp>
|
||||||
#include <SFML/System/Thread.hpp>
|
#include <SFML/System/Thread.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
#include <SFML/System/Mutex.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
@ -65,8 +66,8 @@ public :
|
|||||||
/// \brief Start or resume playing the audio stream
|
/// \brief Start or resume playing the audio stream
|
||||||
///
|
///
|
||||||
/// This function starts the stream if it was stopped, resumes
|
/// This function starts the stream if it was stopped, resumes
|
||||||
/// it if it was paused, and restarts it from beginning if it
|
/// it if it was paused, and restarts it from the beginning if
|
||||||
/// was it already playing.
|
/// it was already playing.
|
||||||
/// This function uses its own thread so that it doesn't block
|
/// This function uses its own thread so that it doesn't block
|
||||||
/// the rest of the program while the stream is played.
|
/// the rest of the program while the stream is played.
|
||||||
///
|
///
|
||||||
@ -131,7 +132,9 @@ public :
|
|||||||
/// \brief Change the current playing position of the stream
|
/// \brief Change the current playing position of the stream
|
||||||
///
|
///
|
||||||
/// The playing position can be changed when the stream is
|
/// The playing position can be changed when the stream is
|
||||||
/// either paused or playing.
|
/// either paused or playing. Changing the playing position
|
||||||
|
/// when the stream is stopped has no effect, since playing
|
||||||
|
/// the stream would reset its position.
|
||||||
///
|
///
|
||||||
/// \param timeOffset New playing position, from the beginning of the stream
|
/// \param timeOffset New playing position, from the beginning of the stream
|
||||||
///
|
///
|
||||||
@ -285,6 +288,8 @@ private :
|
|||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Thread m_thread; ///< Thread running the background tasks
|
Thread m_thread; ///< Thread running the background tasks
|
||||||
|
mutable Mutex m_threadMutex; ///< Thread mutex
|
||||||
|
Status m_threadStartState; ///< State the thread starts in (Playing, Paused, Stopped)
|
||||||
bool m_isStreaming; ///< Streaming state (true = playing, false = stopped)
|
bool m_isStreaming; ///< Streaming state (true = playing, false = stopped)
|
||||||
unsigned int m_buffers[BufferCount]; ///< Sound buffers used to store temporary audio data
|
unsigned int m_buffers[BufferCount]; ///< Sound buffers used to store temporary audio data
|
||||||
unsigned int m_channelCount; ///< Number of channels (1 = mono, 2 = stereo, ...)
|
unsigned int m_channelCount; ///< Number of channels (1 = mono, 2 = stereo, ...)
|
||||||
|
@ -229,7 +229,7 @@ public :
|
|||||||
/// \param data Data containing the raw listing
|
/// \param data Data containing the raw listing
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
ListingResponse(const Response& response, const std::vector<char>& data);
|
ListingResponse(const Response& response, const std::string& data);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Return the array of directory/file names
|
/// \brief Return the array of directory/file names
|
||||||
@ -452,6 +452,9 @@ public :
|
|||||||
/// current working directory of the server, and the local
|
/// current working directory of the server, and the local
|
||||||
/// destination path is relative to the current directory
|
/// destination path is relative to the current directory
|
||||||
/// of your application.
|
/// of your application.
|
||||||
|
/// If a file with the same filename as the distant file
|
||||||
|
/// already exists in the local destination path, it will
|
||||||
|
/// be overwritten.
|
||||||
///
|
///
|
||||||
/// \param remoteFile Filename of the distant file to download
|
/// \param remoteFile Filename of the distant file to download
|
||||||
/// \param localPath The directory in which to put the file on the local computer
|
/// \param localPath The directory in which to put the file on the local computer
|
||||||
|
@ -306,7 +306,9 @@ public :
|
|||||||
///
|
///
|
||||||
/// \param width Icon's width, in pixels
|
/// \param width Icon's width, in pixels
|
||||||
/// \param height Icon's height, in pixels
|
/// \param height Icon's height, in pixels
|
||||||
/// \param pixels Pointer to the array of pixels in memory
|
/// \param pixels Pointer to the array of pixels in memory. The
|
||||||
|
/// pixels are copied, so you need not keep the
|
||||||
|
/// source alive after calling this function.
|
||||||
///
|
///
|
||||||
/// \see setTitle
|
/// \see setTitle
|
||||||
///
|
///
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <SFML/Audio/ALCheck.hpp>
|
#include <SFML/Audio/ALCheck.hpp>
|
||||||
#include <SFML/System/Sleep.hpp>
|
#include <SFML/System/Sleep.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
#include <SFML/System/Lock.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable : 4355) // 'this' used in base member initializer list
|
#pragma warning(disable : 4355) // 'this' used in base member initializer list
|
||||||
@ -41,6 +42,8 @@ namespace sf
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SoundStream::SoundStream() :
|
SoundStream::SoundStream() :
|
||||||
m_thread (&SoundStream::streamData, this),
|
m_thread (&SoundStream::streamData, this),
|
||||||
|
m_threadMutex (),
|
||||||
|
m_threadStartState(Stopped),
|
||||||
m_isStreaming (false),
|
m_isStreaming (false),
|
||||||
m_channelCount (0),
|
m_channelCount (0),
|
||||||
m_sampleRate (0),
|
m_sampleRate (0),
|
||||||
@ -56,7 +59,15 @@ m_samplesProcessed(0)
|
|||||||
SoundStream::~SoundStream()
|
SoundStream::~SoundStream()
|
||||||
{
|
{
|
||||||
// Stop the sound if it was playing
|
// Stop the sound if it was playing
|
||||||
stop();
|
|
||||||
|
// Request the thread to terminate
|
||||||
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
m_isStreaming = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the thread to terminate
|
||||||
|
m_thread.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -89,12 +100,30 @@ void SoundStream::play()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the sound is already playing (probably paused), just resume it
|
bool isStreaming = false;
|
||||||
if (m_isStreaming)
|
Status threadStartState = Stopped;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
|
||||||
|
isStreaming = m_isStreaming;
|
||||||
|
threadStartState = m_threadStartState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isStreaming && (threadStartState == Paused))
|
||||||
|
{
|
||||||
|
// If the sound is paused, resume it
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
m_threadStartState = Playing;
|
||||||
alCheck(alSourcePlay(m_source));
|
alCheck(alSourcePlay(m_source));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (isStreaming && (threadStartState == Playing))
|
||||||
|
{
|
||||||
|
// If the sound is playing, stop it and continue as if it was stopped
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
// Move to the beginning
|
// Move to the beginning
|
||||||
onSeek(Time::Zero);
|
onSeek(Time::Zero);
|
||||||
@ -102,6 +131,7 @@ void SoundStream::play()
|
|||||||
// Start updating the stream in a separate thread to avoid blocking the application
|
// Start updating the stream in a separate thread to avoid blocking the application
|
||||||
m_samplesProcessed = 0;
|
m_samplesProcessed = 0;
|
||||||
m_isStreaming = true;
|
m_isStreaming = true;
|
||||||
|
m_threadStartState = Playing;
|
||||||
m_thread.launch();
|
m_thread.launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +139,16 @@ void SoundStream::play()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SoundStream::pause()
|
void SoundStream::pause()
|
||||||
{
|
{
|
||||||
|
// Handle pause() being called before the thread has started
|
||||||
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
|
||||||
|
if (!m_isStreaming)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_threadStartState = Paused;
|
||||||
|
}
|
||||||
|
|
||||||
alCheck(alSourcePause(m_source));
|
alCheck(alSourcePause(m_source));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +156,20 @@ void SoundStream::pause()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SoundStream::stop()
|
void SoundStream::stop()
|
||||||
{
|
{
|
||||||
|
// Request the thread to terminate
|
||||||
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
m_isStreaming = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the thread to terminate
|
// Wait for the thread to terminate
|
||||||
m_isStreaming = false;
|
|
||||||
m_thread.wait();
|
m_thread.wait();
|
||||||
|
|
||||||
|
// Move to the beginning
|
||||||
|
onSeek(Time::Zero);
|
||||||
|
|
||||||
|
// Reset the playing position
|
||||||
|
m_samplesProcessed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,8 +193,13 @@ SoundStream::Status SoundStream::getStatus() const
|
|||||||
Status status = SoundSource::getStatus();
|
Status status = SoundSource::getStatus();
|
||||||
|
|
||||||
// To compensate for the lag between play() and alSourceplay()
|
// To compensate for the lag between play() and alSourceplay()
|
||||||
if ((status == Stopped) && m_isStreaming)
|
if (status == Stopped)
|
||||||
status = Playing;
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
|
||||||
|
if (m_isStreaming)
|
||||||
|
status = m_threadStartState;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -152,6 +208,9 @@ SoundStream::Status SoundStream::getStatus() const
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SoundStream::setPlayingOffset(Time timeOffset)
|
void SoundStream::setPlayingOffset(Time timeOffset)
|
||||||
{
|
{
|
||||||
|
// Get old playing status
|
||||||
|
Status oldStatus = getStatus();
|
||||||
|
|
||||||
// Stop the stream
|
// Stop the stream
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
@ -160,7 +219,12 @@ void SoundStream::setPlayingOffset(Time timeOffset)
|
|||||||
|
|
||||||
// Restart streaming
|
// Restart streaming
|
||||||
m_samplesProcessed = static_cast<Uint64>(timeOffset.asSeconds() * m_sampleRate * m_channelCount);
|
m_samplesProcessed = static_cast<Uint64>(timeOffset.asSeconds() * m_sampleRate * m_channelCount);
|
||||||
|
|
||||||
|
if (oldStatus == Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
m_isStreaming = true;
|
m_isStreaming = true;
|
||||||
|
m_threadStartState = oldStatus;
|
||||||
m_thread.launch();
|
m_thread.launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,19 +263,42 @@ bool SoundStream::getLoop() const
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SoundStream::streamData()
|
void SoundStream::streamData()
|
||||||
{
|
{
|
||||||
// Create the buffers
|
bool requestStop = false;
|
||||||
alCheck(alGenBuffers(BufferCount, m_buffers));
|
|
||||||
for (int i = 0; i < BufferCount; ++i)
|
|
||||||
m_endBuffers[i] = false;
|
|
||||||
|
|
||||||
// Fill the queue
|
|
||||||
bool requestStop = fillQueue();
|
|
||||||
|
|
||||||
// Play the sound
|
|
||||||
alCheck(alSourcePlay(m_source));
|
|
||||||
|
|
||||||
while (m_isStreaming)
|
|
||||||
{
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
|
||||||
|
// Check if the thread was launched Stopped
|
||||||
|
if (m_threadStartState == Stopped)
|
||||||
|
{
|
||||||
|
m_isStreaming = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the buffers
|
||||||
|
alCheck(alGenBuffers(BufferCount, m_buffers));
|
||||||
|
for (int i = 0; i < BufferCount; ++i)
|
||||||
|
m_endBuffers[i] = false;
|
||||||
|
|
||||||
|
// Fill the queue
|
||||||
|
requestStop = fillQueue();
|
||||||
|
|
||||||
|
// Play the sound
|
||||||
|
alCheck(alSourcePlay(m_source));
|
||||||
|
|
||||||
|
// Check if the thread was launched Paused
|
||||||
|
if (m_threadStartState == Paused)
|
||||||
|
alCheck(alSourcePause(m_source));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
if (!m_isStreaming)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// The stream has been interrupted!
|
// The stream has been interrupted!
|
||||||
if (SoundSource::getStatus() == Stopped)
|
if (SoundSource::getStatus() == Stopped)
|
||||||
{
|
{
|
||||||
@ -223,6 +310,7 @@ void SoundStream::streamData()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// End streaming
|
// End streaming
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
m_isStreaming = false;
|
m_isStreaming = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,6 +354,7 @@ void SoundStream::streamData()
|
|||||||
<< "and initialize() has been called correctly" << std::endl;
|
<< "and initialize() has been called correctly" << std::endl;
|
||||||
|
|
||||||
// Abort streaming (exit main loop)
|
// Abort streaming (exit main loop)
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
m_isStreaming = false;
|
m_isStreaming = false;
|
||||||
requestStop = true;
|
requestStop = true;
|
||||||
break;
|
break;
|
||||||
|
@ -27,11 +27,13 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Network/Ftp.hpp>
|
#include <SFML/Network/Ftp.hpp>
|
||||||
#include <SFML/Network/IpAddress.hpp>
|
#include <SFML/Network/IpAddress.hpp>
|
||||||
|
#include <SFML/System/Err.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
@ -48,10 +50,10 @@ public :
|
|||||||
Ftp::Response open(Ftp::TransferMode mode);
|
Ftp::Response open(Ftp::TransferMode mode);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void send(const std::vector<char>& data);
|
void send(std::istream& stream);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void receive(std::vector<char>& data);
|
void receive(std::ostream& stream);
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
@ -115,17 +117,16 @@ const std::string& Ftp::DirectoryResponse::getDirectory() const
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Ftp::ListingResponse::ListingResponse(const Ftp::Response& response, const std::vector<char>& data) :
|
Ftp::ListingResponse::ListingResponse(const Ftp::Response& response, const std::string& data) :
|
||||||
Ftp::Response(response)
|
Ftp::Response(response)
|
||||||
{
|
{
|
||||||
if (isOk())
|
if (isOk())
|
||||||
{
|
{
|
||||||
// Fill the array of strings
|
// Fill the array of strings
|
||||||
std::string paths(data.begin(), data.end());
|
|
||||||
std::string::size_type lastPos = 0;
|
std::string::size_type lastPos = 0;
|
||||||
for (std::string::size_type pos = paths.find("\r\n"); pos != std::string::npos; pos = paths.find("\r\n", lastPos))
|
for (std::string::size_type pos = data.find("\r\n"); pos != std::string::npos; pos = data.find("\r\n", lastPos))
|
||||||
{
|
{
|
||||||
m_listing.push_back(paths.substr(lastPos, pos - lastPos));
|
m_listing.push_back(data.substr(lastPos, pos - lastPos));
|
||||||
lastPos = pos + 2;
|
lastPos = pos + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +207,7 @@ Ftp::DirectoryResponse Ftp::getWorkingDirectory()
|
|||||||
Ftp::ListingResponse Ftp::getDirectoryListing(const std::string& directory)
|
Ftp::ListingResponse Ftp::getDirectoryListing(const std::string& directory)
|
||||||
{
|
{
|
||||||
// Open a data channel on default port (20) using ASCII transfer mode
|
// Open a data channel on default port (20) using ASCII transfer mode
|
||||||
std::vector<char> directoryData;
|
std::ostringstream directoryData;
|
||||||
DataChannel data(*this);
|
DataChannel data(*this);
|
||||||
Response response = data.open(Ascii);
|
Response response = data.open(Ascii);
|
||||||
if (response.isOk())
|
if (response.isOk())
|
||||||
@ -223,7 +224,7 @@ Ftp::ListingResponse Ftp::getDirectoryListing(const std::string& directory)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ListingResponse(response, directoryData);
|
return ListingResponse(response, directoryData.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -285,33 +286,34 @@ Ftp::Response Ftp::download(const std::string& remoteFile, const std::string& lo
|
|||||||
response = sendCommand("RETR", remoteFile);
|
response = sendCommand("RETR", remoteFile);
|
||||||
if (response.isOk())
|
if (response.isOk())
|
||||||
{
|
{
|
||||||
|
// Extract the filename from the file path
|
||||||
|
std::string filename = remoteFile;
|
||||||
|
std::string::size_type pos = filename.find_last_of("/\\");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
filename = filename.substr(pos + 1);
|
||||||
|
|
||||||
|
// Make sure the destination path ends with a slash
|
||||||
|
std::string path = localPath;
|
||||||
|
if (!path.empty() && (path[path.size() - 1] != '\\') && (path[path.size() - 1] != '/'))
|
||||||
|
path += "/";
|
||||||
|
|
||||||
|
// Create the file and truncate it if necessary
|
||||||
|
std::ofstream file((path + filename).c_str(), std::ios_base::binary | std::ios_base::trunc);
|
||||||
|
if (!file)
|
||||||
|
return Response(Response::InvalidFile);
|
||||||
|
|
||||||
// Receive the file data
|
// Receive the file data
|
||||||
std::vector<char> fileData;
|
data.receive(file);
|
||||||
data.receive(fileData);
|
|
||||||
|
// Close the file
|
||||||
|
file.close();
|
||||||
|
|
||||||
// Get the response from the server
|
// Get the response from the server
|
||||||
response = getResponse();
|
response = getResponse();
|
||||||
if (response.isOk())
|
|
||||||
{
|
|
||||||
// Extract the filename from the file path
|
|
||||||
std::string filename = remoteFile;
|
|
||||||
std::string::size_type pos = filename.find_last_of("/\\");
|
|
||||||
if (pos != std::string::npos)
|
|
||||||
filename = filename.substr(pos + 1);
|
|
||||||
|
|
||||||
// Make sure the destination path ends with a slash
|
// If the download was unsuccessful, delete the partial file
|
||||||
std::string path = localPath;
|
if (!response.isOk())
|
||||||
if (!path.empty() && (path[path.size() - 1] != '\\') && (path[path.size() - 1] != '/'))
|
std::remove((path + filename).c_str());
|
||||||
path += "/";
|
|
||||||
|
|
||||||
// Create the file and copy the received data into it
|
|
||||||
std::ofstream file((path + filename).c_str(), std::ios_base::binary);
|
|
||||||
if (!file)
|
|
||||||
return Response(Response::InvalidFile);
|
|
||||||
|
|
||||||
if (!fileData.empty())
|
|
||||||
file.write(&fileData[0], static_cast<std::streamsize>(fileData.size()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,13 +329,6 @@ Ftp::Response Ftp::upload(const std::string& localFile, const std::string& remot
|
|||||||
if (!file)
|
if (!file)
|
||||||
return Response(Response::InvalidFile);
|
return Response(Response::InvalidFile);
|
||||||
|
|
||||||
file.seekg(0, std::ios::end);
|
|
||||||
std::size_t length = static_cast<std::size_t>(file.tellg());
|
|
||||||
file.seekg(0, std::ios::beg);
|
|
||||||
std::vector<char> fileData(length);
|
|
||||||
if (length > 0)
|
|
||||||
file.read(&fileData[0], static_cast<std::streamsize>(length));
|
|
||||||
|
|
||||||
// Extract the filename from the file path
|
// Extract the filename from the file path
|
||||||
std::string filename = localFile;
|
std::string filename = localFile;
|
||||||
std::string::size_type pos = filename.find_last_of("/\\");
|
std::string::size_type pos = filename.find_last_of("/\\");
|
||||||
@ -355,7 +350,7 @@ Ftp::Response Ftp::upload(const std::string& localFile, const std::string& remot
|
|||||||
if (response.isOk())
|
if (response.isOk())
|
||||||
{
|
{
|
||||||
// Send the file data
|
// Send the file data
|
||||||
data.send(fileData);
|
data.send(file);
|
||||||
|
|
||||||
// Get the response from the server
|
// Get the response from the server
|
||||||
response = getResponse();
|
response = getResponse();
|
||||||
@ -584,15 +579,20 @@ Ftp::Response Ftp::DataChannel::open(Ftp::TransferMode mode)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Ftp::DataChannel::receive(std::vector<char>& data)
|
void Ftp::DataChannel::receive(std::ostream& stream)
|
||||||
{
|
{
|
||||||
// Receive data
|
// Receive data
|
||||||
data.clear();
|
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
std::size_t received;
|
std::size_t received;
|
||||||
while (m_dataSocket.receive(buffer, sizeof(buffer), received) == Socket::Done)
|
while (m_dataSocket.receive(buffer, sizeof(buffer), received) == Socket::Done)
|
||||||
{
|
{
|
||||||
std::copy(buffer, buffer + received, std::back_inserter(data));
|
stream.write(buffer, static_cast<std::streamsize>(received));
|
||||||
|
|
||||||
|
if (!stream.good())
|
||||||
|
{
|
||||||
|
err() << "FTP Error: Writing to the file has failed" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the data socket
|
// Close the data socket
|
||||||
@ -601,11 +601,37 @@ void Ftp::DataChannel::receive(std::vector<char>& data)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Ftp::DataChannel::send(const std::vector<char>& data)
|
void Ftp::DataChannel::send(std::istream& stream)
|
||||||
{
|
{
|
||||||
// Send data
|
// Send data
|
||||||
if (!data.empty())
|
char buffer[1024];
|
||||||
m_dataSocket.send(&data[0], data.size());
|
std::size_t count;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
// read some data from the stream
|
||||||
|
stream.read(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
if (!stream.good() && !stream.eof())
|
||||||
|
{
|
||||||
|
err() << "FTP Error: Reading from the file has failed" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = stream.gcount();
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
// we could read more data from the stream: send them
|
||||||
|
if (m_dataSocket.send(buffer, count) != Socket::Done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no more data: exit the loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Close the data socket
|
// Close the data socket
|
||||||
m_dataSocket.disconnect();
|
m_dataSocket.disconnect();
|
||||||
|
@ -180,7 +180,8 @@ bool EglContext::makeCurrent()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void EglContext::display()
|
void EglContext::display()
|
||||||
{
|
{
|
||||||
eglCheck(eglSwapBuffers(m_display, m_surface));
|
if (m_surface != EGL_NO_SURFACE)
|
||||||
|
eglCheck(eglSwapBuffers(m_display, m_surface));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user