Kaydet (Commit) f1335171 authored tarafından Norbert Thiebaud's avatar Norbert Thiebaud Kaydeden (comit) Andras Timar

performance tuning of helpex

callgrind (on text/swriter/guide translated in 'fr')

before Ir = 889,687,925
after Ir = 406,372,177 (405,668,292 w/o the 'native' memory allocator)

time confirms:
before 0.288/0.272/0.016
after  0.146/0.131/0.015

the output before and after were diff-ed and every generated xhp files
are identical.

All improvements where done still using 'normal' sal and c++ API.

There are still some low-hanging fruits, like XMLUtil:QuoteHTML
(probably 20-30 millions Ir to shave there)

The destruction of XMLElements is also singularly high
(11% of the remaining Ir count)

But the bulk of what is left is OString management (alloc/acquire/release/
free/copy), and I/O using streams

Change-Id: Ia316c953cd4bd46fc33a58a0c10f26b0ffa042c2
Reviewed-on: https://gerrit.libreoffice.org/1262Tested-by: 's avatarNorbert Thiebaud <nthiebaud@gmail.com>
Reviewed-by: 's avatarAndras Timar <atimar@suse.com>
Tested-by: 's avatarAndras Timar <atimar@suse.com>
üst d4498696
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <expat.h> #include <expat.h>
#include <rtl/ustring.hxx> #include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx> #include <rtl/strbuf.hxx>
#include "boost/unordered_map.hpp" #include "boost/unordered_map.hpp"
#include "export.hxx" #include "export.hxx"
...@@ -56,21 +56,21 @@ using namespace std; ...@@ -56,21 +56,21 @@ using namespace std;
class XMLAttribute class XMLAttribute
{ {
private: private:
rtl::OUString sName; rtl::OString sName;
rtl::OUString sValue; rtl::OString sValue;
public: public:
/// creates an attribute /// creates an attribute
XMLAttribute( XMLAttribute(
const rtl::OUString &rName, // attributes name const rtl::OString &rName, // attributes name
const rtl::OUString &rValue // attributes data const rtl::OString &rValue // attributes data
) )
: sName( rName ), sValue( rValue ) {} : sName( rName ), sValue( rValue ) {}
rtl::OUString GetName() const { return sName; } rtl::OString GetName() const { return sName; }
rtl::OUString GetValue() const { return sValue; } rtl::OString GetValue() const { return sValue; }
void setValue(const rtl::OUString &rValue){sValue=rValue;} void setValue(const rtl::OString &rValue){sValue=rValue;}
/// returns true if two attributes are equal and have the same value /// returns true if two attributes are equal and have the same value
sal_Bool IsEqual( sal_Bool IsEqual(
...@@ -183,7 +183,7 @@ class XMLFile : public XMLParentNode ...@@ -183,7 +183,7 @@ class XMLFile : public XMLParentNode
{ {
public: public:
XMLFile( XMLFile(
const rtl::OUString &rFileName // the file name, empty if created from memory stream const rtl::OString &rFileName // the file name, empty if created from memory stream
); );
XMLFile( const XMLFile& obj ) ; XMLFile( const XMLFile& obj ) ;
~XMLFile(); ~XMLFile();
...@@ -203,18 +203,18 @@ public: ...@@ -203,18 +203,18 @@ public:
virtual sal_uInt16 GetNodeType(); virtual sal_uInt16 GetNodeType();
/// returns file name /// returns file name
rtl::OUString GetName() { return sFileName; } rtl::OString GetName() { return sFileName; }
void SetName( const rtl::OUString &rFilename ) { sFileName = rFilename; } void SetName( const rtl::OString &rFilename ) { sFileName = rFilename; }
const std::vector<rtl::OString> getOrder(){ return order; } const std::vector<rtl::OString> getOrder(){ return order; }
protected: protected:
// writes a string as UTF8 with dos line ends to a given stream // writes a string as UTF8 with dos line ends to a given stream
void WriteString( ofstream &rStream, const rtl::OUString &sString ); void WriteString( ofstream &rStream, const rtl::OString &sString );
void InsertL10NElement( XMLElement* pElement); void InsertL10NElement( XMLElement* pElement);
// DATA // DATA
rtl::OUString sFileName; rtl::OString sFileName;
const rtl::OString ID, OLDREF, XML_LANG; const rtl::OString ID, OLDREF, XML_LANG;
...@@ -230,10 +230,10 @@ class XMLUtil{ ...@@ -230,10 +230,10 @@ class XMLUtil{
public: public:
/// Quot the XML characters and replace \n \t /// Quot the XML characters and replace \n \t
static void QuotHTML( rtl::OUString &rString ); static void QuotHTML( rtl::OString &rString );
/// UnQuot the XML characters and restore \n \t /// UnQuot the XML characters and restore \n \t
static void UnQuotHTML ( rtl::OUString &rString ); static void UnQuotHTML ( rtl::OString &rString );
}; };
...@@ -245,7 +245,7 @@ public: ...@@ -245,7 +245,7 @@ public:
class XMLElement : public XMLParentNode class XMLElement : public XMLParentNode
{ {
private: private:
rtl::OUString sElementName; rtl::OString sElementName;
XMLAttributeList *pAttributes; XMLAttributeList *pAttributes;
rtl::OString project, rtl::OString project,
filename, filename,
...@@ -256,12 +256,12 @@ private: ...@@ -256,12 +256,12 @@ private:
int nPos; int nPos;
protected: protected:
void Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement); void Print(XMLNode *pCur, OStringBuffer& buffer , bool rootelement);
public: public:
/// create a element node /// create a element node
XMLElement(){} XMLElement(){}
XMLElement( XMLElement(
const rtl::OUString &rName, // the element name const rtl::OString &rName, // the element name
XMLParentNode *Parent // parent node of this element XMLParentNode *Parent // parent node of this element
): XMLParentNode( Parent ), ): XMLParentNode( Parent ),
sElementName( rName ), sElementName( rName ),
...@@ -283,18 +283,18 @@ public: ...@@ -283,18 +283,18 @@ public:
virtual sal_uInt16 GetNodeType(); virtual sal_uInt16 GetNodeType();
/// returns element name /// returns element name
rtl::OUString GetName() { return sElementName; } rtl::OString GetName() { return sElementName; }
/// returns list of attributes of this element /// returns list of attributes of this element
XMLAttributeList *GetAttributeList() { return pAttributes; } XMLAttributeList *GetAttributeList() { return pAttributes; }
/// adds a new attribute to this element, typically used by parser /// adds a new attribute to this element, typically used by parser
void AddAttribute( const rtl::OUString &rAttribute, const rtl::OUString &rValue ); void AddAttribute( const rtl::OString &rAttribute, const rtl::OString &rValue );
void ChangeLanguageTag( const rtl::OUString &rValue ); void ChangeLanguageTag( const rtl::OString &rValue );
// Return a Unicode String representation of this object // Return a Unicode String representation of this object
OUString ToOUString(); OString ToOString();
void SetProject ( rtl::OString const & prj ){ project = prj; } void SetProject ( rtl::OString const & prj ){ project = prj; }
void SetFileName ( rtl::OString const & fn ){ filename = fn; } void SetFileName ( rtl::OString const & fn ){ filename = fn; }
...@@ -322,18 +322,18 @@ public: ...@@ -322,18 +322,18 @@ public:
class XMLData : public XMLChildNode class XMLData : public XMLChildNode
{ {
private: private:
rtl::OUString sData; rtl::OString sData;
bool isNewCreated; bool isNewCreated;
public: public:
/// create a data node /// create a data node
XMLData( XMLData(
const rtl::OUString &rData, // the initial data const rtl::OString &rData, // the initial data
XMLParentNode *Parent // the parent node of this data, typically a element node XMLParentNode *Parent // the parent node of this data, typically a element node
) )
: XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){} : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){}
XMLData( XMLData(
const rtl::OUString &rData, // the initial data const rtl::OString &rData, // the initial data
XMLParentNode *Parent, // the parent node of this data, typically a element node XMLParentNode *Parent, // the parent node of this data, typically a element node
bool newCreated bool newCreated
) )
...@@ -345,12 +345,12 @@ public: ...@@ -345,12 +345,12 @@ public:
virtual sal_uInt16 GetNodeType(); virtual sal_uInt16 GetNodeType();
/// returns the data /// returns the data
rtl::OUString GetData() { return sData; } rtl::OString GetData() { return sData; }
bool isNew() { return isNewCreated; } bool isNew() { return isNewCreated; }
/// adds new character data to the existing one /// adds new character data to the existing one
void AddData( void AddData(
const rtl::OUString &rData // the new data const rtl::OString &rData // the new data
); );
...@@ -364,12 +364,12 @@ public: ...@@ -364,12 +364,12 @@ public:
class XMLComment : public XMLChildNode class XMLComment : public XMLChildNode
{ {
private: private:
rtl::OUString sComment; rtl::OString sComment;
public: public:
/// create a comment node /// create a comment node
XMLComment( XMLComment(
const rtl::OUString &rComment, // the comment const rtl::OString &rComment, // the comment
XMLParentNode *Parent // the parent node of this comemnt, typically a element node XMLParentNode *Parent // the parent node of this comemnt, typically a element node
) )
: XMLChildNode( Parent ), sComment( rComment ) {} : XMLChildNode( Parent ), sComment( rComment ) {}
...@@ -381,7 +381,7 @@ public: ...@@ -381,7 +381,7 @@ public:
XMLComment& operator=(const XMLComment& obj); XMLComment& operator=(const XMLComment& obj);
/// returns the comment /// returns the comment
rtl::OUString GetComment() { return sComment; } rtl::OString GetComment() { return sComment; }
}; };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
...@@ -391,12 +391,12 @@ public: ...@@ -391,12 +391,12 @@ public:
class XMLDefault : public XMLChildNode class XMLDefault : public XMLChildNode
{ {
private: private:
rtl::OUString sDefault; rtl::OString sDefault;
public: public:
/// create a comment node /// create a comment node
XMLDefault( XMLDefault(
const rtl::OUString &rDefault, // the comment const rtl::OString &rDefault, // the comment
XMLParentNode *Parent // the parent node of this comemnt, typically a element node XMLParentNode *Parent // the parent node of this comemnt, typically a element node
) )
: XMLChildNode( Parent ), sDefault( rDefault ) {} : XMLChildNode( Parent ), sDefault( rDefault ) {}
...@@ -409,7 +409,7 @@ public: ...@@ -409,7 +409,7 @@ public:
virtual sal_uInt16 GetNodeType(); virtual sal_uInt16 GetNodeType();
/// returns the comment /// returns the comment
rtl::OUString GetDefault() { return sDefault; } rtl::OString GetDefault() { return sDefault; }
}; };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
...@@ -420,7 +420,7 @@ struct XMLError { ...@@ -420,7 +420,7 @@ struct XMLError {
XML_Error eCode; // the error code XML_Error eCode; // the error code
std::size_t nLine; // error line number std::size_t nLine; // error line number
std::size_t nColumn; // error column number std::size_t nColumn; // error column number
rtl::OUString sMessage; // readable error message rtl::OString sMessage; // readable error message
}; };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
...@@ -460,7 +460,7 @@ public: ...@@ -460,7 +460,7 @@ public:
/// parse a file, returns NULL on criticall errors /// parse a file, returns NULL on criticall errors
XMLFile *Execute( XMLFile *Execute(
const rtl::OUString &rFileName, // the file name const rtl::OString &rFileName, // the file name
XMLFile *pXMLFileIn // the XMLFile XMLFile *pXMLFileIn // the XMLFile
); );
......
...@@ -69,6 +69,33 @@ inline rtl::OUString pathnameToAbsoluteUrl(rtl::OUString const & pathname) { ...@@ -69,6 +69,33 @@ inline rtl::OUString pathnameToAbsoluteUrl(rtl::OUString const & pathname) {
return url; return url;
} }
inline rtl::OUString pathnameToAbsoluteUrl(rtl::OString const & pathname)
{
rtl::OUString url;
if (osl::FileBase::getFileURLFromSystemPath(OStringToOUString(pathname, RTL_TEXTENCODING_UTF8) , url)
!= osl::FileBase::E_None)
{
std::cerr << "Error: Cannot convert input pathname to URL\n";
std::exit(EXIT_FAILURE);
}
static rtl::OUString cwd;
if(cwd.isEmpty())
{
if (osl_getProcessWorkingDir(&cwd.pData) != osl_Process_E_None)
{
std::cerr << "Error: Cannot determine cwd\n";
std::exit(EXIT_FAILURE);
}
}
if (osl::FileBase::getAbsoluteFileURL(cwd, url, url)
!= osl::FileBase::E_None)
{
std::cerr << "Error: Cannot convert input URL to absolute URL\n";
std::exit(EXIT_FAILURE);
}
return url;
}
inline rtl::OString pathnameToken(char const * pathname, char const * root) { inline rtl::OString pathnameToken(char const * pathname, char const * root) {
rtl::OUString full; rtl::OUString full;
if (!rtl_convertStringToUString( if (!rtl_convertStringToUString(
......
...@@ -118,7 +118,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) { ...@@ -118,7 +118,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
hasNoError = hasNoError =
aParser.CreateSDF( aParser.CreateSDF(
aArgs.m_sOutputFile, aArgs.m_sPrj, aArgs.m_sPrjRoot, aArgs.m_sOutputFile, aArgs.m_sPrj, aArgs.m_sPrjRoot,
aArgs.m_sInputFile, new XMLFile( OUString('0') ), "help" ); aArgs.m_sInputFile, new XMLFile( OString('0') ), "help" );
} }
if( hasNoError ) if( hasNoError )
......
...@@ -78,20 +78,16 @@ bool HelpParser::CreateSDF( ...@@ -78,20 +78,16 @@ bool HelpParser::CreateSDF(
const rtl::OString &rSDFFile_in, const rtl::OString &rPrj_in,const rtl::OString &rRoot_in, const rtl::OString &rSDFFile_in, const rtl::OString &rPrj_in,const rtl::OString &rRoot_in,
const rtl::OString &sHelpFile, XMLFile *pXmlFile, const rtl::OString &rGsi1){ const rtl::OString &sHelpFile, XMLFile *pXmlFile, const rtl::OString &rGsi1){
SimpleXMLParser aParser; SimpleXMLParser aParser;
rtl::OUString sXmlFile(
rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
//TODO: explicit BOM handling? //TODO: explicit BOM handling?
std::auto_ptr <XMLFile> file ( aParser.Execute( sXmlFile, pXmlFile ) ); std::auto_ptr <XMLFile> file ( aParser.Execute( sHelpFile, pXmlFile ) );
if(file.get() == NULL) if(file.get() == NULL)
{ {
printf( printf(
"%s: %s\n", "%s: %s\n",
sHelpFile.getStr(), sHelpFile.getStr(),
(rtl::OUStringToOString( aParser.GetError().sMessage.getStr());
aParser.GetError().sMessage, RTL_TEXTENCODING_ASCII_US).
getStr()));
exit(-1); exit(-1);
} }
file->Extract(); file->Extract();
...@@ -113,10 +109,7 @@ bool HelpParser::CreateSDF( ...@@ -113,10 +109,7 @@ bool HelpParser::CreateSDF(
LangHashMap* pElem; LangHashMap* pElem;
XMLElement* pXMLElement = NULL; XMLElement* pXMLElement = NULL;
OUStringBuffer sBuffer; OStringBuffer sBuffer;
const OUString sOUPrj( rPrj_in.getStr() , rPrj_in.getLength() , RTL_TEXTENCODING_ASCII_US );
const OUString sOUActFileName(sActFileName.getStr() , sActFileName.getLength() , RTL_TEXTENCODING_ASCII_US );
const OUString sOUGsi1( rGsi1.getStr() , rGsi1.getLength() , RTL_TEXTENCODING_ASCII_US );
Export::InitLanguages( false ); Export::InitLanguages( false );
std::vector<rtl::OString> aLanguages = Export::GetLanguages(); std::vector<rtl::OString> aLanguages = Export::GetLanguages();
...@@ -138,34 +131,33 @@ bool HelpParser::CreateSDF( ...@@ -138,34 +131,33 @@ bool HelpParser::CreateSDF(
if( pXMLElement != NULL ) if( pXMLElement != NULL )
{ {
OUString data( OString data(
pXMLElement->ToOUString(). pXMLElement->ToOString().
replaceAll( replaceAll(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n")), rtl::OString("\n"),
rtl::OUString()). rtl::OString()).
replaceAll( replaceAll(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t")), rtl::OString("\t"),
rtl::OUString()).trim()); rtl::OString()).trim());
sBuffer.append( sOUPrj );
sBuffer.append('\t');
if ( !rRoot_in.isEmpty())
sBuffer.append( sOUActFileName );
sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t0\t"));
sBuffer.append( sOUGsi1 ); //"help";
sBuffer.append('\t');
rtl::OString sID = posm->first; // ID
sBuffer.append( rtl::OStringToOUString( sID, RTL_TEXTENCODING_UTF8 ) );
sBuffer.append('\t');
rtl::OString sOldRef = pXMLElement->GetOldref(); // oldref
sBuffer.append( rtl::OStringToOUString(sOldRef, RTL_TEXTENCODING_UTF8 ) );
sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t\t\t0\t"));
sBuffer.append( rtl::OStringToOUString( sCur, RTL_TEXTENCODING_UTF8 ) );
sBuffer.append('\t');
sBuffer.append( data );
sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t\t\t\t"));
rtl::OString sOut(rtl::OUStringToOString(sBuffer.makeStringAndClear().getStr() , RTL_TEXTENCODING_UTF8));
if( !data.isEmpty() ) if( !data.isEmpty() )
aSDFStream << sOut.getStr() << '\n'; {
sBuffer.append( rPrj_in );
sBuffer.append("\t");
if ( !rRoot_in.isEmpty())
sBuffer.append( sActFileName );
sBuffer.append( "\t0\t");
sBuffer.append( rGsi1 ); //"help";
sBuffer.append( "\t");
sBuffer.append( posm->first );
sBuffer.append( "\t");
sBuffer.append( pXMLElement->GetOldref());
sBuffer.append( "\t\t\t0\t");
sBuffer.append( sCur);
sBuffer.append('\t');
sBuffer.append( data );
sBuffer.append( "\t\t\t\t");
aSDFStream << sBuffer.makeStringAndClear().getStr() << '\n';
}
pXMLElement=NULL; pXMLElement=NULL;
} }
else else
...@@ -188,11 +180,9 @@ bool HelpParser::Merge( const rtl::OString &rSDFFile, const rtl::OString &rDesti ...@@ -188,11 +180,9 @@ bool HelpParser::Merge( const rtl::OString &rSDFFile, const rtl::OString &rDesti
SimpleXMLParser aParser; SimpleXMLParser aParser;
rtl::OUString sXmlFile(
rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
//TODO: explicit BOM handling? //TODO: explicit BOM handling?
XMLFile* xmlfile = ( aParser.Execute( sXmlFile, new XMLFile( rtl::OUString('0') ) ) ); XMLFile* xmlfile = ( aParser.Execute( sHelpFile, new XMLFile( rtl::OString('0') ) ) );
hasNoError = MergeSingleFile( xmlfile , aMergeDataFile , rLanguage , rDestinationFile ); hasNoError = MergeSingleFile( xmlfile , aMergeDataFile , rLanguage , rDestinationFile );
delete xmlfile; delete xmlfile;
return hasNoError; return hasNoError;
...@@ -203,7 +193,7 @@ bool HelpParser::MergeSingleFile( XMLFile* file , MergeDataFile& aMergeDataFile ...@@ -203,7 +193,7 @@ bool HelpParser::MergeSingleFile( XMLFile* file , MergeDataFile& aMergeDataFile
{ {
file->Extract(); file->Extract();
XMLHashMap* aXMLStrHM = file->GetStrings(); XMLHashMap* aXMLStrHM = file->GetStrings();
LangHashMap* aLangHM; LangHashMap* aLangHM;
static ResData pResData( "","",""); static ResData pResData( "","","");
pResData.sResTyp = "help"; pResData.sResTyp = "help";
...@@ -255,14 +245,14 @@ void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur , ...@@ -255,14 +245,14 @@ void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur ,
if( pEntrys != NULL) if( pEntrys != NULL)
{ {
rtl::OString sNewText; rtl::OString sNewText;
rtl::OUString sSourceText( rtl::OString sSourceText(
pXMLElement->ToOUString(). pXMLElement->ToOString().
replaceAll( replaceAll(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n")), rtl::OString("\n"),
rtl::OUString()). rtl::OString()).
replaceAll( replaceAll(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t")), rtl::OString("\t"),
rtl::OUString())); rtl::OString()));
// re-add spaces to the beginning of translated string, // re-add spaces to the beginning of translated string,
// important for indentation of Basic code examples // important for indentation of Basic code examples
sal_Int32 nPreSpaces = 0; sal_Int32 nPreSpaces = 0;
...@@ -270,11 +260,11 @@ void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur , ...@@ -270,11 +260,11 @@ void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur ,
while ( (nPreSpaces < nLen) && (*(sSourceText.getStr()+nPreSpaces) == ' ') ) while ( (nPreSpaces < nLen) && (*(sSourceText.getStr()+nPreSpaces) == ' ') )
nPreSpaces++; nPreSpaces++;
pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur , true ); pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur , true );
OUString sNewdata; OString sNewdata;
if (helper::isWellFormedXML(helper::QuotHTML(sNewText))) if (helper::isWellFormedXML(helper::QuotHTML(sNewText)))
{ {
sNewdata = sSourceText.copy(0,nPreSpaces) + sNewdata = sSourceText.copy(0,nPreSpaces) +
rtl::OStringToOUString(sNewText, RTL_TEXTENCODING_UTF8); sNewText;
} }
else else
{ {
...@@ -297,8 +287,7 @@ void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur , ...@@ -297,8 +287,7 @@ void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur ,
pResData->sGId.getStr(), pResData->sId.getStr(), pResData->sGId.getStr(), pResData->sId.getStr(),
pResData->sResTyp.getStr()); pResData->sResTyp.getStr());
} }
pXMLElement->ChangeLanguageTag( pXMLElement->ChangeLanguageTag(sCur);
rtl::OStringToOUString(sCur, RTL_TEXTENCODING_ASCII_US));
} }
} }
......
...@@ -29,13 +29,18 @@ ...@@ -29,13 +29,18 @@
namespace namespace
{ {
static ::rtl::OString lcl_NormalizeFilename(const ::rtl::OString& rFilename) static sal_Int32 lcl_BasenameIndex(const OString& rFilename)
{ {
return rFilename.copy( sal_Int32 index;
std::max( for(index = rFilename.getLength() - 1; index >= 0 ; --index)
rFilename.lastIndexOf( '\\' ), {
rFilename.lastIndexOf( '/' ))+1); if(rFilename[index] == '/' || rFilename[index] == '\\')
}; {
break;
}
}
return index + 1;
}
static bool lcl_ReadPoChecked( static bool lcl_ReadPoChecked(
PoEntry& o_rPoEntry, PoIfstream& rPoFile, PoEntry& o_rPoEntry, PoIfstream& rPoFile,
...@@ -165,7 +170,7 @@ MergeDataFile::MergeDataFile( ...@@ -165,7 +170,7 @@ MergeDataFile::MergeDataFile(
while( !aInputStream.eof() ) while( !aInputStream.eof() )
{ {
const OString sHack("HACK"); const OString sHack("HACK");
const OString sFileName( lcl_NormalizeFilename(rFile) ); const OString sFileName( rFile.getStr() + lcl_BasenameIndex(rFile) );
const bool bReadAll = sFileName.isEmpty(); const bool bReadAll = sFileName.isEmpty();
const OString sPoFileName(sPoFile.data(), sPoFile.length()); const OString sPoFileName(sPoFile.data(), sPoFile.length());
PoIfstream aPoInput; PoIfstream aPoInput;
...@@ -379,13 +384,7 @@ rtl::OString MergeDataFile::CreateKey(const rtl::OString& rTYP, const rtl::OStri ...@@ -379,13 +384,7 @@ rtl::OString MergeDataFile::CreateKey(const rtl::OString& rTYP, const rtl::OStri
const rtl::OString& rLID, const rtl::OString& rFilename, bool bCaseSensitive) const rtl::OString& rLID, const rtl::OString& rFilename, bool bCaseSensitive)
{ {
static const ::rtl::OString sStroke('-'); static const ::rtl::OString sStroke('-');
::rtl::OString sKey( rTYP ); ::rtl::OString sKey = rTYP + "-" + rGID + "-" + rLID + "-" + (rFilename.getStr() + lcl_BasenameIndex(rFilename) );
sKey += sStroke;
sKey += rGID;
sKey += sStroke;
sKey += rLID;
sKey += sStroke;
sKey += lcl_NormalizeFilename(rFilename);
OSL_TRACE("created key: %s", sKey.getStr()); OSL_TRACE("created key: %s", sKey.getStr());
if(bCaseSensitive) if(bCaseSensitive)
return sKey; // officecfg case sensitive identifier return sKey; // officecfg case sensitive identifier
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
#include <rtl/ustring.hxx> #include <rtl/ustring.hxx>
#include <rtl/strbuf.hxx>
#include <cstring> #include <cstring>
#include <ctime> #include <ctime>
...@@ -107,21 +108,217 @@ namespace ...@@ -107,21 +108,217 @@ namespace
} }
//Unescape text //Unescape text
static OString lcl_UnEscapeText(const OString& rText, static OString lcl_UnEscapeText(const OString& rText)
const OString& rEscaped = POESCAPED,
const OString& rUnEscaped = POUNESCAPED)
{ {
assert( rEscaped.getLength() == 2*rUnEscaped.getLength() ); sal_Int32 index;
OString sResult = rText; for(index = 0 ; index < rText.getLength() - 1; ++index)
int nCount = 0;
for(sal_Int32 nIndex=0; nIndex<rText.getLength()-1; ++nIndex)
{ {
sal_Int32 nActChar = rEscaped.indexOf(rText.copy(nIndex,2)); if(rText[index] == '\\')
if(nActChar % 2 == 0) {
sResult = sResult.replaceAt((nIndex++)-(nCount++),2, switch(rText[index + 1])
rUnEscaped.copy(nActChar/2,1)); {
case '\\':
case 'n':
case 'r':
case 't':
case '"':
OStringBuffer sBuff(rText);
const sal_Char* in = sBuff.getStr() + index;
sal_Char* out = &sBuff[index];
while(*in)
{
if(*in == '\\')
{
switch(in[1])
{
case '\\':
*out++ = '\\';
in += 2;
break;
case 'n':
*out++ = '\n';
in += 2;
break;
case 'r':
*out++ = '\r';
in += 2;
break;
case 't':
*out++ = '\t';
in += 2;
break;
case '"':
*out++ = '"';
in += 2;
break;
default:
*out++ = *in++;
break;
}
}
else
{
*out++ = *in++;
}
}
*out = 0;
sBuff.setLength((out - sBuff.getStr()));
return sBuff.makeStringAndClear();
}
}
} }
return sResult; return rText;
}
static OString lcl_UnEscapeTextBlanks(const OString& rText)
{
sal_Int32 index;
for(index = 0 ; index < rText.getLength() - 1; ++index)
{
if(rText[index] == '\\')
{
switch(rText[index + 1])
{
case 'n':
case 'r':
case 't':
OStringBuffer sBuff(rText);
const sal_Char* in = sBuff.getStr() + index;
sal_Char* out = &sBuff[index];
while(*in)
{
if(*in == '\\')
{
switch(in[1])
{
case 'n':
*out++ = '\n';
in += 2;
break;
case 'r':
*out++ = '\r';
in += 2;
break;
case 't':
*out++ = '\t';
in += 2;
break;
default:
*out++ = *in++;
break;
}
}
else
{
*out++ = *in++;
}
}
*out = 0;
sBuff.setLength((out - sBuff.getStr()));
return sBuff.makeStringAndClear();
}
}
}
return rText;
}
static OString lcl_EscapeTextBlanks(const OString& rText)
{
sal_Int32 index;
for(index = 0 ; index < rText.getLength() - 1; ++index)
{
switch(rText[index])
{
case '\n':
case '\r':
case '\t':
OStringBuffer sBuff(rText);
const sal_Char* in = rText.getStr() + index;
sal_Char* out = &sBuff[index];
while(*in)
{
switch(in[1])
{
case '\n':
*out++ = '\\';
*out++ = 'n';
break;
case '\r':
*out++ = '\\';
*out++ = 'r';
break;
case 't':
*out++ = '\\';
*out++ = 'r';
break;
default:
*out++ = *in++;
break;
}
}
*out = 0;
sBuff.setLength((out - sBuff.getStr()));
return sBuff.makeStringAndClear();
}
}
return rText;
}
static OString lcl_UnEscapeTextHelp(const OString& rText)
{
sal_Int32 index;
for(index = 0 ; index < rText.getLength() - 1; ++index)
{
if(rText[index] == '\\')
{
switch(rText[index + 1])
{
case '<':
case '>':
case '"':
case '\\':
OStringBuffer sBuff(rText);
const sal_Char* in = sBuff.getStr() + index;
sal_Char* out = &sBuff[index];
while(*in)
{
if(*in == '\\')
{
switch(in[1])
{
case '<':
*out++ = '<';
in += 2;
break;
case '>':
*out++ = '>';
in += 2;
break;
case '"':
*out++ = '"';
in += 2;
break;
case '\\':
*out++ = '\\';
in += 2;
break;
default:
*out++ = *in++;
break;
}
}
else
{
*out++ = *in++;
}
}
*out = 0;
sBuff.setLength((out - sBuff.getStr()));
return sBuff.makeStringAndClear();
}
}
}
return rText;
} }
//Convert a normal string to msg/po output string //Convert a normal string to msg/po output string
...@@ -301,9 +498,9 @@ namespace ...@@ -301,9 +498,9 @@ namespace
const OString& rText,const bool bHelpText = false ) const OString& rText,const bool bHelpText = false )
{ {
if ( bHelpText ) if ( bHelpText )
return lcl_UnEscapeText(rText,"\\<\\>\\\"\\\\","<>\"\\"); return lcl_UnEscapeTextHelp(rText);
else else
return lcl_UnEscapeText(rText,"\\n\\t\\r","\n\t\r"); return lcl_UnEscapeTextBlanks(rText);
} }
//Find all special tag in a string using a regular expression //Find all special tag in a string using a regular expression
...@@ -311,18 +508,18 @@ namespace ...@@ -311,18 +508,18 @@ namespace
const OString& rText,std::vector<OString>& o_vFoundTags ) const OString& rText,std::vector<OString>& o_vFoundTags )
{ {
UErrorCode nIcuErr = U_ZERO_ERROR; static UErrorCode nIcuErr = U_ZERO_ERROR;
sal_uInt32 nSearchFlags = UREGEX_DOTALL | UREGEX_CASE_INSENSITIVE; static sal_uInt32 nSearchFlags = UREGEX_DOTALL | UREGEX_CASE_INSENSITIVE;
OUString sLocaleText( OStringToOUString(rText,RTL_TEXTENCODING_UTF8) ); OUString sLocaleText( OStringToOUString(rText,RTL_TEXTENCODING_UTF8) );
OUString sPattern("<[/]\?\?[a-z_-]+?(?:| +[a-z]+?=\".*?\") *[/]\?\?>"); static OUString sPattern("<[/]\?\?[a-z_-]+?(?:| +[a-z]+?=\".*?\") *[/]\?\?>");
UnicodeString sSearchPat( static UnicodeString sSearchPat(
reinterpret_cast<const UChar*>( reinterpret_cast<const UChar*>(
sPattern.getStr()), sPattern.getLength() ); sPattern.getStr()), sPattern.getLength() );
UnicodeString sSource( UnicodeString sSource(
reinterpret_cast<const UChar*>( reinterpret_cast<const UChar*>(
sLocaleText.getStr()), sLocaleText.getLength() ); sLocaleText.getStr()), sLocaleText.getLength() );
RegexMatcher aRegexMatcher( sSearchPat, nSearchFlags, nIcuErr ); static RegexMatcher aRegexMatcher( sSearchPat, nSearchFlags, nIcuErr );
aRegexMatcher.reset( sSource ); aRegexMatcher.reset( sSource );
int64_t nStartPos = 0; int64_t nStartPos = 0;
while( aRegexMatcher.find(nStartPos, nIcuErr) && while( aRegexMatcher.find(nStartPos, nIcuErr) &&
...@@ -386,7 +583,7 @@ namespace ...@@ -386,7 +583,7 @@ namespace
if ( bHelpText ) if ( bHelpText )
return lcl_EscapeTags(rText.replaceAll("\\","\\\\")); return lcl_EscapeTags(rText.replaceAll("\\","\\\\"));
else else
return lcl_EscapeText(rText,"\n\t\r","\\n\\t\\r"); return lcl_EscapeTextBlanks(rText);
} }
} }
......
This diff is collapsed.
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