Skip to content

Commit db30d34

Browse files
committed
more more more
1 parent 704ab4b commit db30d34

File tree

15 files changed

+1106
-1000
lines changed

15 files changed

+1106
-1000
lines changed

TODO_SCTP.md

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,19 @@ else if (auto* barItem = std::get_if<std::unique_ptr<BarItem>>(&item))
4848
// However we can check item->GetType() instead and do a switch().
4949
```
5050
51-
## Parsing of subclasses FooItem
52-
53-
- Must initialize Value Length field in the constructor.
54-
- Must provide with a `virtual bool FooItem::Verify() const = 0` method in which subclasses verify if header, flags, value length and value is ok.
55-
- Must probably remove `GetValue()` and `SetValue()` in parent `FooItem` class or make then protected.
56-
57-
NO! Instead:
58-
59-
- Must remove static `Parse()` and `Factory()` in FooItem and implement
60-
- them into each subclass.
61-
6251
## Optimize creation of packets with items
6352
6453
- Add some `GetNextItemPtr(size_t& remainingBufferLength)` in a packert class that returns a pointer to the position in which a new item would take place and modifies the given `remainingBufferLength` with the remaining length of the buffer after that position.
6554
- Then create a `Item` via `Item::Factory()` by passing `ptr` as `buffer` and `remainingBufferLength` as `bufferLength`.
6655
- Then also add `packet->AddInPlaceItem(item, ptr)` (or whatever) so the packet doesn't serialize (doesn't memcpy) the bytes of the `Item` into its buffer.
6756
- Another related option is to add specialized `AddXxxxItem()` methods in the packet class.
6857
69-
## FooItem subclasses
58+
## FooPacket and FooItem TODO
7059
71-
- If we have a FooDataItem, the app should not be able to change its id via `SetId()`, AKA make `SetId()` protected since app should use `FooXxxxItem::Factory()` static methods.
72-
- `FooItem` constructor: It doesn't make sense that it fills things since we want to rely on subclasses' `Parse()`, `Factory()` and constructors (that will override these calls anyway).
7360
- If `FooItem` has valid but unknown id, that's correct, but let's remove the `SetValue()` method so those unknown items can only be parsed but not created.
61+
- Remove `FooItem::GetValue()` and `GetValueLength()`.
62+
- Document that having `auto item = FooPacket::GetIem(idx)`, the caller needs to cast to specific `FooItem` subclass by checking `item->GetId()` and then doing this, HOEWEVER this will **invalidate** the `FooItem` in the `FooPacket`!!!:
63+
```c++
64+
auto numericItem = std::unique_ptr<FooNumericItem>(static_cast<FooNumericItem*>(item.release()));
65+
```
66+
- Wait!

worker/include/common.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <cstddef> // size_t
77
#include <cstdint> // uint8_t, etc
88
#include <functional> // std::function
9-
#include <memory> // std::addressof()
9+
#include <memory> // std::addressof(), std::unique_ptr(), etc
1010
#include <optional>
1111
#ifdef _WIN32
1212
#include <winsock2.h>

worker/meson.build

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,9 @@ if get_option('ms_sctp_stack')
390390
'test/src/RTC/TestSerializable.cpp',
391391
'test/src/RTC/TestSerializable/FooPacket.cpp',
392392
'test/src/RTC/TestSerializable/FooItem.cpp',
393-
'test/src/RTC/TestSerializable/FooDataItem.cpp',
393+
'test/src/RTC/TestSerializable/FooNumericItem.cpp',
394+
'test/src/RTC/TestSerializable/FooTextItem.cpp',
395+
'test/src/RTC/TestSerializable/FooUnknownItem.cpp',
394396
]
395397
endif
396398

worker/test/include/RTC/TestSerializable/FooItem.hpp

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,12 @@ class FooItem : public Serializable
3838
* Item Id.
3939
*
4040
* @remarks
41-
* - NONE is not a valid value, so a FooItem with id NONE should be
42-
* considered invalid and parsing should fail.
43-
* - Values other than the defined must be accepted as FooUnknownItem.
41+
* Values other than the defined must be accepted as FooUnknownItem.
4442
*/
4543
enum class ItemId : uint8_t
4644
{
47-
NONE = 0x0,
48-
DATA = 0x1,
49-
EVENT = 0x2,
50-
CONTROL = 0x3,
45+
NUMERIC = 0x1,
46+
TEXT = 0x2
5147
};
5248

5349
/**
@@ -75,30 +71,12 @@ class FooItem : public Serializable
7571
* @param buffer
7672
* @param bufferLength
7773
* @param itemId - If given buffer is a valid FooItem then `itemId` is
78-
* rewritten to parsed ItemId. Otherwuise it's rewritten to ItemId::NONE
79-
* (0).
74+
* rewritten to parsed ItemId.
8075
* @param valueLength - If given buffer is a valid FooItem then `valueLength`
81-
* is rewritten to the value of the Value Length field. Otherwise it's
82-
* rewritten to 0.
76+
* is rewritten to the value of the Value Length field.
8377
*/
8478
static bool IsFooItem(const uint8_t* buffer, size_t bufferLength, ItemId& itemId, uint8_t& valueLength);
8579

86-
/**
87-
* Parse a FooItem.
88-
*
89-
* @remarks
90-
* - `bufferLength` may exceed the exact length of the item.
91-
*/
92-
static std::unique_ptr<FooItem> Parse(const uint8_t* buffer, size_t bufferLength);
93-
94-
static std::unique_ptr<FooItem> Factory(
95-
uint8_t* buffer,
96-
size_t bufferLength,
97-
ItemId id,
98-
uint8_t flags,
99-
const uint8_t* value,
100-
uint8_t valueLength);
101-
10280
static const std::string& ItemId2String(ItemId id);
10381

10482
private:
@@ -109,7 +87,7 @@ class FooItem : public Serializable
10987
* Constructor is protected because we only want to create FooItem instances
11088
* via Parse() and Factory() in subclasses.
11189
*/
112-
FooItem(const uint8_t* buffer, size_t bufferLength, bool initializeHeader);
90+
FooItem(const uint8_t* buffer, size_t bufferLength);
11391

11492
public:
11593
virtual ~FooItem() override;
@@ -129,52 +107,17 @@ class FooItem : public Serializable
129107
return GetHeaderPointer()->id;
130108
}
131109

132-
virtual void SetId(ItemId id) final
133-
{
134-
GetHeaderPointer()->id = id;
135-
}
136-
137110
virtual uint8_t GetFlags() const final
138111
{
139112
return GetHeaderPointer()->flags;
140113
}
141114

142-
virtual void SetFlags(uint8_t flags) final
143-
{
144-
GetHeaderPointer()->flags = flags;
145-
}
146-
147115
virtual bool HasValue() const final
148116
{
149117
return GetValueLengthField() > 0u;
150118
;
151119
}
152120

153-
// TODO: Make it protected since the app should use subclasses instead.
154-
virtual const uint8_t* GetValue() const final
155-
{
156-
if (!HasValue())
157-
{
158-
return nullptr;
159-
}
160-
161-
return GetValuePointer();
162-
}
163-
164-
// TODO: Make it protected since the app should use subclasses instead.
165-
virtual uint8_t GetValueLength() const final
166-
{
167-
if (!HasValue())
168-
{
169-
return 0u;
170-
}
171-
172-
return GetValueLengthField();
173-
}
174-
175-
// TODO: Make it protected since the app should use subclasses instead.
176-
virtual void SetValue(const uint8_t* value, uint8_t valueLength) final;
177-
178121
protected:
179122
/**
180123
* NOTE: Return ItemHeader* instead of const ItemHeader* since we may
@@ -185,6 +128,13 @@ class FooItem : public Serializable
185128
return reinterpret_cast<ItemHeader*>(const_cast<uint8_t*>(GetBuffer()));
186129
}
187130

131+
void InitializeHeader(ItemId id, uint8_t flags, uint8_t valueLength)
132+
{
133+
GetHeaderPointer()->id = id;
134+
GetHeaderPointer()->flags = flags;
135+
SetValueLengthField(valueLength);
136+
}
137+
188138
/**
189139
* Private private because it returns the value of the Value Length field,
190140
* which is not useful for the application.
@@ -208,6 +158,16 @@ class FooItem : public Serializable
208158
return const_cast<uint8_t*>(GetBuffer()) + ItemHeaderLength;
209159
}
210160

161+
virtual uint8_t GetValueLength() const final
162+
{
163+
if (!HasValue())
164+
{
165+
return 0u;
166+
}
167+
168+
return GetValueLengthField();
169+
}
170+
211171
const uint8_t* GetEndPointer() const
212172
{
213173
return GetBuffer() + ItemHeaderLength + GetValueLength();

worker/test/include/RTC/TestSerializable/FooDataItem.hpp renamed to worker/test/include/RTC/TestSerializable/FooNumericItem.hpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,56 @@
1-
#ifndef MS_RTC_SERIALIZABLE_FOO_DATA_ITEM_HPP
2-
#define MS_RTC_SERIALIZABLE_FOO_DATA_ITEM_HPP
1+
#ifndef MS_RTC_SERIALIZABLE_FOO_NUMERIC_ITEM_HPP
2+
#define MS_RTC_SERIALIZABLE_FOO_NUMERIC_ITEM_HPP
33

44
#include "common.hpp"
55
#include "RTC/TestSerializable/FooItem.hpp"
66

77
using namespace RTC;
88

99
/**
10-
* FooDataItem.
10+
* FooNumericItem.
1111
*
1212
* 0 1 2 3
1313
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1414
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1515
* | Id | Flags | Value Length | Number |
1616
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1717
*
18-
* - Id (4 bits): Unsigned integer.
18+
* - Id (4 bits): Unsigned integer. Must be 1 (NUMERIC).
1919
* - Flags (4 bits).
2020
* - Value Length (8 bits): Length of the Value field. Must be 2.
2121
* - Number (16 bits): Unsigned integer.
2222
*
23-
* Length of a FooDataItem must be 4 bytes.
23+
* Length of a FooNumericItem must be 4 bytes.
2424
*/
2525

26-
class FooDataItem : public FooItem
26+
class FooNumericItem : public FooItem
2727
{
2828
public:
2929
/**
30-
* FooDataItem has fixed length.
30+
* FooNumericItem has fixed length.
3131
*/
32-
static const size_t Length{ 4u };
3332
static const size_t NumberLength{ 2u };
3433

3534
public:
3635
/**
37-
* Parse a FooDataItem.
36+
* Parse a FooNumericItem.
3837
*
3938
* @remarks
4039
* - `bufferLength` may exceed the exact length of the item.
4140
*/
42-
static std::unique_ptr<FooDataItem> Parse(const uint8_t* buffer, size_t bufferLength);
41+
static std::unique_ptr<FooNumericItem> Parse(const uint8_t* buffer, size_t bufferLength);
4342

44-
static std::unique_ptr<FooDataItem> Factory(
43+
static std::unique_ptr<FooNumericItem> Factory(
4544
uint8_t* buffer, size_t bufferLength, uint8_t flags, uint16_t number);
4645

4746
private:
4847
/**
49-
* Constructor is private because we only want to create FooDataItem instances
50-
* via Parse() and Factory().
48+
* Private constructor used by Parse() and Factory() static methods.
5149
*/
52-
FooDataItem(const uint8_t* buffer, size_t bufferLength, bool initializeHeader);
50+
FooNumericItem(const uint8_t* buffer, size_t bufferLength);
5351

5452
public:
55-
virtual ~FooDataItem() override;
53+
virtual ~FooNumericItem() override;
5654

5755
virtual void Dump() const override final;
5856

worker/test/include/RTC/TestSerializable/FooPacket.hpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ class FooPacket : public Serializable
119119
{
120120
if (HasAppendix())
121121
{
122-
return GetLengthField() > HeaderLength + AppendixLength;
122+
return GetLengthField() > FooPacket::HeaderLength + FooPacket::AppendixLength;
123123
}
124124
else
125125
{
126-
return GetLengthField() > HeaderLength;
126+
return GetLengthField() > FooPacket::HeaderLength;
127127
}
128128
}
129129

@@ -132,13 +132,19 @@ class FooPacket : public Serializable
132132
return this->items.size();
133133
}
134134

135+
/**
136+
* Get the FooItem with index `idx` (starts at 0).
137+
*/
135138
const std::unique_ptr<FooItem>& GetItem(size_t idx) const;
136139

140+
template<typename T>
141+
const T* GetItem(size_t idx) const;
142+
137143
/**
138-
* Serializes given Item into Packet's buffer.
144+
* Serializes given FooItem into Packet's buffer.
139145
*
140146
* @remarks
141-
* Once this method is called, the Item is owned by FooPacket instance.
147+
* Once this method is called, the FooItem is owned by FooPacket instance.
142148
*/
143149
void AddItem(std::unique_ptr<FooItem> item);
144150

@@ -182,16 +188,16 @@ class FooPacket : public Serializable
182188
*/
183189
uint8_t* GetAppendixPointer() const
184190
{
185-
return const_cast<uint8_t*>(GetBuffer()) + HeaderLength;
191+
return const_cast<uint8_t*>(GetBuffer()) + FooPacket::HeaderLength;
186192
}
187193

188194
const uint8_t* GetItemsPointer() const
189195
{
190-
auto* ptr = GetBuffer() + HeaderLength;
196+
auto* ptr = GetBuffer() + FooPacket::HeaderLength;
191197

192198
if (HasAppendix())
193199
{
194-
ptr += AppendixLength;
200+
ptr += FooPacket::AppendixLength;
195201
}
196202

197203
return ptr;
@@ -204,7 +210,7 @@ class FooPacket : public Serializable
204210

205211
/**
206212
* Must be used within Parse() static method (instead than AddItem()).
207-
* This method doesn't serializa the given Item into Packet's buffer since
213+
* This method doesn't serializa the given FooItem into Packet's buffer since
208214
* it's already serialized (obviously since we are parsing a buffer).
209215
*/
210216
void AddParsedItem(std::unique_ptr<FooItem> item)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#ifndef MS_RTC_SERIALIZABLE_FOO_TEXT_ITEM_HPP
2+
#define MS_RTC_SERIALIZABLE_FOO_TEXT_ITEM_HPP
3+
4+
#include "common.hpp"
5+
#include "RTC/TestSerializable/FooItem.hpp"
6+
#include <string>
7+
#include <string_view>
8+
9+
using namespace RTC;
10+
11+
/**
12+
* FooTextItem.
13+
*
14+
* 0 1 2 3
15+
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
16+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17+
* | Id | Flags | Value Length | Text |
18+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19+
* | ... |
20+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21+
*
22+
* - Id (4 bits): Unsigned integer. Must be 2 (TEXT).
23+
* - Flags (4 bits).
24+
* - Value Length (8 bits): Length of the Value field.
25+
* - Text (variable length bits): String not ended in \0.
26+
*
27+
* Length of a FooTextItem is therefore variable.
28+
*/
29+
30+
class FooTextItem : public FooItem
31+
{
32+
public:
33+
/**
34+
* Parse a FooTextItem.
35+
*
36+
* @remarks
37+
* - `bufferLength` may exceed the exact length of the item.
38+
*/
39+
static std::unique_ptr<FooTextItem> Parse(const uint8_t* buffer, size_t bufferLength);
40+
41+
static std::unique_ptr<FooTextItem> Factory(
42+
uint8_t* buffer, size_t bufferLength, uint8_t flags, const std::string& text);
43+
44+
private:
45+
/**
46+
* Private constructor used by Parse() and Factory() static methods.
47+
*/
48+
FooTextItem(const uint8_t* buffer, size_t bufferLength);
49+
50+
public:
51+
virtual ~FooTextItem() override;
52+
53+
virtual void Dump() const override final;
54+
55+
virtual const std::string_view GetText() const final;
56+
57+
virtual void SetText(const std::string& text) final;
58+
};
59+
60+
#endif

0 commit comments

Comments
 (0)