Field Header

A

Andrea Crotti

I have a Stream class, which handles in short the manipulation of vector
of chars, and what I need also is something that creates a header.

Now I only have (now) two possibilities
- type + payload
- type + size + payload

And that's what I'm using:

class FieldHeader : public Stream
{
public:
stream_t type;
stream_t size;
static const size_t TYPE = sizeof(stream_t);
static const size_t SIZE = sizeof(stream_t);
static const size_t TYPE_SIZE = TYPE + SIZE;

FieldHeader(stream_t);
FieldHeader(stream_t, stream_t);
FieldHeader(const Stream&, bool full=true);

static Stream createField(const Serializable&, stream_t, bool full=true);
};


it works and with "createField" I create the whole stream containing
payload and header, BUT

- the TYPE, SIZE, TYPE_SIZE are quite ugly
I would like to use "sizeof(type)" for example if possible, but a
static variable can't use a non-static variable (of course).
- if I want to add other fields is quite painful

Any suggestions to make this better?
 
V

Victor Bazarov

I have a Stream class, which handles in short the manipulation of vector
of chars, and what I need also is something that creates a header.

Now I only have (now) two possibilities
- type + payload
- type + size + payload

And that's what I'm using:

class FieldHeader : public Stream
{
public:
stream_t type;
stream_t size;
static const size_t TYPE = sizeof(stream_t);
static const size_t SIZE = sizeof(stream_t);
static const size_t TYPE_SIZE = TYPE + SIZE;

FieldHeader(stream_t);
FieldHeader(stream_t, stream_t);
FieldHeader(const Stream&, bool full=true);

static Stream createField(const Serializable&, stream_t, bool full=true);
};


it works and with "createField" I create the whole stream containing
payload and header, BUT

- the TYPE, SIZE, TYPE_SIZE are quite ugly
I would like to use "sizeof(type)" for example if possible, but a
static variable can't use a non-static variable (of course).

Why "of course"? 'sizeof' is a compile-time expression. Both variables
(their sizes) are known at compile time...

And what's ugly about them? Capital letters? Use small ones.
- if I want to add other fields is quite painful

In what way?
Any suggestions to make this better?

Templatize the hell out of it (using Policies). Get a copy of "Modern
C++ Design" by Alexandrescu.

V
 
A

Andrea Crotti

Victor Bazarov said:
Why "of course"? 'sizeof' is a compile-time expression. Both
variables (their sizes) are known at compile time...

And what's ugly about them? Capital letters? Use small ones.

Well but if I do
sizeof(type) instead
I get

FieldHeader.hpp:16: error: invalid use of non-static data member 'FieldHeader::type'
include/FieldHeader.hpp:18: error: from this location

I think because a const static can't make use of a "normal" variable.
And by the I'm not 100% sure but I think that only the OSX g++ complains here.
In what way?

Well I should add another constructor, another size and so on, but ok no
other choices..
Templatize the hell out of it (using Policies). Get a copy of "Modern
C++ Design" by Alexandrescu.

V

The book looks great and it's not even too expensive so I'll get it.
In the meanwhile, what exactly could I templatize?

The type of the parameters size and type?

Or maybe the "type" of header, which can be made of both fields or only
one (but there could be other possibilities maybe).
 
J

Jorgen Grahn

I have a Stream class, which handles in short the manipulation of vector
of chars, and what I need also is something that creates a header.

Now I only have (now) two possibilities
- type + payload
- type + size + payload

And that's what I'm using:

class FieldHeader : public Stream
{
public:
stream_t type;
stream_t size;
static const size_t TYPE = sizeof(stream_t);
static const size_t SIZE = sizeof(stream_t);
static const size_t TYPE_SIZE = TYPE + SIZE;

FieldHeader(stream_t);
FieldHeader(stream_t, stream_t);
FieldHeader(const Stream&, bool full=true);

static Stream createField(const Serializable&, stream_t, bool full=true);
};


it works and with "createField" I create the whole stream containing
payload and header, BUT

- the TYPE, SIZE, TYPE_SIZE are quite ugly
I would like to use "sizeof(type)" for example if possible, but a
static variable can't use a non-static variable (of course).
- if I want to add other fields is quite painful

Any suggestions to make this better?

To be blunt, you are probably overdesigning this A LOT. You have
asked a dozen or so questions here recently, all revolving around
run-time polymorphism. Concentrate on making the program do its job
instead.

I spent three years[1] maintaining an overdesigned protocol en/decoder
for the GTP protocol (which uses tag-value and tag-length-value
message attributes, just like yours) and I still hate the original
author. There were abstract factories, dynamic memory allocation,
std::multimap, templates, inheritance abuse in one big mix ... and it
was obviously not under its authors control.

I could prove, later, that none of that was needed, helpful, or even
harmless.

/Jorgen

[1] I had real work to do too, and the software had to work --
or I would have rewritten it during the first year.
 
A

Andrea Crotti

Jorgen Grahn said:
To be blunt, you are probably overdesigning this A LOT. You have
asked a dozen or so questions here recently, all revolving around
run-time polymorphism. Concentrate on making the program do its job
instead.

I spent three years[1] maintaining an overdesigned protocol en/decoder
for the GTP protocol (which uses tag-value and tag-length-value
message attributes, just like yours) and I still hate the original
author. There were abstract factories, dynamic memory allocation,
std::multimap, templates, inheritance abuse in one big mix ... and it
was obviously not under its authors control.

I could prove, later, that none of that was needed, helpful, or even
harmless.

/Jorgen

[1] I had real work to do too, and the software had to work --
or I would have rewritten it during the first year.

Well I don't think it's too much, I don't care too much about
polymorphism, I just care that I'll be able to write the more annoying
and hard to understand parts of the code in a clear and concise way.

This for me:
FieldHeader bh(BEACON);
Stream idSt = FieldHeader::createField(id, ID);
Stream coord = FieldHeader::createField(currentLocation, NODE_COORD);
Stream addr = FieldHeader::createField(address, NODE_ADDR);

creates a beacon, the corresponding old version was something like

char buffer[magic + 100 +2];
memcpy(buffer, xx, xx + 1010);
memcpy
....

and other 10 arbitraty memcpy, frankly since I'm using C++ I try to use
it's feature, otherwise I would use C...

Since it's an accademic research I must be able to change easily
implementation details / algorithms and test them, and I've been
explictily asked to develop in a very polymorphic and modular way.

(hope that clarifies)
 
J

Jorgen Grahn

Jorgen Grahn said:
To be blunt, you are probably overdesigning this A LOT. You have
asked a dozen or so questions here recently, all revolving around
run-time polymorphism. Concentrate on making the program do its job
instead.

I spent three years[1] maintaining an overdesigned protocol en/decoder
for the GTP protocol (which uses tag-value and tag-length-value
message attributes, just like yours) and I still hate the original
author. There were abstract factories, dynamic memory allocation,
std::multimap, templates, inheritance abuse in one big mix ... and it
was obviously not under its authors control.

I could prove, later, that none of that was needed, helpful, or even
harmless.

/Jorgen

[1] I had real work to do too, and the software had to work --
or I would have rewritten it during the first year.

Well I don't think it's too much, I don't care too much about
polymorphism, I just care that I'll be able to write the more annoying
and hard to understand parts of the code in a clear and concise way.

This for me:
FieldHeader bh(BEACON);
Stream idSt = FieldHeader::createField(id, ID);
Stream coord = FieldHeader::createField(currentLocation, NODE_COORD);
Stream addr = FieldHeader::createField(address, NODE_ADDR);

creates a beacon, the corresponding old version was something like

char buffer[magic + 100 +2];
memcpy(buffer, xx, xx + 1010);
memcpy
...

and other 10 arbitraty memcpy,

OK, that clearly sucks -- if it's sprinkled around in the code. But if
it's in one place, far away from the interesting parts of the program
logic, and encapsulated by well-documented functions and data
structures -- then I would let it be and concentrate on important
things first.

ugly + works + isolated = not an urgent problem
frankly since I'm using C++ I try to use
it's feature, otherwise I would use C...

C++ has a lot of features, and noone says you have to use *all* of them.
The ones you have asked about here are of the kind that IMO

- are really good to have in certain fairly rare situations
- are extremely overused, particularly by freshly indoctrinated students
and Java/Smalltalk programmers
Since it's an accademic research I must be able to change easily
implementation details / algorithms and test them, and I've been
explictily asked to develop in a very polymorphic and modular way.

Yes, but I'm worried that you do *too much* design in the wrong places.
I'm not complaining about the fact that you *do* design.
(hope that clarifies)

Sorry for the late answer,
/Jorgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,197
Latest member
ScottChare

Latest Threads

Top