Suggestion about formatting

B

Barzo

Hi,

in a my previous post (http://groups.google.it/group/comp.lang.c++/
browse_frm/thread/fcd414d039dbd6be#) I had to convert a buffer into a
timestamp string:

[1F][4D][BC][77][80] -> 20030630073000

Now I have to do the opposite: having a string 20030630073000 I have
to return a buffer [1F][4D][BC][77][80].

The econding is like this:

00011111 01001101 10111100 01110111 10000000 -> 1F 4D BC 77 80
| 2003 | 06 | 30 | 07 | 30 | 00 |

where the year use 14 bits, months 4, days 5 and so on..

I have tought to do something like this:

int encode_time(const std::string& value, std::string& ret_val)
{
std::stringstream ss;
int i;
double d;
int st;

//value has to be YYYYMMDDhhmmss

ss << value.substr(0, 4);
if( (ss >> i).fail() ) { st = ss.rdstate(); return st;}
d = i * 0x4000000;
ss.flush();
ss << value.substr(4, 2);
if( (ss >> i).fail() ) { st = ss.rdstate(); return st;}
d += i * 0x400000;
ss.flush();
ss << value.substr(6, 2);
if( (ss >> i).fail() ) { st = ss.rdstate(); return st;}
d += i * 0x20000;
ss.flush();
.....
.....
ss.flush();
ss << d;
ret_val = ss.str();

}

The first conversion (0, 4) is ok and i=2003, but the second one (4,2)
fails and the func returns 7.
Where I wrong?

Tnx.
Daniele.
 
M

Michael DOUBEZ

Barzo said:
Hi,

in a my previous post (http://groups.google.it/group/comp.lang.c++/
browse_frm/thread/fcd414d039dbd6be#) I had to convert a buffer into a
timestamp string:

[1F][4D][BC][77][80] -> 20030630073000

Now I have to do the opposite: having a string 20030630073000 I have
to return a buffer [1F][4D][BC][77][80].

Perhaps the design solution would be to make a class that stores a
timestamp and as methods to read/write the different encoding. Rather
than coupling the two each time. It would make testing also easier.
The econding is like this:

00011111 01001101 10111100 01110111 10000000 -> 1F 4D BC 77 80
| 2003 | 06 | 30 | 07 | 30 | 00 |

where the year use 14 bits, months 4, days 5 and so on..

I have tought to do something like this:

int encode_time(const std::string& value, std::string& ret_val)
{
std::stringstream ss;
int i;
double d;
int st;

//value has to be YYYYMMDDhhmmss

ss << value.substr(0, 4);
if( (ss >> i).fail() ) { st = ss.rdstate(); return st;}
d = i * 0x4000000;

Beware of endianess. And double is not guaranteed to represent you number.
ss.flush();
ss << value.substr(4, 2);
if( (ss >> i).fail() ) { st = ss.rdstate(); return st;}
d += i * 0x400000;
ss.flush();
ss << value.substr(6, 2);
if( (ss >> i).fail() ) { st = ss.rdstate(); return st;}
d += i * 0x20000;
ss.flush();
.....
.....
ss.flush();
ss << d;
ret_val = ss.str();

}

Maybe you can consider using boost.lexical_cast (or roll your own
lexical_cast which is not that hard).

You function would be rewritten
try{
const unsigned year =lexical_cast<unsigned>(value.substr(0,4));
const unsigned month=lexical_cast<unsigned>(value.substr(4,2));
const unsigned day =lexical_cast<unsigned>(value.substr(6,2));
....
//re-encode
}
catch(const bad_lexical_cast& e)
{
//conversion error
}
The first conversion (0, 4) is ok and i=2003, but the second one (4,2)
fails and the func returns 7.
Where I wrong?
flush() doesn't remove the content of the underlying buffer in only
ensures the synchronization with underlying buffer.

You can Set your stringstream with:
ss.str(value.substr(4,2));
And use it rather than ss<<value...
 
B

Barzo

Perhaps the design solution would be to make a class that stores a
timestamp and as methods to read/write the different encoding. Rather
than coupling the two each time. It would make testing also easier.

I have tought about it, but for my case I think two functions are
enough.

Maybe you can consider using boost.lexical_cast (or roll your own
lexical_cast which is not that hard).

You function would be rewritten
try{
const unsigned year =lexical_cast<unsigned>(value.substr(0,4));
const unsigned month=lexical_cast<unsigned>(value.substr(4,2));
const unsigned day  =lexical_cast<unsigned>(value.substr(6,2));
...
//re-encode}

catch(const bad_lexical_cast& e)
{
   //conversion error}

Yes, this is a good solution.
I don't want to depend on Boost so I think I'll build my own.

flush() doesn't remove the content of the underlying buffer it only
ensures the synchronization with underlying buffer.

You can Set your stringstream with:
ss.str(value.substr(4,2));
And use it rather than ss<<value...

Ok. I'll keep it in mind!
Thanks for suggestions!

Daniele.
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top