#include "file-protocol.h"
#include "netmanager.h"
#include "neterror.h"
#include "netparameters.h"
namespace Security {
namespace Network {
FileProtocol::FileProtocol(Manager &mgr) : Protocol(mgr, "file")
{
}
FileProtocol::FileTransfer *FileProtocol::makeTransfer(const Target &target, Operation operation)
{
switch (operation) {
case download:
return new Reader(*this, target);
break;
case upload:
return new Writer(*this, target);
default:
Error::throwMe();
}
}
FileProtocol::FileTransfer::FileTransfer(FileProtocol &proto, const Target &tgt, Operation op)
: Transfer(proto, tgt, op)
{
}
int FileProtocol::FileTransfer::fileDesc() const
{ return *this; }
void FileProtocol::FileTransfer::transitError(const CssmCommonError &error)
{
fail();
}
FileProtocol::Reader::Reader(FileProtocol &proto, const Target &tgt)
: FileTransfer(proto, tgt, download)
{
}
void FileProtocol::Reader::start()
{
open(target.path.c_str());
observe(Observer::resourceFound);
observe(Observer::downloading);
setFlag(O_NONBLOCK);
int restartOffset = getv<int>(kNetworkRestartPosition, 0);
if (restartOffset)
seek(restartOffset);
size_t size = fileSize() - restartOffset;
mode(sink(), size);
sink().setSize(size);
protocol.manager.addIO(this);
}
void FileProtocol::Reader::transit(Event event, char *, size_t)
{
assert(event == autoReadDone);
protocol.manager.removeIO(this);
finish();
}
FileProtocol::Writer::Writer(FileProtocol &proto, const Target &tgt)
: FileTransfer(proto, tgt, upload)
{
}
void FileProtocol::Writer::start()
{
open(target.path.c_str(), O_WRONLY | O_CREAT);
observe(Observer::resourceFound);
observe(Observer::uploading);
int restartOffset = getv<int>(kNetworkRestartPosition, 0);
if (restartOffset)
seek(restartOffset);
protocol.manager.addIO(this);
disable(input);
mode(source(), fileSize() - restartOffset);
}
void FileProtocol::Writer::transit(Event event, char *, size_t)
{
assert(event == autoWriteDone);
protocol.manager.removeIO(this);
finish();
}
} }