1

For a school project, I need to send and receive some data named as TLV through the network.

In fact, because a TLV can be small, the application send a meta-TLV that groups several TLV in a packet.

My problem is the following : what are the classes that I need to create to modelise properly the TLV ?

I don't know if I need to mention all the TLV possible but what I know is the following :

-Every TLV has a field type that identify the semantic of the TLV -Every TLV but one has a field length. However for five TLV, this sized is fixed -Two TLV has exactly the same field : type, length=0 -Three TLV has exactly the same field : type, length=8 and id. Just the type change (and their name)

The other are quite different.

My first idea was to use a mother class TLV that has a enum to store all the different TLV allowed like this :

//enum class to avoid conflicts

enum class TlvType {
        Pad1,
        PadN,
        Bad,
        No,
        PeersReq,
        Peers,
        Data,
        IHave,
        IDontHave,
        INeed,
//      Unknown,
    };
class Tlv {
private:
    virtual void to_stream(std::ostream& output) const = 0;
protected:
    uint8_t length_;
public:

    virtual TlvType type() const = 0;

    /*Solution find here : http://stackoverflow.com/questions/2059058/c-abstract-class-operator-overloading-and-interface-enforcement-question*/
    friend std::ostream &operator<<(std::ostream& output, const Tlv& tlv) {
        tlv.to_stream(output);
        return output;
    }

    //TO DO : do we really need that this method is virtual ?
    virtual uint8_t length() const;

    Tlv();

    virtual ~Tlv() {}

};

class PadN : public Tlv {
private:
    void to_stream(std::ostream& output) const;
    static constexpr TlvType code() {return TlvType::PadN;}
public:
    TlvType type() const;
    PadN();
    PadN(uint8_t zero_bytes);
    void set_length(uint8_t length);
};

The problem is that this codes somehow an algebraic type, that introduces a lot of redundant code. For example, I need to define for each tlv the method TlvType type() const . Since some Tlv has a fixed size, I only want a setter for the ones that can change their size.

Moreover each Tlv will be then formated in a format ready to send to the network. This, looks like a lot to serialization. However, I think that serialization is overkill for this project. Besides, since it's a network project, each student use his own language. And the only thing that we know is the format of a tlv that needs to be sent through the network.

Because my code is quite redundant I think that my modelisation is wrong for the TLV. And I'm doubting about using a class for each TLV. Indeed, probably the user won't change his TLV once he created it. He just wants to send it. And there is the same problem for the other way: I need to receive TLV. So I'm not sure how should I do.

Claudio
  • 10,614
  • 4
  • 31
  • 71
Saroupille
  • 609
  • 8
  • 14

0 Answers0