Kaydet (Commit) de84529b authored tarafından Noel Grandin's avatar Noel Grandin Kaydeden (comit) Michael Stahl

Clang plugin to re-write SvStream operator<< to non-overloaded methods

Use a clang rewriter to rewrite SvStream::operator<< to methods
like WriteUInt32.
Note that the rewriter is not perfect, and hand-tweaking the output
is necessary.

Change-Id: I0291c8192ca74d6334ed3cf8cb713212b2f0c67d
Reviewed-on: https://gerrit.libreoffice.org/7307Reviewed-by: 's avatarMichael Stahl <mstahl@redhat.com>
Tested-by: 's avatarMichael Stahl <mstahl@redhat.com>
üst 14c8638a
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* Based on LLVM/Clang.
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*/
/*
This is a rewriter.
It changes the SvStream operator<< calls into calls to more explicitly named
methods, which reduces the casting needed, and makes it less likely that we
will accidentally write data to a file using the wrong data-type-size.
TODO we don't currently cope with macro expansion e.g. if the constant on the RHS is a #define
TODO we don't currently cope with code like "(*this) << 1;"
TODO we don't currently cope with code like "aStream << x << endl;" the "endl" parts ends up dangling.
TODO we don't currently cope with custom overloads of operator<< in some of the use-sites.
*/
#include "plugin.hxx"
#include <clang/Lex/Lexer.h>
#include <iostream>
namespace loplugin
{
class SvStreamOutputOperators
: public RecursiveASTVisitor< SvStreamOutputOperators >
, public RewritePlugin
{
public:
explicit SvStreamOutputOperators( CompilerInstance& compiler, Rewriter& rewriter );
virtual void run() override;
bool VisitCallExpr( const CallExpr* call );
private:
SourceLocation after(const SourceLocation& loc);
};
SvStreamOutputOperators::SvStreamOutputOperators( CompilerInstance& compiler, Rewriter& rewriter )
: RewritePlugin( compiler, rewriter )
{
}
void SvStreamOutputOperators::run()
{
TraverseDecl( compiler.getASTContext().getTranslationUnitDecl());
}
bool SvStreamOutputOperators::VisitCallExpr( const CallExpr* callExpr )
{
if( ignoreLocation( callExpr ))
return true;
if( callExpr->getNumArgs() < 2 )
return true;
const FunctionDecl* func = dyn_cast_or_null< FunctionDecl >( callExpr->getCalleeDecl() );
if ( func == NULL )
return true;
if( func->getNumParams() != 1 )
return true;
string qualifiedName = func->getQualifiedNameAsString();
if( qualifiedName != "SvStream::operator<<" )
return true;
string arg0 = func->getParamDecl( 0 )->getType().getAsString();
string newWriteMethod;
if( arg0 == "sal_uInt16" )
newWriteMethod = "WriteUInt16";
else if( arg0 == "sal_uInt32" )
newWriteMethod = "WriteUInt32";
else if( arg0 == "sal_uInt64" )
newWriteMethod = "WriteUInt64";
else if( arg0 == "sal_Int16" )
newWriteMethod = "WriteInt16";
else if( arg0 == "sal_Int32" )
newWriteMethod = "WriteInt32";
else if( arg0 == "sal_Int64" )
newWriteMethod = "WriteInt64";
else if( arg0 == "sal_uInt8" )
newWriteMethod = "WriteUInt8";
else if( arg0 == "sal_Unicode" )
newWriteMethod = "WriteUnicode";
else if( arg0 == "rtl::OString" )
newWriteMethod = "WriteOString";
else if( arg0 == "bool" )
newWriteMethod = "WriteBool";
else if( arg0 == "signed char" )
newWriteMethod = "WriteSChar";
else if( arg0 == "char" )
newWriteMethod = "WriteChar";
else if( arg0 == "unsigned char" )
newWriteMethod = "WriteUChar";
else if( arg0 == "float" )
newWriteMethod = "WriteFloat";
else if( arg0 == "double" )
newWriteMethod = "WriteDouble";
else if( arg0 == "const double &" )
newWriteMethod = "WriteDouble";
else if( arg0 == "const char *" )
newWriteMethod = "WriteCharPtr";
else if( arg0 == "char *" )
newWriteMethod = "WriteCharPtr";
else if( arg0 == "const unsigned char *" )
newWriteMethod = "WriteUCharPtr";
else if( arg0 == "unsigned char *" )
newWriteMethod = "WriteUCharPtr";
else if( arg0 == "class SvStream &" )
newWriteMethod = "WriteStream";
else
{
report( DiagnosticsEngine::Warning,
"found call to operator<< that I cannot convert with type: " + arg0,
callExpr->getLocStart());
return true;
}
// CallExpr overrides the children() method from Stmt, but not the const variant of it, so we need to cast const away.
StmtRange range = const_cast<CallExpr*>(callExpr)->children();
const Stmt* child1 = *range; // ImplicitCastExpr
++range;
const Stmt* child2 = *range; // ImplicitCastExpr
if( dyn_cast_or_null< UnaryOperator >( child2 ) != NULL )
{
// remove the "*" before the stream variable
if( !replaceText( callExpr->getLocStart(), 1, "" ) )
return true;
if( !replaceText( child1->getLocStart().getLocWithOffset(-1), 4, "->" ) )
return true;
}
else
{
if( !replaceText( child1->getLocStart().getLocWithOffset(-1), 4, "." ) )
return true;
}
if( !insertTextBefore( callExpr->getArg( 1 )->getLocStart(), newWriteMethod + "( " ) )
return true;
if( !insertTextAfter( after( callExpr->getLocEnd() ), " )" ) )
return true;
//TODO for some reason this is currently removing too much text
// if there was a cast e.g. "r << (sal_Int32) 1", then remove the cast
// const CStyleCastExpr* cast = dyn_cast_or_null< CStyleCastExpr >( callExpr->getArg(1) );
// if (cast != NULL)
// {
// replaceText( SourceRange( cast->getLParenLoc(), cast->getRParenLoc() ), "" );
// }
// if there was already parentheses around the expression, remove them
const ParenExpr* paren = dyn_cast_or_null< ParenExpr >( callExpr->getArg(1) );
if (paren != NULL)
{
if( !replaceText( paren->getLocStart(), 1, "" ) )
return true;
if( !replaceText( paren->getLocEnd(), 1, "" ) )
return true;
}
// report( DiagnosticsEngine::Note, "found", callExpr->getLocStart());
return true;
}
SourceLocation SvStreamOutputOperators::after( const SourceLocation& loc )
{
return Lexer::getLocForEndOfToken( loc, 0, compiler.getASTContext().getSourceManager(), compiler.getASTContext().getLangOpts() );
}
static Plugin::Registration< SvStreamOutputOperators > X( "svstreamoutputoperators" );
} // namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -315,24 +315,57 @@ public: ...@@ -315,24 +315,57 @@ public:
SvStream& operator>>( double& rDouble ); SvStream& operator>>( double& rDouble );
SvStream& operator>>( SvStream& rStream ); SvStream& operator>>( SvStream& rStream );
SvStream& operator<<( sal_uInt16 nUInt16 ); SvStream& operator<<( sal_uInt16 nUInt16 )
SvStream& operator<<( sal_uInt32 nUInt32 ); { return WriteUInt16(nUInt16); }
SvStream& operator<<( sal_uInt64 nuInt64 ); SvStream& operator<<( sal_uInt32 nUInt32 )
SvStream& operator<<( sal_Int16 nInt16 ); { return WriteUInt32(nUInt32); }
SvStream& operator<<( sal_Int32 nInt32 ); SvStream& operator<<( sal_uInt64 nuInt64 )
{ return WriteUInt64(nuInt64); }
SvStream& operator<<( sal_Int16 nInt16 )
{ return WriteInt16(nInt16); }
SvStream& operator<<( sal_Int32 nInt32 )
{ return WriteInt32(nInt32); }
SvStream& operator<<( sal_Int64 nInt64 ) SAL_DELETED_FUNCTION; SvStream& operator<<( sal_Int64 nInt64 ) SAL_DELETED_FUNCTION;
SvStream& WriteInt64(sal_Int64 nInt64);
SvStream& operator<<( bool b ) SvStream& operator<<( bool b )
{ return operator<<(static_cast< sal_Bool >(b)); } { return operator<<(static_cast< sal_Bool >(b)); }
SvStream& operator<<( signed char nChar ); SvStream& operator<<( signed char nChar )
SvStream& operator<<( char nChar ); { return WriteSChar(nChar); }
SvStream& operator<<( unsigned char nChar ); SvStream& operator<<( char nChar )
SvStream& operator<<( float nFloat ); { return WriteChar(nChar); }
SvStream& operator<<( const double& rDouble ); SvStream& operator<<( unsigned char nChar )
SvStream& operator<<( const char* pBuf ); { return WriteUChar(nChar); }
SvStream& operator<<( const unsigned char* pBuf ); SvStream& operator<<( float nFloat )
SvStream& operator<<( SvStream& rStream ); { return WriteFloat(nFloat); }
SvStream& operator<<( const double& rDouble )
{ return WriteDouble(rDouble); }
SvStream& operator<<( const char* pBuf )
{ return WriteCharPtr(pBuf); }
SvStream& operator<<( const unsigned char* pBuf )
{ return WriteUCharPtr(pBuf); }
SvStream& operator<<( SvStream& rStream )
{ return WriteStream(rStream); }
SvStream& WriteUInt16( sal_uInt16 nUInt16 );
SvStream& WriteUInt32( sal_uInt32 nUInt32 );
SvStream& WriteUInt64( sal_uInt64 nuInt64 );
SvStream& WriteInt16( sal_Int16 nInt16 );
SvStream& WriteInt32( sal_Int32 nInt32 );
SvStream& WriteInt64( sal_Int64 nInt64 );
SvStream& WriteUInt8( sal_uInt8 nuInt8 );
SvStream& WriteUnicode( sal_Unicode );
SvStream& WriteOString(const OString& rStr)
{ return WriteCharPtr(rStr.getStr()); }
SvStream& WriteStream( SvStream& rStream );
SvStream& WriteBool( bool b )
{ return WriteUChar(static_cast< sal_Bool >(b)); }
SvStream& WriteSChar( signed char nChar );
SvStream& WriteChar( char nChar );
SvStream& WriteUChar( unsigned char nChar );
SvStream& WriteFloat( float nFloat );
SvStream& WriteDouble( const double& rDouble );
SvStream& WriteCharPtr( const char* pBuf );
SvStream& WriteUCharPtr( const unsigned char* pBuf );
SvStream& WriteNumber( sal_uInt32 nUInt32 ); SvStream& WriteNumber( sal_uInt32 nUInt32 );
SvStream& WriteNumber( sal_Int32 nInt32 ); SvStream& WriteNumber( sal_Int32 nInt32 );
...@@ -585,6 +618,18 @@ sal_Size write_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm, ...@@ -585,6 +618,18 @@ sal_Size write_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
return streamdetail::write_lenPrefixed_seq_From_str<prefix, OUString, write_uInt16s_FromOUString>(rStrm, rStr); return streamdetail::write_lenPrefixed_seq_From_str<prefix, OUString, write_uInt16s_FromOUString>(rStrm, rStr);
} }
/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
/// of 16bit units from an OUString, returned value is number of bytes written
/// (including byte-count of prefix)
TOOLS_DLLPUBLIC sal_Size write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
const OUString &rStr);
/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
/// of 16bit units from an OUString, returned value is number of bytes written
/// (including byte-count of prefix)
TOOLS_DLLPUBLIC sal_Size write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
const OUString &rStr);
/// Attempt to read 8bit units to an OString until a zero terminator is /// Attempt to read 8bit units to an OString until a zero terminator is
/// encountered, returned OString's length is number of units *definitely* /// encountered, returned OString's length is number of units *definitely*
/// successfully read, check SvStream::good() to see if null terminator was /// successfully read, check SvStream::good() to see if null terminator was
...@@ -650,6 +695,22 @@ sal_Size write_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm, ...@@ -650,6 +695,22 @@ sal_Size write_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
return write_lenPrefixed_uInt8s_FromOString<prefix>(rStrm, OUStringToOString(rStr, eEnc)); return write_lenPrefixed_uInt8s_FromOString<prefix>(rStrm, OUStringToOString(rStr, eEnc));
} }
/// Attempt to write a pascal-style length (of type prefix) prefixed
/// sequence of units from a string-type, returned value is number of bytes
/// written (including byte-count of prefix)
TOOLS_DLLPUBLIC sal_Size write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
const OString &rStr);
/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
/// of 8bit units from an OUString, returned value is number of bytes written
/// (including byte-count of prefix)
TOOLS_DLLPUBLIC inline sal_Size write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
const OUString &rStr,
rtl_TextEncoding eEnc)
{
return write_uInt16_lenPrefixed_uInt8s_FromOString(rStrm, OUStringToOString(rStr, eEnc));
}
// FileStream // FileStream
class TOOLS_DLLPUBLIC SvFileStream : public SvStream class TOOLS_DLLPUBLIC SvFileStream : public SvStream
......
...@@ -790,7 +790,7 @@ bool SvStream::WriteLine(const OString& rStr) ...@@ -790,7 +790,7 @@ bool SvStream::WriteLine(const OString& rStr)
bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet ) bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet )
{ {
if ( eDestCharSet == RTL_TEXTENCODING_UNICODE ) if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
*this << ch; WriteChar(ch);
else else
{ {
OString aStr(&ch, 1, eDestCharSet); OString aStr(&ch, 1, eDestCharSet);
...@@ -805,7 +805,7 @@ bool SvStream::StartWritingUnicodeText() ...@@ -805,7 +805,7 @@ bool SvStream::StartWritingUnicodeText()
// BOM, Byte Order Mark, U+FEFF, see // BOM, Byte Order Mark, U+FEFF, see
// http://www.unicode.org/faq/utf_bom.html#BOM // http://www.unicode.org/faq/utf_bom.html#BOM
// Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap // Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
*this << sal_uInt16( 0xfeff ); WriteUInt16( 0xfeff );
return nError == SVSTREAM_OK; return nError == SVSTREAM_OK;
} }
...@@ -1055,7 +1055,7 @@ SvStream& SvStream::operator>> ( SvStream& rStream ) ...@@ -1055,7 +1055,7 @@ SvStream& SvStream::operator>> ( SvStream& rStream )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( sal_uInt16 v ) SvStream& SvStream::WriteUInt16( sal_uInt16 v )
{ {
if( bSwap ) if( bSwap )
SwapUShort(v); SwapUShort(v);
...@@ -1063,7 +1063,7 @@ SvStream& SvStream::operator<< ( sal_uInt16 v ) ...@@ -1063,7 +1063,7 @@ SvStream& SvStream::operator<< ( sal_uInt16 v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( sal_uInt32 v ) SvStream& SvStream::WriteUInt32( sal_uInt32 v )
{ {
if( bSwap ) if( bSwap )
SwapULong(v); SwapULong(v);
...@@ -1071,7 +1071,7 @@ SvStream& SvStream::operator<< ( sal_uInt32 v ) ...@@ -1071,7 +1071,7 @@ SvStream& SvStream::operator<< ( sal_uInt32 v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( sal_uInt64 v ) SvStream& SvStream::WriteUInt64( sal_uInt64 v )
{ {
if( bSwap ) if( bSwap )
SwapUInt64(v); SwapUInt64(v);
...@@ -1079,7 +1079,7 @@ SvStream& SvStream::operator<< ( sal_uInt64 v ) ...@@ -1079,7 +1079,7 @@ SvStream& SvStream::operator<< ( sal_uInt64 v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( sal_Int16 v ) SvStream& SvStream::WriteInt16( sal_Int16 v )
{ {
if( bSwap ) if( bSwap )
SwapShort(v); SwapShort(v);
...@@ -1087,7 +1087,7 @@ SvStream& SvStream::operator<< ( sal_Int16 v ) ...@@ -1087,7 +1087,7 @@ SvStream& SvStream::operator<< ( sal_Int16 v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( sal_Int32 v ) SvStream& SvStream::WriteInt32( sal_Int32 v )
{ {
if( bSwap ) if( bSwap )
SwapLongInt(v); SwapLongInt(v);
...@@ -1103,7 +1103,7 @@ SvStream& SvStream::WriteInt64 (sal_Int64 v) ...@@ -1103,7 +1103,7 @@ SvStream& SvStream::WriteInt64 (sal_Int64 v)
return *this; return *this;
} }
SvStream& SvStream::operator<< ( signed char v ) SvStream& SvStream::WriteSChar( signed char v )
{ {
//SDO //SDO
if(bIoWrite && sizeof(signed char) <= nBufFree ) if(bIoWrite && sizeof(signed char) <= nBufFree )
...@@ -1123,7 +1123,7 @@ SvStream& SvStream::operator<< ( signed char v ) ...@@ -1123,7 +1123,7 @@ SvStream& SvStream::operator<< ( signed char v )
// Special treatment for Chars due to PutBack // Special treatment for Chars due to PutBack
SvStream& SvStream::operator<< ( char v ) SvStream& SvStream::WriteChar( char v )
{ {
//SDO //SDO
if(bIoWrite && sizeof(char) <= nBufFree ) if(bIoWrite && sizeof(char) <= nBufFree )
...@@ -1141,7 +1141,7 @@ SvStream& SvStream::operator<< ( char v ) ...@@ -1141,7 +1141,7 @@ SvStream& SvStream::operator<< ( char v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( unsigned char v ) SvStream& SvStream::WriteUChar( unsigned char v )
{ {
//SDO //SDO
if(bIoWrite && sizeof(char) <= nBufFree ) if(bIoWrite && sizeof(char) <= nBufFree )
...@@ -1159,7 +1159,17 @@ SvStream& SvStream::operator<< ( unsigned char v ) ...@@ -1159,7 +1159,17 @@ SvStream& SvStream::operator<< ( unsigned char v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( float v ) SvStream& SvStream::WriteUInt8( sal_uInt8 v )
{
return WriteUChar(v);
}
SvStream& SvStream::WriteUnicode( sal_Unicode v )
{
return WriteUInt16(v);
}
SvStream& SvStream::WriteFloat( float v )
{ {
#ifdef UNX #ifdef UNX
if( bSwap ) if( bSwap )
...@@ -1169,7 +1179,7 @@ SvStream& SvStream::operator<< ( float v ) ...@@ -1169,7 +1179,7 @@ SvStream& SvStream::operator<< ( float v )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( const double& r ) SvStream& SvStream::WriteDouble ( const double& r )
{ {
#if defined UNX #if defined UNX
if( bSwap ) if( bSwap )
...@@ -1187,19 +1197,19 @@ SvStream& SvStream::operator<< ( const double& r ) ...@@ -1187,19 +1197,19 @@ SvStream& SvStream::operator<< ( const double& r )
return *this; return *this;
} }
SvStream& SvStream::operator<< ( const char* pBuf ) SvStream& SvStream::WriteCharPtr( const char* pBuf )
{ {
Write( pBuf, strlen( pBuf ) ); Write( pBuf, strlen( pBuf ) );
return *this; return *this;
} }
SvStream& SvStream::operator<< ( const unsigned char* pBuf ) SvStream& SvStream::WriteUCharPtr( const unsigned char* pBuf )
{ {
Write( (char*)pBuf, strlen( (char*)pBuf ) ); Write( (char*)pBuf, strlen( (char*)pBuf ) );
return *this; return *this;
} }
SvStream& SvStream::operator<< ( SvStream& rStream ) SvStream& SvStream::WriteStream( SvStream& rStream )
{ {
const sal_uInt32 cBufLen = 0x8000; const sal_uInt32 cBufLen = 0x8000;
char* pBuf = new char[ cBufLen ]; char* pBuf = new char[ cBufLen ];
...@@ -1225,9 +1235,9 @@ SvStream& SvStream::WriteUniOrByteString( const OUString& rStr, rtl_TextEncoding ...@@ -1225,9 +1235,9 @@ SvStream& SvStream::WriteUniOrByteString( const OUString& rStr, rtl_TextEncoding
{ {
// write UTF-16 string directly into stream ? // write UTF-16 string directly into stream ?
if (eDestCharSet == RTL_TEXTENCODING_UNICODE) if (eDestCharSet == RTL_TEXTENCODING_UNICODE)
write_lenPrefixed_uInt16s_FromOUString<sal_uInt32>(*this, rStr); write_uInt32_lenPrefixed_uInt16s_FromOUString(*this, rStr);
else else
write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(*this, rStr, eDestCharSet); write_uInt16_lenPrefixed_uInt8s_FromOUString(*this, rStr, eDestCharSet);
return *this; return *this;
} }
...@@ -1627,11 +1637,11 @@ SvStream& endl( SvStream& rStr ) ...@@ -1627,11 +1637,11 @@ SvStream& endl( SvStream& rStr )
{ {
LineEnd eDelim = rStr.GetLineDelimiter(); LineEnd eDelim = rStr.GetLineDelimiter();
if ( eDelim == LINEEND_CR ) if ( eDelim == LINEEND_CR )
rStr << '\r'; rStr.WriteChar('\r');
else if( eDelim == LINEEND_LF ) else if( eDelim == LINEEND_LF )
rStr << '\n'; rStr.WriteChar('\n');
else else
rStr << '\r' << '\n'; rStr.WriteChar('\r').WriteChar('\n');
return rStr; return rStr;
} }
...@@ -1640,13 +1650,13 @@ SvStream& endlu( SvStream& rStrm ) ...@@ -1640,13 +1650,13 @@ SvStream& endlu( SvStream& rStrm )
switch ( rStrm.GetLineDelimiter() ) switch ( rStrm.GetLineDelimiter() )
{ {
case LINEEND_CR : case LINEEND_CR :
rStrm << sal_Unicode('\r'); rStrm.WriteUnicode('\r');
break; break;
case LINEEND_LF : case LINEEND_LF :
rStrm << sal_Unicode('\n'); rStrm.WriteUnicode('\n');
break; break;
default: default:
rStrm << sal_Unicode('\r') << sal_Unicode('\n'); rStrm.WriteUnicode('\r').WriteUnicode('\n');
} }
return rStrm; return rStrm;
} }
...@@ -2170,4 +2180,55 @@ OUString convertLineEnd(const OUString &rIn, LineEnd eLineEnd) ...@@ -2170,4 +2180,55 @@ OUString convertLineEnd(const OUString &rIn, LineEnd eLineEnd)
return tmpl_convertLineEnd<OUString, OUStringBuffer>(rIn, eLineEnd); return tmpl_convertLineEnd<OUString, OUStringBuffer>(rIn, eLineEnd);
} }
sal_Size write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
const OUString &rStr)
{
sal_Size nWritten = 0;
sal_uInt32 nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<sal_uInt32>::max());
SAL_WARN_IF(static_cast<sal_Size>(nUnits) != static_cast<sal_Size>(rStr.getLength()),
"tools.stream",
"string too long for prefix count to fit in output type");
rStrm.WriteUInt32(nUnits);
if (rStrm.good())
{
nWritten += sizeof(sal_uInt32);
nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
}
return nWritten;
}
sal_Size write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
const OUString &rStr)
{
sal_Size nWritten = 0;
sal_uInt16 nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<sal_uInt16>::max());
SAL_WARN_IF(nUnits != rStr.getLength(),
"tools.stream",
"string too long for prefix count to fit in output type");
rStrm.WriteUInt16(nUnits);
if (rStrm.good())
{
nWritten += sizeof(nUnits);
nWritten += write_uInt16s_FromOUString(rStrm, rStr, nUnits);
}
return nWritten;
}
sal_Size write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
const OString &rStr)
{
sal_Size nWritten = 0;
sal_uInt16 nUnits = std::min<sal_Size>(rStr.getLength(), std::numeric_limits<sal_uInt16>::max());
SAL_WARN_IF(static_cast<sal_Size>(nUnits) != static_cast<sal_Size>(rStr.getLength()),
"tools.stream",
"string too long for sal_uInt16 count to fit in output type");
rStrm.WriteUInt16( nUnits );
if (rStrm.good())
{
nWritten += sizeof(sal_uInt16);
nWritten += write_uInt8s_FromOString(rStrm, rStr, nUnits);
}
return nWritten;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment