void FileTransferSocket::_filePullDataRspResponse(CImPdu* pdu)//收
{
	CImPduClientFilePullDataRsp* pDataRsp = (CImPduClientFilePullDataRsp*)pdu;
	UInt32 nRes = pDataRsp->GetResult();
	if (FILE_SERVER_ERRNO_OK != nRes)
	{
		APP_LOG(LOG_ERROR, _T("PullDataRspResponse: error result:%d"),nRes);
		return;
	}
	std::string taskId(pDataRsp->GetTaskId(), pDataRsp->GetTaskIdLen());
	void* pData = pDataRsp->GetData();
	UInt32 fileSize = pDataRsp->GetDataSize();
	UInt32 fileOffset = pDataRsp->GetOffset();
	TransferFileEntity fileEntity;
	if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
	{
		APP_LOG(LOG_ERROR, _T("PullDataRspResponse: can't find the fileInfo"));
		return;
	}
	APP_LOG(LOG_DEBUG, _T("receive:taskId=%s,filesize=%d,name=%s")
		, util::stringToCString(fileEntity.sTaskID)
		, fileEntity.nFileSize
		, fileEntity.getRealFileName());

	//存文件...
	if (!fileEntity.pFileObject->writeBlock(fileOffset, fileSize, pData))
	{
		APP_LOG(LOG_DEBUG, _T("FileTransferSocket::_filePullDataRspResponse-writeBlock failed "));
		return;
	}

	fileEntity.nProgress = fileOffset + fileSize;
	if (fileEntity.nProgress <= fileEntity.nFileSize)
	{
		//更新进度条
		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);//保存当前进度
		logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_PROGRESSBAR, fileEntity.sTaskID);

		//继续发file block req...
		int mode = fileEntity.nClientMode == CLIENT_OFFLINE_DOWNLOAD ? FILE_TYPE_OFFLINE : FILE_TYPE_ONLINE;
		CImPduClientFilePullDataReq pduPullDataReq(taskId.c_str(), fileEntity.sToID.c_str()
			, mode, fileEntity.nProgress, fileSize);
		sendPacket(&pduPullDataReq);
	}
	else//传输完成
	{
		if (fileEntity.pFileObject)
		{
			delete fileEntity.pFileObject;
			fileEntity.pFileObject = nullptr;
		}
		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
		logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
	}
}
void FileTransferModule_Impl::_sendfileResponse(IN std::string& body)
{
    IM::File::IMFileRsp imFileRsp;
    if (!imFileRsp.ParseFromString(body))
    {
        LOG__(ERR, _T("parse failed,body:%s"), util::stringToCString(body));
        return;
    }

    UInt32 nResult = imFileRsp.result_code();
    if (nResult != 0)
    {
        LOG__(ERR, _T("_sendfileResponse result != 0"));
        module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_UPLOAD_FAILED);
    }

    TransferFileEntity fileEntity;
    fileEntity.sTaskID = imFileRsp.task_id();
    assert(!fileEntity.sTaskID.empty());
    fileEntity.sFromID = util::uint32ToString(imFileRsp.from_user_id());
    fileEntity.sToID = util::uint32ToString(imFileRsp.to_user_id());
    fileEntity.sFileName = imFileRsp.file_name();
    fileEntity.setSaveFilePath(util::stringToCString(fileEntity.sFileName));//发送方文件地址,就是保存地址
    fileEntity.time = static_cast<UInt32>(time(0));
    uint32_t transMode = imFileRsp.trans_mode();
    if (IM::BaseDefine::FileType::FILE_TYPE_ONLINE == transMode)
    {
        fileEntity.nClientMode = IM::BaseDefine::ClientFileRole::CLIENT_REALTIME_SENDER;
    }
    else if (IM::BaseDefine::FileType::FILE_TYPE_OFFLINE == transMode)
    {
        fileEntity.nClientMode = IM::BaseDefine::ClientFileRole::CLIENT_OFFLINE_UPLOAD;
    }
    fileEntity.pFileObject = new TransferFile(util::stringToCString(fileEntity.sFileName),FALSE);
    if (fileEntity.pFileObject)
    {
        fileEntity.nFileSize = fileEntity.pFileObject->length();
    }

    UINT32 nIPCount = imFileRsp.ip_addr_list_size();
    if (nIPCount <= 0)
    {
        return;
    }
    const IM::BaseDefine::IpAddr& ipAdd = imFileRsp.ip_addr_list(0);
    fileEntity.sIP = ipAdd.ip();
    fileEntity.nPort = ipAdd.port();

    if (!TransferFileEntityManager::getInstance()->pushTransferFileEntity(fileEntity))
        TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);

    LOG__(DEBG, _T("FileTransferSevice_Impl::准备连接文件服务器 sTaskId = %s"), util::stringToCString(fileEntity.sTaskID));
    TransferFileEntityManager::getInstance()->openFileSocketByTaskId(fileEntity.sTaskID);
}
void FileTransferSocket::_filePullDataReqResponse(CImPdu* pdu)//发
{
	CImPduClientFilePullDataReq* pData = (CImPduClientFilePullDataReq*)pdu;
	UInt32 fileSize = pData->GetDataSize();
	UInt32 fileOffset = pData->GetOffset();
	std::string taskId = std::string(pData->GetTaskId(),pData->GetTaskIdLen());
	
	TransferFileEntity fileEntity;
	if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
	{
		APP_LOG(LOG_ERROR, _T("PullDataReqResponse: can't find the fileInfo"));
		return;
	}
	APP_LOG(LOG_DEBUG, _T("send:taskId=%s,filesize=%d,name=%s")
		,util::stringToCString(fileEntity.sTaskID)
		,fileEntity.nFileSize
		,fileEntity.getRealFileName());
	std::string buff;
	if (nullptr == fileEntity.pFileObject)
	{
		APP_LOG(LOG_ERROR, _T("PullDataReqResponse: file boject Destoryed!"));
		return;
	}
	fileEntity.pFileObject->readBlock(fileOffset, fileSize, buff);
	CImPduClientFilePullDataRsp pduPullDataRep(taskId.c_str()
		, fileEntity.sFromID.c_str(), fileOffset, fileSize, (uchar_t*)buff.data());
	sendPacket(&pduPullDataRep);

	fileEntity.nProgress = fileOffset + fileSize;
	if (fileEntity.nProgress <= fileEntity.nFileSize)
	{
		//更新进度条
		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);//保存当前进度
		logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_PROGRESSBAR, fileEntity.sTaskID);
	}
	else//传输完成
	{
		if (fileEntity.pFileObject)
		{
			delete fileEntity.pFileObject;
			fileEntity.pFileObject = nullptr;
		}
		logic::GetLogic()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
	}
	TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
}
BOOL FileTransferModule_Impl::acceptFileTransfer(IN const std::string& sTaskId, IN const BOOL bAccept /*= TRUE*/)
{
    TransferFileEntity FileInfo;
    if (TransferFileEntityManager::getInstance()->getFileInfoByTaskId(sTaskId, FileInfo))
    {
        if (bAccept)//接收文件
        {
            FileInfo.pFileObject = new TransferFile(FileInfo.getSaveFilePath(), TRUE);
            FileInfo.time = static_cast<UInt32>(time(0));
            TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(FileInfo);
            LOG__(DEBG, _T("FileTransferSevice_Impl::acceptFileTransfer 接收文件 sFileID = %s"), util::stringToCString(FileInfo.sTaskID));
            TransferFileEntityManager::getInstance()->acceptFileTransfer(std::string(sTaskId));
        }
        else//拒绝文件
        {
            if (IM::BaseDefine::ClientFileRole::CLIENT_REALTIME_RECVER == FileInfo.nClientMode)//在线文件
            {
                LOG__(DEBG, _T("FileTransferSevice_Impl::acceptFileTransfer 拒绝文件 sFileID = %s"), util::stringToCString(FileInfo.sTaskID));
                TransferFileEntityManager::getInstance()->rejectFileTransfer(sTaskId);
            }
            else if (IM::BaseDefine::ClientFileRole::CLIENT_OFFLINE_DOWNLOAD == FileInfo.nClientMode)//离线文件
            {
                LOG__(DEBG, _T("FileTransferSevice_Impl::acceptFileTransfer 拒绝离线文件 sFileID = %s"), util::stringToCString(FileInfo.sTaskID));
                imcore::IMLibCoreStartOperationWithLambda(
                    [=]()
                {
                    LOG__(APP, _T("拒绝离线文件 imFileDelOfflineReq sFileID = %s"), util::stringToCString(FileInfo.sFileName));
                    IM::File::IMFileDelOfflineReq imFileDelOfflineReq;
                    imFileDelOfflineReq.set_from_user_id(util::stringToInt32(FileInfo.sFromID));
                    imFileDelOfflineReq.set_to_user_id(util::stringToInt32(FileInfo.sToID));
                    imFileDelOfflineReq.set_task_id(FileInfo.sTaskID);
                    module::getTcpClientModule()->sendPacket(IM::BaseDefine::ServiceID::DFFX_SID_FILE
                            , IM::BaseDefine::FileCmdID::DFFX_CID_FILE_DEL_OFFLINE_REQ
                            , &imFileDelOfflineReq);
                });
            }
            module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_UPLOAD_REJECT, FileInfo.sTaskID);
        }
        return TRUE;
    }
    return FALSE;
}
BOOL DatabaseModule_Impl::sqlGetFileTransferHistory(OUT std::vector<TransferFileEntity>& fileList)
{
    try
    {
        CppSQLite3Statement stmt;
        stmt = m_pSqliteDB->compileStatement(getFileTransferHistoryBySIdSql.c_str());
        stmt.bind(1, 20);

        CppSQLite3Query query = stmt.execQuery();
        while (!query.eof())
        {
            TransferFileEntity fileInfo;
            fileInfo.sTaskID = query.getStringField(1);
            fileInfo.sFromID = query.getStringField(2);
            fileInfo.sFileName = query.getStringField(3);
            CString strSavePath = util::stringToCString(query.getStringField(7));
            fileInfo.setSaveFilePath(strSavePath);
            fileInfo.nFileSize = query.getIntField(8);
            fileInfo.time = query.getIntField(9);
            fileList.push_back(fileInfo);
            query.nextRow();
        }
    }
    catch (CppSQLite3Exception& sqliteException)
    {
#ifdef _DEBUG
        MessageBoxA(0, sqliteException.errorMessage(), "BD ERROR", MB_OK | MB_ICONHAND);
#endif
        CString csErrMsg = util::stringToCString(sqliteException.errorMessage(), CP_UTF8);
        LOG__(ERR, _T("db failed,error msg:%s"),
            csErrMsg);
        return FALSE;
    }
    catch (...)
    {
        return FALSE;
    }

    return TRUE;
}
void FileTransferSocket::_filePullDataRspResponse(IN std::string& body)//收
{
	IM::File::IMFilePullDataRsp imFilePullDataRsp;
    if (!imFilePullDataRsp.ParseFromString(body))
    {
        LOG__(ERR, _T("parse failed,body:%s"), util::stringToCString(body));
        return;
    }
	UInt32 nRes = imFilePullDataRsp.result_code();
	if (0 != nRes)
	{
		LOG__(ERR, _T("PullDataRspResponse: error result:%d"),nRes);
		return;
	}
	std::string taskId = imFilePullDataRsp.task_id();
	const std::string& strData = imFilePullDataRsp.file_data();//todo ?????要长度
	void* pData = (void*)(strData.data());
	UInt32 nBlockSize = strData.size();
	UInt32 fileOffset = imFilePullDataRsp.offset();
	TransferFileEntity fileEntity;
	if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
	{
		LOG__(ERR, _T("can't find the fileInfo"));
		return;
	}
	LOG__(DEBG, _T("receive:taskId=%s,filesize=%d,name=%s,BolckSize=%d")
		, util::stringToCString(fileEntity.sTaskID)
		, fileEntity.nFileSize
		, fileEntity.getRealFileName()
        , nBlockSize);

	//存文件...
	if (!fileEntity.pFileObject->writeBlock(fileOffset, nBlockSize, pData))
	{
		LOG__(DEBG, _T("writeBlock failed "));
		return;
	}

	fileEntity.nProgress = fileOffset + nBlockSize;
	if (fileEntity.nProgress < fileEntity.nFileSize)
	{
		//更新进度条
		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);//保存当前进度
		module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_PROGRESSBAR
            , fileEntity.sTaskID);

		//继续发file block req...
		int mode = fileEntity.nClientMode == IM::BaseDefine::ClientFileRole::CLIENT_OFFLINE_DOWNLOAD ? IM::BaseDefine::TransferFileType::FILE_TYPE_OFFLINE : IM::BaseDefine::TransferFileType::FILE_TYPE_ONLINE;
		IM::File::IMFilePullDataReq imFilePullDataReq;
		imFilePullDataReq.set_task_id(taskId);
		imFilePullDataReq.set_user_id(util::stringToInt32(fileEntity.sToID));
		imFilePullDataReq.set_trans_mode(static_cast<IM::BaseDefine::TransferFileType>(mode));
		imFilePullDataReq.set_offset(fileEntity.nProgress);

        UInt32 pullSize = fileEntity.nFileSize - fileEntity.nProgress;
        pullSize > nBlockSize ? imFilePullDataReq.set_data_size(nBlockSize) : imFilePullDataReq.set_data_size(pullSize);
		
		// 发包
        sendPacket(IM::BaseDefine::ServiceID::SID_FILE, IM::BaseDefine::FileCmdID::CID_FILE_PULL_DATA_REQ, &imFilePullDataReq);
	}
	else//传输完成
	{
		if (fileEntity.pFileObject)
		{
			delete fileEntity.pFileObject;
			fileEntity.pFileObject = nullptr;
		}

        //告知对方文件传输完成了。
        IM::File::IMFileState imFileState;
        imFileState.set_state(IM::BaseDefine::ClientFileState::CLIENT_FILE_DONE);
        imFileState.set_task_id(taskId);
        imFileState.set_user_id(util::stringToInt32(fileEntity.sToID));
        sendPacket(IM::BaseDefine::ServiceID::SID_FILE, IM::BaseDefine::FileCmdID::CID_FILE_STATE, &imFileState);

		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
		module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
	}
}
void FileTransferSocket::_filePullDataReqResponse(IN std::string& body)//发
{
	IM::File::IMFilePullDataReq imFilePullDataReq;
    if (!imFilePullDataReq.ParseFromString(body))
    {
        LOG__(ERR, _T("parse failed,body:%s"), util::stringToCString(body));
        return;
    }
	UInt32 fileSize = imFilePullDataReq.data_size();
	UInt32 fileOffset = imFilePullDataReq.offset();
	std::string taskId = imFilePullDataReq.task_id();
	
	TransferFileEntity fileEntity;
	if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
	{
		LOG__(ERR, _T("PullDataReqResponse: can't find the fileInfo"));
		return;
	}
	LOG__(DEBG, _T("send:taskId=%s,filesize=%d,name=%s,BolckSize=%d")
		,util::stringToCString(fileEntity.sTaskID)
		,fileEntity.nFileSize
		,fileEntity.getRealFileName()
        ,fileSize);
	std::string buff;
	if (nullptr == fileEntity.pFileObject)
	{
		LOG__(ERR, _T("PullDataReqResponse: file boject Destoryed!"));
		return;
	}
	fileEntity.pFileObject->readBlock(fileOffset, fileSize, buff);//读取本地文件的数据块
	IM::File::IMFilePullDataRsp imFilePullDataRsp;//todo check
    imFilePullDataRsp.set_result_code(0);
	imFilePullDataRsp.set_task_id(taskId);
	imFilePullDataRsp.set_user_id(util::stringToInt32(fileEntity.sFromID));
	imFilePullDataRsp.set_offset(fileOffset);
    imFilePullDataRsp.set_file_data((void*)buff.data(), fileSize);

    //send packet
    sendPacket(IM::BaseDefine::ServiceID::SID_FILE, IM::BaseDefine::FileCmdID::CID_FILE_PULL_DATA_RSP
        , &imFilePullDataRsp);

	fileEntity.nProgress = fileOffset + fileSize;
	if (fileEntity.nProgress < fileEntity.nFileSize)
	{
		//更新进度条
		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);//保存当前进度
		module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_UPDATA_PROGRESSBAR
            , fileEntity.sTaskID);
	}
	else//传输完成
	{
		if (fileEntity.pFileObject)
		{
			delete fileEntity.pFileObject;
			fileEntity.pFileObject = nullptr;
		}
		module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED
            , fileEntity.sTaskID);
	}
	TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
}