Skip to content

Commit 840de99

Browse files
committed
Field creation functionality for <bitfield> in commsdsl2wireshark.
1 parent 71488bb commit 840de99

7 files changed

Lines changed: 227 additions & 8 deletions

File tree

app/commsdsl2wireshark/src/WiresharkBitfieldField.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,23 @@
1515

1616
#include "WiresharkBitfieldField.h"
1717

18+
#include "Wireshark.h"
1819
#include "WiresharkGenerator.h"
20+
#include "WiresharkIntField.h"
21+
22+
#include "commsdsl/gen/util.h"
23+
#include "commsdsl/gen/strings.h"
24+
#include "commsdsl/parse/ParseIntField.h"
25+
26+
#include <cassert>
27+
#include <iomanip>
28+
#include <sstream>
29+
#include <type_traits>
30+
31+
namespace strings = commsdsl::gen::strings;
32+
namespace util = commsdsl::gen::util;
33+
34+
using ParseIntField = commsdsl::parse::ParseIntField;
1935

2036
namespace commsdsl2wireshark
2137
{
@@ -26,4 +42,120 @@ WiresharkBitfieldField::WiresharkBitfieldField(WiresharkGenerator& generator, Pa
2642
{
2743
}
2844

45+
std::string WiresharkBitfieldField::wiresharkForcedBitfieldMask(const WiresharkField& member) const
46+
{
47+
std::size_t bitOffset = 0U;
48+
for (auto& mPtr : genMembers()) {
49+
auto parseObj = mPtr->genParseObj();
50+
auto bitLen = parseObj.parseBitLength();
51+
assert(bitLen != 0U);
52+
if (mPtr.get() == &member.wiresharkGenField()) {
53+
auto mask = ((1ULL << bitLen) - 1U) << bitOffset;
54+
std::stringstream stream;
55+
stream << "0x" << std::hex << std::setfill('0') << std::setw(static_cast<int>(genParseObj().parseMaxLength() * 2)) << mask;
56+
return stream.str();
57+
}
58+
59+
bitOffset += bitLen;
60+
}
61+
62+
[[maybe_unused]] static constexpr bool Should_not_happen = false;
63+
assert(Should_not_happen);
64+
return strings::genNilStr();
65+
}
66+
67+
std::string WiresharkBitfieldField::wiresharkIntegralType() const
68+
{
69+
using ParseType = ParseIntField::ParseType;
70+
static const ParseType TypeMap[] = {
71+
ParseType::Uint8,
72+
ParseType::Uint16,
73+
ParseType::Uint32,
74+
ParseType::Uint32,
75+
ParseType::Uint64,
76+
ParseType::Uint64,
77+
ParseType::Uint64,
78+
ParseType::Uint64,
79+
};
80+
static const std::size_t TypeMapSize = std::extent_v<decltype(TypeMap)>;
81+
82+
auto parseObj = genParseObj();
83+
auto len = parseObj.parseMaxLength();
84+
if (TypeMapSize < len) {
85+
[[maybe_unused]] static constexpr bool Should_not_happen = false;
86+
assert(Should_not_happen);
87+
return strings::genEmptyString();
88+
}
89+
auto idx = len - 1U;
90+
return WiresharkIntField::wiresharkIntegralType(TypeMap[idx], len);
91+
}
92+
93+
unsigned WiresharkBitfieldField::wiresharkMaskShiftFor(const WiresharkField& member) const
94+
{
95+
unsigned bitOffset = 0U;
96+
for (auto& mPtr : genMembers()) {
97+
auto parseObj = mPtr->genParseObj();
98+
auto bitLen = parseObj.parseBitLength();
99+
assert(bitLen != 0U);
100+
if (mPtr.get() == &member.wiresharkGenField()) {
101+
return bitOffset;
102+
}
103+
104+
bitOffset += static_cast<decltype(bitOffset)>(bitLen);
105+
}
106+
107+
[[maybe_unused]] static constexpr bool Should_not_happen = false;
108+
assert(Should_not_happen);
109+
return 0U;
110+
}
111+
112+
bool WiresharkBitfieldField::genPrepareImpl()
113+
{
114+
if (!GenBase::genPrepareImpl()) {
115+
return false;
116+
}
117+
118+
m_wiresharkFields = wiresharkTransformFieldsList(genMembers());
119+
// TODO: force mask
120+
return true;
121+
}
122+
123+
std::string WiresharkBitfieldField::wiresharkFieldRegistrationImpl() const
124+
{
125+
static const std::string Templ =
126+
"local #^#OBJ_NAME#$# = #^#CREATE_FUNC#$#(ProtoField.#^#TYPE#$#(\"#^#REF_NAME#$#\", \"#^#DISP_NAME#$#\", base.HEX, #^#NIL#$#, #^#MASK#$#, #^#DESC#$#))\n"
127+
;
128+
129+
auto mask = wiresharkForcedIntegralFieldMask();
130+
auto obj = genParseObj();
131+
util::GenReplacementMap repl = {
132+
{"OBJ_NAME", wiresharkFieldObjName()},
133+
{"CREATE_FUNC", Wireshark::wiresharkCreateFieldFuncName(WiresharkGenerator::wiresharkCast(genGenerator()))},
134+
{"TYPE", wiresharkIntegralType()},
135+
{"REF_NAME", wiresharkFieldRefName()},
136+
{"DISP_NAME", util::genDisplayName(obj.parseDisplayName(), obj.parseName())},
137+
{"NIL", strings::genNilStr()},
138+
{"MASK", wiresharkForcedIntegralFieldMask()},
139+
{"DESC", wiresharkFieldDescriptionStr()},
140+
};
141+
142+
assert(!repl["TYPE"].empty());
143+
return util::genProcessTemplate(Templ, repl);
144+
}
145+
146+
std::string WiresharkBitfieldField::wiresharkMembersDissectCodeImpl() const
147+
{
148+
util::GenStringsList elems;
149+
for (auto* f : m_wiresharkFields) {
150+
auto str = f->wiresharkDissectCode();
151+
if (str.empty()) {
152+
continue;
153+
}
154+
155+
elems.push_back(std::move(str));
156+
}
157+
158+
return util::genStrListToString(elems, "\n", "\n");
159+
}
160+
29161
} // namespace commsdsl2wireshark

app/commsdsl2wireshark/src/WiresharkBitfieldField.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ class WiresharkBitfieldField final : public commsdsl::gen::GenBitfieldField, pub
3333
using GenElem = commsdsl::gen::GenElem;
3434

3535
WiresharkBitfieldField(WiresharkGenerator& generator, ParseField parseObj, GenElem* parent);
36+
37+
std::string wiresharkForcedBitfieldMask(const WiresharkField& member) const;
38+
std::string wiresharkIntegralType() const;
39+
unsigned wiresharkMaskShiftFor(const WiresharkField& member) const;
40+
41+
protected:
42+
virtual bool genPrepareImpl() override;
43+
virtual std::string wiresharkFieldRegistrationImpl() const override;
44+
virtual std::string wiresharkMembersDissectCodeImpl() const override;
45+
46+
private:
47+
WiresharkFieldsList m_wiresharkFields;
3648
};
3749

3850
} // namespace commsdsl2wireshark

app/commsdsl2wireshark/src/WiresharkEnumField.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ std::string WiresharkEnumField::wiresharkFieldRegistrationImpl() const
4848
{"VALS", wiresharkValsInternal()},
4949
{"OBJ_NAME", wiresharkFieldObjName()},
5050
{"CREATE_FUNC", Wireshark::wiresharkCreateFieldFuncName(WiresharkGenerator::wiresharkCast(genGenerator()))},
51-
{"TYPE", WiresharkIntField::wiresharkIntegralType(obj.parseType(), obj.parseMaxLength())},
51+
{"TYPE", wiresharkForcedIntegralFieldType()},
5252
{"REF_NAME", wiresharkFieldRefName()},
5353
{"DISP_NAME", util::genDisplayName(obj.parseDisplayName(), obj.parseName())},
5454
{"VALS_NAME", wiresharkFieldObjName() + strings::genValsSuffixStr()},
@@ -61,6 +61,13 @@ std::string WiresharkEnumField::wiresharkFieldRegistrationImpl() const
6161
repl["BASE"] = "base.HEX_DEC";
6262
}
6363

64+
if (repl["TYPE"].empty()) {
65+
repl["TYPE"] = WiresharkIntField::wiresharkIntegralType(obj.parseType(), obj.parseMaxLength());
66+
}
67+
else if (!genIsUnsignedType() && (repl["TYPE"].front() == 'u')) {
68+
repl["TYPE"] = repl["TYPE"].substr(1U);
69+
}
70+
6471
assert(!repl["TYPE"].empty());
6572
return util::genProcessTemplate(Templ, repl);
6673
}

app/commsdsl2wireshark/src/WiresharkField.cpp

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616
#include "WiresharkField.h"
1717

1818
#include "Wireshark.h"
19+
#include "WiresharkBitfieldField.h"
1920
#include "WiresharkGenerator.h"
2021

2122
#include "commsdsl/gen/comms.h"
2223
#include "commsdsl/gen/strings.h"
2324
#include "commsdsl/gen/util.h"
25+
#include "commsdsl/parse/ParseField.h"
2426

2527
#include <cassert>
28+
#include <utility>
2629

2730
namespace comms = commsdsl::gen::comms;
2831
namespace strings = commsdsl::gen::strings;
@@ -31,6 +34,27 @@ namespace util = commsdsl::gen::util;
3134
namespace commsdsl2wireshark
3235
{
3336

37+
namespace
38+
{
39+
40+
const WiresharkBitfieldField* wiresharkParentBitfieldInternal(const WiresharkField& field)
41+
{
42+
auto* parent = field.wiresharkGenField().genGetParent();
43+
assert(parent != nullptr);
44+
if (parent->genElemType() != commsdsl::gen::GenElem::GenType_Field) {
45+
return nullptr;
46+
}
47+
48+
auto* asField = static_cast<const commsdsl::gen::GenField*>(parent);
49+
if (asField->genParseObj().parseKind() != commsdsl::parse::ParseField::ParseKind::Bitfield) {
50+
return nullptr;
51+
}
52+
53+
return static_cast<const WiresharkBitfieldField*>(asField);
54+
}
55+
56+
} // namespace
57+
3458
WiresharkField::WiresharkField(GenField& field) :
3559
m_genField(field)
3660
{
@@ -86,6 +110,7 @@ std::string WiresharkField::wiresharkDissectCode() const
86110
}
87111

88112
static const std::string Templ =
113+
"#^#MEMBERS#$#\n"
89114
"#^#REG#$#\n"
90115
"#^#PREPEND#$#\n"
91116
"local function #^#NAME#$##^#SUFFIX#$#(tvb, tree, offset, offsetLimit)\n"
@@ -104,6 +129,7 @@ std::string WiresharkField::wiresharkDissectCode() const
104129
bool replaced = false;
105130
bool extended = false;
106131
util::GenReplacementMap repl = {
132+
{"MEMBERS", wiresharkMembersDissectCodeImpl()},
107133
{"REG", wiresharkFieldRegistrationImpl()},
108134
{"NAME", wiresharkDissectName()},
109135
{"REPLACE", wiresharkGenerator.genReadCodeInjectCode(replaceFileName, "Replace this function body", &replaced)},
@@ -134,6 +160,11 @@ std::string WiresharkField::wiresharkFieldRegistrationImpl() const
134160
return std::string();
135161
}
136162

163+
std::string WiresharkField::wiresharkMembersDissectCodeImpl() const
164+
{
165+
return std::string();
166+
}
167+
137168
std::string WiresharkField::wiresharkFieldRefName() const
138169
{
139170
auto& wiresharkGenerator = WiresharkGenerator::wiresharkCast(m_genField.genGenerator());
@@ -143,8 +174,32 @@ std::string WiresharkField::wiresharkFieldRefName() const
143174

144175
std::string WiresharkField::wiresharkForcedIntegralFieldMask() const
145176
{
146-
// TODO: for <bitfield> members
147-
return strings::genNilStr();
177+
auto* parentBitfield = wiresharkParentBitfieldInternal(*this);
178+
if (parentBitfield == nullptr) {
179+
return strings::genNilStr();
180+
}
181+
182+
return parentBitfield->wiresharkForcedBitfieldMask(*this);
183+
}
184+
185+
std::string WiresharkField::wiresharkForcedIntegralFieldType() const
186+
{
187+
auto* parentBitfield = wiresharkParentBitfieldInternal(*this);
188+
if (parentBitfield == nullptr) {
189+
return strings::genEmptyString();
190+
}
191+
192+
return parentBitfield->wiresharkIntegralType();
193+
}
194+
195+
unsigned WiresharkField::wiresharkForcedMaskShift() const
196+
{
197+
auto* parentBitfield = wiresharkParentBitfieldInternal(*this);
198+
if (parentBitfield == nullptr) {
199+
return 0U;
200+
}
201+
202+
return parentBitfield->wiresharkMaskShiftFor(*this);
148203
}
149204

150205
std::string WiresharkField::wiresharkDissectBodyInternal() const

app/commsdsl2wireshark/src/WiresharkField.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@ class WiresharkField
5555

5656
protected:
5757
virtual std::string wiresharkFieldRegistrationImpl() const;
58+
virtual std::string wiresharkMembersDissectCodeImpl() const;
5859

5960
std::string wiresharkFieldRefName() const;
6061
std::string wiresharkForcedIntegralFieldMask() const;
62+
std::string wiresharkForcedIntegralFieldType() const;
63+
unsigned wiresharkForcedMaskShift() const;
6164
std::string wiresharkFieldDescriptionStr() const;
6265

6366
private:

app/commsdsl2wireshark/src/WiresharkIntField.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ std::string WiresharkIntField::wiresharkFieldRegistrationImpl() const
111111
{"SPECIALS", wiresharkSpecialsInternal()},
112112
{"OBJ_NAME", wiresharkFieldObjName()},
113113
{"CREATE_FUNC", Wireshark::wiresharkCreateFieldFuncName(WiresharkGenerator::wiresharkCast(genGenerator()))},
114-
{"TYPE", wiresharkIntegralType(obj.parseType(), obj.parseMaxLength())},
114+
{"TYPE", wiresharkForcedIntegralFieldType()},
115115
{"REF_NAME", wiresharkFieldRefName()},
116116
{"DISP_NAME", util::genDisplayName(obj.parseDisplayName(), obj.parseName())},
117117
{"SPECIALS_NAME", strings::genNilStr()},
@@ -123,6 +123,13 @@ std::string WiresharkIntField::wiresharkFieldRegistrationImpl() const
123123
repl["SPECIALS_NAME"] = wiresharkFieldObjName() + strings::genValsSuffixStr();
124124
}
125125

126+
if (repl["TYPE"].empty()) {
127+
repl["TYPE"] = wiresharkIntegralType(obj.parseType(), obj.parseMaxLength());
128+
}
129+
else if (!genIsUnsignedType() && (repl["TYPE"].front() == 'u')) {
130+
repl["TYPE"] = repl["TYPE"].substr(1U);
131+
}
132+
126133
assert(!repl["TYPE"].empty());
127134
return util::genProcessTemplate(Templ, repl);
128135
}

app/commsdsl2wireshark/src/WiresharkSetField.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,18 @@ std::string WiresharkSetField::wiresharkFieldRegistrationImpl() const
5050
{"BITS", wiresharkBitsInternal()},
5151
{"OBJ_NAME", wiresharkFieldObjName()},
5252
{"CREATE_FUNC", Wireshark::wiresharkCreateFieldFuncName(WiresharkGenerator::wiresharkCast(genGenerator()))},
53-
{"TYPE", WiresharkIntField::wiresharkIntegralType(parseObj.parseType(), parseObj.parseMaxLength())},
53+
{"TYPE", wiresharkForcedIntegralFieldType()},
5454
{"REF_NAME", wiresharkFieldRefName()},
5555
{"DISP_NAME", util::genDisplayName(parseObj.parseDisplayName(), parseObj.parseName())},
5656
{"MASK", wiresharkForcedIntegralFieldMask()},
5757
{"DESC", wiresharkFieldDescriptionStr()},
5858
{"NIL", strings::genNilStr()},
5959
};
6060

61+
if (repl["TYPE"].empty()) {
62+
repl["TYPE"] = WiresharkIntField::wiresharkIntegralType(parseObj.parseType(), parseObj.parseMaxLength());
63+
}
64+
6165
assert(!repl["TYPE"].empty());
6266
return util::genProcessTemplate(Templ, repl);
6367
}
@@ -86,12 +90,13 @@ std::string WiresharkSetField::wiresharkBitsInternal() const
8690
"local #^#BIT_OBJ_NAME#$# = #^#CREATE_FUNC#$#(ProtoField.bool(\"#^#REF_NAME#$#\", \"#^#DISP_NAME#$#\", #^#PARENT_WIDTH#$#, #^#NIL#$#, #^#MASK#$#, #^#DESC#$#))\n"
8791
;
8892

93+
auto forcedShift = wiresharkForcedMaskShift();
8994
util::GenReplacementMap repl = {
9095
{"BIT_OBJ_NAME", wiresharkBitObjName(bitInfo.first)},
9196
{"CREATE_FUNC", Wireshark::wiresharkCreateFieldFuncName(WiresharkGenerator::wiresharkCast(genGenerator()))},
9297
{"REF_NAME", refName + '.' + bitInfo.first},
9398
{"DISP_NAME", util::genDisplayName(bitInfo.second.m_displayName, bitInfo.first)},
94-
{"MASK", wiresharkBitMaskInternal(bitInfo.second.m_idx)},
99+
{"MASK", wiresharkBitMaskInternal(bitInfo.second.m_idx + forcedShift)},
95100
{"DESC", strings::genNilStr()},
96101
{"NIL", strings::genNilStr()},
97102
{"PARENT_WIDTH", parentWidth},
@@ -109,8 +114,6 @@ std::string WiresharkSetField::wiresharkBitsInternal() const
109114

110115
std::string WiresharkSetField::wiresharkBitMaskInternal(unsigned idx) const
111116
{
112-
// TODO: parent mask
113-
114117
auto mask = 1U << idx;
115118
auto parseObj = genSetFieldParseObj();
116119
std::stringstream stream;

0 commit comments

Comments
 (0)