Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#610 cant send image in group chat #637

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ IncludeCategories:
- Regex: '^"config\.h"'
Priority: -1
# The main header for a source file automatically gets category 0
- Regex: '.*'
- Regex: '^<[^.]*>'
Priority: 1
- Regex: '^<.*\.h>'
- Regex: '^<.*>'
Priority: 2
- Regex: '.*'
Priority: 3
4 changes: 2 additions & 2 deletions examples/count-bot/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ void processNewMessageEvent(shared_ptr<CoreThread> ct,
LOG(INFO) << "New Message Event: " << endl;
LOG(INFO) << " From: " << para.getPal()->GetKey().ToString() << endl;
for (auto& chip : para.dtlist) {
LOG(INFO) << " Message: " << chip.ToString() << endl;
LOG(INFO) << " Message: " << chip->ToString() << endl;
ostringstream oss;
oss << "your message has " << chip.data.size() << " bytes.";
oss << "your message has " << chip->data.size() << " bytes.";
ct->SendMessage(para.getPal(), oss.str());
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/api/iptux-core/CoreThread.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
#ifndef IPTUX_CORETHREAD_H
#define IPTUX_CORETHREAD_H

#include "iptux-core/Models.h"
#include <atomic>
#include <cstdint>
#include <memory>
#include <netinet/in.h>
#include <vector>

#include <netinet/in.h>
#include <sigc++/signal.h>

#include "iptux-core/Const.h"
#include "iptux-core/Event.h"
#include "iptux-core/Models.h"
#include "iptux-core/ProgramData.h"
#include "iptux-core/TransFileModel.h"

Expand Down Expand Up @@ -126,13 +125,22 @@ class CoreThread {
* @return false if send failed
*/
bool SendMessage(CPPalInfo pal, const std::string& message);
bool SendMessage(CPPalInfo pal, const ChipData& chipData);
bool SendMessage(CPPalInfo pal,
enum GroupMsgOption opttype,
std::shared_ptr<ChipData> chipData);
bool SendMsgPara(std::shared_ptr<MsgPara> msgPara);
bool SendMsgPara(CPPalInfo pal,
enum GroupMsgOption opttype,
std::shared_ptr<MsgPara> msgPara);
void AsyncSendMsgPara(std::shared_ptr<MsgPara> msgPara);
void SendUnitMessage(const PalKey& palKey,
uint32_t opttype,
const std::string& message);
void SendUnitMessage(const PalKey& palKey,
enum GroupMsgOption opttype,
std::shared_ptr<MsgPara> msgPara);
void SendGroupMessage(const PalKey& palKey, const std::string& message);
void SendGroupMessage(const PalKey& palKey, std::shared_ptr<MsgPara> msgPara);

bool SendAskShared(PPalInfo pal);
bool SendAskSharedWithPassword(const PalKey& palKey,
Expand Down
13 changes: 10 additions & 3 deletions src/api/iptux-core/Models.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,15 @@ using PFileInfo = std::shared_ptr<FileInfo>;
*/
class ChipData {
public:
static std::shared_ptr<ChipData> newTxtMsg(const std::string& text);
static std::shared_ptr<ChipData> newImgMsg(const std::string& picPath,
bool deleteFileAfterSent = true);

private:
explicit ChipData(const std::string& data);
ChipData(MessageContentType type, const std::string& data);

public:
~ChipData();

std::string ToString() const;
Expand Down Expand Up @@ -226,9 +233,9 @@ class MsgPara {

CPPalInfo getPal() const { return pal; }

MessageSourceType stype; ///< 来源类型
GroupBelongType btype; ///< 所属类型
std::vector<ChipData> dtlist; ///< 数据链表 *
MessageSourceType stype; ///< 来源类型
GroupBelongType btype; ///< 所属类型
std::vector<std::shared_ptr<ChipData>> dtlist; ///< 数据链表 *
private:
CPPalInfo pal; ///< 好友数据信息(来自好友*)
};
Expand Down
12 changes: 7 additions & 5 deletions src/iptux-core/Const.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ const int MAX_PHOTOSIZE = 300;
const int MAX_UDPLEN = 8192;
const int MAX_SHAREDFILE = 10000;

const uint32_t IPTUX_REGULAROPT = 0x00000100UL;
const uint32_t IPTUX_SEGMENTOPT = 0x00000200UL;
const uint32_t IPTUX_GROUPOPT = 0x00000300UL;
const uint32_t IPTUX_BROADCASTOPT = 0x00000400UL;
enum GroupMsgOption {
IPTUX_REGULAROPT = 0x00000100UL,
IPTUX_SEGMENTOPT = 0x00000200UL,
IPTUX_GROUPOPT = 0x00000300UL,
IPTUX_BROADCASTOPT = 0x00000400UL,
};
} // namespace iptux

#endif
#endif
37 changes: 23 additions & 14 deletions src/iptux-core/CoreThread.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
#include "config.h"
#include "iptux-core/CoreThread.h"

#include <deque>
#include <fstream>
#include <functional>
#include <future>
#include <memory>
#include <mutex>
#include <thread>

#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <glog/logging.h>
#include <poll.h>
#include <sys/stat.h>

#include "iptux-core/Exception.h"
#include "iptux-core/Models.h"
#include "iptux-core/internal/Command.h"
#include "iptux-core/internal/RecvFileData.h"
#include "iptux-core/internal/SendFile.h"
Expand Down Expand Up @@ -477,12 +475,13 @@ bool CoreThread::SendMessage(CPPalInfo palInfo, const string& message) {
return true;
}

bool CoreThread::SendMessage(CPPalInfo pal, const ChipData& chipData) {
auto ptr = chipData.data.c_str();
switch (chipData.type) {
bool CoreThread::SendMessage(CPPalInfo pal,
enum GroupMsgOption option,
shared_ptr<ChipData> chipData) {
switch (chipData->type) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Null pointer check for chipData

Ensure that chipData is not null before dereferencing it to avoid potential null pointer dereference.

case MessageContentType::STRING:
/* 文本类型 */
return SendMessage(pal, chipData.data);
return SendMessage(pal, chipData->data);
case MESSAGE_CONTENT_TYPE_PICTURE:
/* 图片类型 */
int sock;
Expand All @@ -491,22 +490,25 @@ bool CoreThread::SendMessage(CPPalInfo pal, const ChipData& chipData) {
strerror(errno));
return false;
}
Command(*this).SendSublayer(sock, pal, IPTUX_MSGPICOPT, ptr);
Command(*this).SendSublayer(sock, pal, IPTUX_MSGPICOPT,
chipData->data.c_str());
Comment on lines +493 to +494
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Potential resource leak

Ensure that the socket is closed in case of an exception to avoid potential resource leaks.

close(sock); // 关闭网络套接口
/*/* 删除此图片 */
if (chipData.GetDeleteFileAfterSent()) {
unlink(ptr); // 此文件已无用处
}
return true;
default:
g_assert_not_reached();
}
}

bool CoreThread::SendMsgPara(shared_ptr<MsgPara> para) {
return SendMsgPara(para->getPal(), IPTUX_REGULAROPT, para);
}

bool CoreThread::SendMsgPara(CPPalInfo pal,
enum GroupMsgOption option,
shared_ptr<MsgPara> para) {
for (int i = 0; i < int(para->dtlist.size()); ++i) {
if (!SendMessage(para->getPal(), para->dtlist[i])) {
LOG_ERROR("send message failed: %s", para->dtlist[i].ToString().c_str());
if (!SendMessage(pal, para->dtlist[i])) {
LOG_ERROR("send message failed: %s", para->dtlist[i]->ToString().c_str());
return false;
}
}
Expand Down Expand Up @@ -709,6 +711,13 @@ void CoreThread::SendUnitMessage(const PalKey& palKey,
Command(*this).SendUnitMsg(udpSock, GetPal(palKey), opttype, message.c_str());
}

void CoreThread::SendUnitMessage(const PalKey& palKey,
enum GroupMsgOption opttype,
std::shared_ptr<MsgPara> msgPara) {
auto pal = ((const CoreThread*)this)->GetPal(palKey);
SendMsgPara(pal, msgPara);
}

void CoreThread::SendGroupMessage(const PalKey& palKey,
const std::string& message) {
Command(*this).SendGroupMsg(udpSock, GetPal(palKey), message.c_str());
Expand Down
9 changes: 4 additions & 5 deletions src/iptux-core/CoreThreadTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ TEST(CoreThread, SendMessage_ChipData) {
CoreThread* thread = new CoreThread(core);
auto pal = make_shared<PalInfo>("127.0.0.1", 2425);
thread->AttachPalToList(pal);
ChipData chipData("hello world");
auto chipData = ChipData::newTxtMsg("hello world");
EXPECT_TRUE(thread->SendMessage(pal, chipData));
delete thread;
}
Expand All @@ -95,7 +95,7 @@ TEST(CoreThread, SendMsgPara) {
CoreThread* thread = new CoreThread(core);
PPalInfo pal = make_shared<PalInfo>("127.0.0.1", 2425);
thread->AttachPalToList(pal);
ChipData chipData("hello world");
auto chipData = ChipData::newTxtMsg("hello world");
auto para = make_shared<MsgPara>(pal);
para->dtlist.push_back(std::move(chipData));
EXPECT_TRUE(thread->SendMsgPara(para));
Expand Down Expand Up @@ -179,7 +179,7 @@ TEST(CoreThread, FullCase) {
}

auto event2 = dynamic_pointer_cast<const NewMessageEvent>(event);
ASSERT_EQ(event2->getMsgPara().dtlist[0].ToString(),
ASSERT_EQ(event2->getMsgPara().dtlist[0]->ToString(),
"ChipData(MessageContentType::STRING, hello world)");
{
lock_guard<std::mutex> l(thread2EventsMutex);
Expand All @@ -204,8 +204,7 @@ TEST(CoreThread, FullCase) {
thread1->SendAskShared(pal2InThread1);

// send picture
ChipData chipData(MessageContentType::PICTURE, testDataPath("iptux.png"));
chipData.SetDeleteFileAfterSent(false);
auto chipData = ChipData::newImgMsg(testDataPath("iptux.png"), false);
thread1->SendMessage(pal2InThread1, chipData);
// WARNING: does not work as expected, the message will be sent from
// 127.0.0.2(expect 127.0.0.1) while(thread2Events.size() != 2) {
Expand Down
110 changes: 69 additions & 41 deletions src/iptux-core/Models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ using namespace std;

namespace iptux {

// MARK: PalInfo

PalInfo::PalInfo(in_addr ipv4, uint16_t port)
: segdes(NULL), photo(NULL), sign(NULL), packetn(0), rpacketn(0) {
this->ipv4_ = ipv4;
Expand Down Expand Up @@ -120,6 +122,8 @@ string PalInfo::toString() const {
int(rpacketn), compatible, online, changed, in_blacklist);
}

// MARK: FileInfo

FileInfo::FileInfo()
: fileid(0),
packetn(0),
Expand Down Expand Up @@ -160,6 +164,17 @@ void FileInfo::ensureFilesizeFilled() {
filesize = afs.ftwsize(filepath);
}

bool FileInfo::operator==(const FileInfo& rhs) const {
const FileInfo& lhs = *this;
return lhs.fileid == rhs.fileid && lhs.packetn == rhs.packetn &&
lhs.fileattr == rhs.fileattr && lhs.filesize == rhs.filesize &&
lhs.finishedsize == rhs.finishedsize &&
lhs.filectime == rhs.filectime && lhs.filemtime == rhs.filemtime &&
lhs.filenum == rhs.filenum;
}

// MARK: MsgPara

MsgPara::MsgPara(CPPalInfo pal)
: stype(MessageSourceType::PAL),
btype(GROUP_BELONG_TYPE_REGULAR),
Expand All @@ -171,14 +186,65 @@ string MsgPara::getSummary() const {
if (this->dtlist.empty()) {
return _("Empty Message");
}
return this->dtlist[0].getSummary();
return this->dtlist[0]->getSummary();
}

// MARK: ChipData

shared_ptr<ChipData> ChipData::newTxtMsg(const std::string& text) {
return shared_ptr<ChipData>(new ChipData(text));
}

shared_ptr<ChipData> ChipData::newImgMsg(const std::string& text,
bool deleteFileAfterSent) {
auto res =
shared_ptr<ChipData>(new ChipData(MessageContentType::PICTURE, text));
res->deleteFileAfterSent = deleteFileAfterSent;
Comment on lines +200 to +202
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider using make_shared for shared_ptr creation

Using make_shared is generally more efficient and safer than using new with shared_ptr. It performs a single memory allocation for both the control block and the object.

Suggested change
auto res =
shared_ptr<ChipData>(new ChipData(MessageContentType::PICTURE, text));
res->deleteFileAfterSent = deleteFileAfterSent;
auto res = make_shared<ChipData>(MessageContentType::PICTURE, text);
res->deleteFileAfterSent = deleteFileAfterSent;

return res;
}

ChipData::ChipData(const string& data)
: type(MessageContentType::STRING), data(data) {}
ChipData::ChipData(MessageContentType type, const string& data)
: type(type), data(data) {}
ChipData::~ChipData() {}
ChipData::~ChipData() {
if (type == MessageContentType::PICTURE && deleteFileAfterSent) {
g_unlink(data.c_str());
}
}

string ChipData::ToString() const {
ostringstream oss;
oss << "ChipData(";
switch (type) {
case MessageContentType::STRING:
oss << "MessageContentType::STRING";
break;
case MessageContentType::PICTURE:
oss << "MessageContentType::PICTURE";
break;
default:
g_assert_not_reached();
}
oss << ", ";
oss << data;
oss << ")";
return oss.str();
}

string ChipData::getSummary() const {
switch (type) {
case MessageContentType::STRING:
return data;
case MessageContentType::PICTURE:
return _("Received an image");
default:
g_assert_not_reached();
}
return "";
}

// MARK: NetSegment

NetSegment::NetSegment() {}

Expand Down Expand Up @@ -223,36 +289,7 @@ NetSegment NetSegment::fromJsonValue(Json::Value& value) {
return res;
}

string ChipData::ToString() const {
ostringstream oss;
oss << "ChipData(";
switch (type) {
case MessageContentType::STRING:
oss << "MessageContentType::STRING";
break;
case MessageContentType::PICTURE:
oss << "MessageContentType::PICTURE";
break;
default:
g_assert_not_reached();
}
oss << ", ";
oss << data;
oss << ")";
return oss.str();
}

string ChipData::getSummary() const {
switch (type) {
case MessageContentType::STRING:
return data;
case MessageContentType::PICTURE:
return _("Received an image");
default:
g_assert_not_reached();
}
return "";
}
// MARK: PalKey

PalKey::PalKey(in_addr ipv4, int port) : ipv4(ipv4), port(port) {}

Expand All @@ -268,13 +305,4 @@ string PalKey::ToString() const {
return stringFormat("%s:%d", inAddrToString(ipv4).c_str(), port);
}

bool FileInfo::operator==(const FileInfo& rhs) const {
const FileInfo& lhs = *this;
return lhs.fileid == rhs.fileid && lhs.packetn == rhs.packetn &&
lhs.fileattr == rhs.fileattr && lhs.filesize == rhs.filesize &&
lhs.finishedsize == rhs.finishedsize &&
lhs.filectime == rhs.filectime && lhs.filemtime == rhs.filemtime &&
lhs.filenum == rhs.filenum;
}

} // namespace iptux
Loading
Loading