|
Boost : |
From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-05-07 13:36:56
John Nagle wrote:
>Reece Dunn wrote:
>>John Nagle wrote:
>>
>>>Reece Dunn wrote:
>>>
>>>>There is currently a static-sized array in the Boost library that allows
>>>>you to operate on arrays of fixed size. I was wondering if something
>>>>similar exists for strings, in particular, providing buffer-overflow
>>>>safe string operations.
>>>>
>>>>I have an nstring< std::size_t n > string class that provides size-safe
>>>>copying and comparison, allowing for you to do things like:
>
>OK, thanks. First bug reports:
>
>1. Compile problems under VC++ 6:
> No include brings in "std::size_t".
Fixed.
>2. VC++ 6.x complains about references to a zero-sized array for
> [edit]: copy( const char( & s )[ m ] )
I have disabled these for VC6 since they are causing problems with the
compiler, even with Thorsten Ottersen's workaround :(.
>3. "copy" function does not place a trailing null in the string.
>[snip]
> Note that "strlen" returns a count that does NOT contain the null.
I have added this facility as a template parameter (bool null_terminate).
The logic behind this is when you do not specifically need a null-terminated
string, e.g.:
struct JPEGHeader
{
// ...
boost::string::char_string< 4 > magic;
// ...
} hdr;
if( hdr.magic != "JPEG" ) error( "invalid format" );
but also to allow it if you need that security.
> All the operations should guarantee that the string remains null
>terminated. A constructor should be provided, but all it has to
>do is put a null in the first character position.
I have already provided such a constructor :).
> As for the naming issue, the important thing for retrofit work
>is that it should be possible to write a "using" statement that makes
>"strcopy", "sprintf", for char_string etc. valid without prefixes, and
>doesn't break anything else. You should be able to include something
>("safe_strings.hpp"?) that does as much as possible to fix old code.
I have moved the char_string class into char_string.hpp and started work on
providing safe versions of ::strXXX. It is not possible to use the same
names (strlen, etc.) for the char_string versions :( as can be seen in the
example below.
#include <iostream>
#include <cstring>
namespace boost { namespace string
{
using ::strcpy;
inline char * strcpy( char * d, const char * s, size_t n )
{
return( ::strncpy( d, s, n ));
}
}}
int main()
{
char str[ 100 ];
using boost::string::strcpy;
::strcpy( str, "Meine Welt!" );
std::cout << str << '\n';
::strcpy( str, "1234567890", 5 ); // error
std::cout << str << '\n';
return( 0 );
}
Because of this, I have decided to use the c prefix (e.g. cstrlen). This
seems the best solution, but if the c prefix is problematic, let me know and
I'll change it.
>This is a good start, and not hard to fix. I look forward to the
>next round.
I have included this round as attachments, but will place the next version
in the boost sandbox. It has the signature:
template< size_t n, bool null_terminate = true, typename CharT = char,
class StringPolicy = std::char_traits< CharT > >
class boost::string::char_string;
and is the initial move towards a basic_string-like interface. How about the
name fixed_string?
Regards,
Reece
_________________________________________________________________
It's fast, it's easy and it's free. Get MSN Messenger today!
http://www.msn.co.uk/messenger
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk