diff options
Diffstat (limited to 'svl/source/misc')
-rw-r--r-- | svl/source/misc/PasswordHelper.cxx | 109 | ||||
-rw-r--r-- | svl/source/misc/adrparse.cxx | 921 | ||||
-rw-r--r-- | svl/source/misc/documentlockfile.cxx | 238 | ||||
-rw-r--r-- | svl/source/misc/filenotation.cxx | 147 | ||||
-rw-r--r-- | svl/source/misc/folderrestriction.cxx | 109 | ||||
-rw-r--r-- | svl/source/misc/fstathelper.cxx | 103 | ||||
-rw-r--r-- | svl/source/misc/inethist.cxx | 545 | ||||
-rw-r--r-- | svl/source/misc/inettype.cxx | 1348 | ||||
-rw-r--r-- | svl/source/misc/lngmisc.cxx | 141 | ||||
-rw-r--r-- | svl/source/misc/lockfilecommon.cxx | 276 | ||||
-rw-r--r-- | svl/source/misc/makefile.mk | 74 | ||||
-rw-r--r-- | svl/source/misc/mediatyp.src | 610 | ||||
-rw-r--r-- | svl/source/misc/ownlist.cxx | 330 | ||||
-rw-r--r-- | svl/source/misc/restrictedpaths.cxx | 217 | ||||
-rw-r--r-- | svl/source/misc/sharecontrolfile.cxx | 376 | ||||
-rw-r--r-- | svl/source/misc/strmadpt.cxx | 1048 | ||||
-rw-r--r-- | svl/source/misc/svldata.cxx | 94 | ||||
-rw-r--r-- | svl/source/misc/urihelper.cxx | 952 |
18 files changed, 7638 insertions, 0 deletions
diff --git a/svl/source/misc/PasswordHelper.cxx b/svl/source/misc/PasswordHelper.cxx new file mode 100644 index 000000000000..a1125306eb7b --- /dev/null +++ b/svl/source/misc/PasswordHelper.cxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PasswordHelper.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + + +#ifndef GCC +#endif +#include "PasswordHelper.hxx" +#include <rtl/digest.h> +#include <tools/string.hxx> + +using namespace com::sun::star; + +void SvPasswordHelper::GetHashPassword(uno::Sequence<sal_Int8>& rPassHash, const sal_Char* pPass, sal_uInt32 nLen) +{ + rPassHash.realloc(RTL_DIGEST_LENGTH_SHA1); + + rtlDigestError aError = rtl_digest_SHA1 (pPass, nLen, reinterpret_cast<sal_uInt8*>(rPassHash.getArray()), rPassHash.getLength()); + if (aError != rtl_Digest_E_None) + { + rPassHash.realloc(0); + } +} + +void SvPasswordHelper::GetHashPasswordLittleEndian(uno::Sequence<sal_Int8>& rPassHash, const String& sPass) +{ + xub_StrLen nSize(sPass.Len()); + sal_Char* pCharBuffer = new sal_Char[nSize * sizeof(sal_Unicode)]; + + for (xub_StrLen i = 0; i < nSize; ++i) + { + sal_Unicode ch(sPass.GetChar(i)); + pCharBuffer[2 * i] = static_cast< sal_Char >(ch & 0xFF); + pCharBuffer[2 * i + 1] = static_cast< sal_Char >(ch >> 8); + } + + GetHashPassword(rPassHash, pCharBuffer, nSize * sizeof(sal_Unicode)); + + delete[] pCharBuffer; +} + +void SvPasswordHelper::GetHashPasswordBigEndian(uno::Sequence<sal_Int8>& rPassHash, const String& sPass) +{ + xub_StrLen nSize(sPass.Len()); + sal_Char* pCharBuffer = new sal_Char[nSize * sizeof(sal_Unicode)]; + + for (xub_StrLen i = 0; i < nSize; ++i) + { + sal_Unicode ch(sPass.GetChar(i)); + pCharBuffer[2 * i] = static_cast< sal_Char >(ch >> 8); + pCharBuffer[2 * i + 1] = static_cast< sal_Char >(ch & 0xFF); + } + + GetHashPassword(rPassHash, pCharBuffer, nSize * sizeof(sal_Unicode)); + + delete[] pCharBuffer; +} + +void SvPasswordHelper::GetHashPassword(uno::Sequence<sal_Int8>& rPassHash, const String& sPass) +{ + GetHashPasswordLittleEndian(rPassHash, sPass); +} + +bool SvPasswordHelper::CompareHashPassword(const uno::Sequence<sal_Int8>& rOldPassHash, const String& sNewPass) +{ + bool bResult = false; + + uno::Sequence<sal_Int8> aNewPass(RTL_DIGEST_LENGTH_SHA1); + GetHashPasswordLittleEndian(aNewPass, sNewPass); + if (aNewPass == rOldPassHash) + bResult = true; + else + { + GetHashPasswordBigEndian(aNewPass, sNewPass); + bResult = (aNewPass == rOldPassHash); + } + + return bResult; +} + diff --git a/svl/source/misc/adrparse.cxx b/svl/source/misc/adrparse.cxx new file mode 100644 index 000000000000..b45650846df5 --- /dev/null +++ b/svl/source/misc/adrparse.cxx @@ -0,0 +1,921 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: adrparse.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/inetmime.hxx> +#include <adrparse.hxx> + +namespace unnamed_svl_adrparse {} +using namespace unnamed_svl_adrparse; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svl_adrparse { + +enum ElementType { ELEMENT_START, ELEMENT_DELIM, ELEMENT_ITEM, ELEMENT_END }; + +//============================================================================ +struct ParsedAddrSpec +{ + sal_Unicode const * m_pBegin; + sal_Unicode const * m_pEnd; + ElementType m_eLastElem; + bool m_bAtFound; + bool m_bReparse; + + ParsedAddrSpec() { reset(); } + + bool isPoorlyValid() const { return m_eLastElem >= ELEMENT_ITEM; } + + bool isValid() const { return isPoorlyValid() && m_bAtFound; } + + inline void reset(); + + inline void finish(); +}; + +inline void ParsedAddrSpec::reset() +{ + m_pBegin = 0; + m_pEnd = 0; + m_eLastElem = ELEMENT_START; + m_bAtFound = false; + m_bReparse = false; +} + +inline void ParsedAddrSpec::finish() +{ + if (isPoorlyValid()) + m_eLastElem = ELEMENT_END; + else + reset(); +} + +} + +//============================================================================ +class SvAddressParser_Impl +{ + enum State { BEFORE_COLON, BEFORE_LESS, AFTER_LESS, AFTER_GREATER }; + + enum TokenType { TOKEN_QUOTED = 0x80000000, TOKEN_DOMAIN, TOKEN_COMMENT, + TOKEN_ATOM }; + + sal_Unicode const * m_pInputPos; + sal_Unicode const * m_pInputEnd; + sal_uInt32 m_nCurToken; + sal_Unicode const * m_pCurTokenBegin; + sal_Unicode const * m_pCurTokenEnd; + sal_Unicode const * m_pCurTokenContentBegin; + sal_Unicode const * m_pCurTokenContentEnd; + bool m_bCurTokenReparse; + ParsedAddrSpec m_aOuterAddrSpec; + ParsedAddrSpec m_aInnerAddrSpec; + ParsedAddrSpec * m_pAddrSpec; + sal_Unicode const * m_pRealNameBegin; + sal_Unicode const * m_pRealNameEnd; + sal_Unicode const * m_pRealNameContentBegin; + sal_Unicode const * m_pRealNameContentEnd; + bool m_bRealNameReparse; + bool m_bRealNameFinished; + sal_Unicode const * m_pFirstCommentBegin; + sal_Unicode const * m_pFirstCommentEnd; + bool m_bFirstCommentReparse; + State m_eState; + TokenType m_eType; + + inline void resetRealNameAndFirstComment(); + + inline void reset(); + + inline void addTokenToAddrSpec(ElementType eTokenElem); + + inline void addTokenToRealName(); + + bool readToken(); + + static UniString reparse(sal_Unicode const * pBegin, + sal_Unicode const * pEnd, bool bAddrSpec); + + static UniString reparseComment(sal_Unicode const * pBegin, + sal_Unicode const * pEnd); + +public: + SvAddressParser_Impl(SvAddressParser * pParser, UniString const & rInput); +}; + +inline void SvAddressParser_Impl::resetRealNameAndFirstComment() +{ + m_pRealNameBegin = 0; + m_pRealNameEnd = 0; + m_pRealNameContentBegin = 0; + m_pRealNameContentEnd = 0; + m_bRealNameReparse = false; + m_bRealNameFinished = false; + m_pFirstCommentBegin = 0; + m_pFirstCommentEnd = 0; + m_bFirstCommentReparse = false; +} + +inline void SvAddressParser_Impl::reset() +{ + m_aOuterAddrSpec.reset(); + m_aInnerAddrSpec.reset(); + m_pAddrSpec = &m_aOuterAddrSpec; + resetRealNameAndFirstComment(); + m_eState = BEFORE_COLON; + m_eType = TOKEN_ATOM; +} + +inline void SvAddressParser_Impl::addTokenToAddrSpec(ElementType eTokenElem) +{ + if (!m_pAddrSpec->m_pBegin) + m_pAddrSpec->m_pBegin = m_pCurTokenBegin; + else if (m_pAddrSpec->m_pEnd < m_pCurTokenBegin) + m_pAddrSpec->m_bReparse = true; + m_pAddrSpec->m_pEnd = m_pCurTokenEnd; + m_pAddrSpec->m_eLastElem = eTokenElem; +} + +inline void SvAddressParser_Impl::addTokenToRealName() +{ + if (!m_bRealNameFinished && m_eState != AFTER_LESS) + { + if (!m_pRealNameBegin) + m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin; + else if (m_pRealNameEnd < m_pCurTokenBegin - 1 + || (m_pRealNameEnd == m_pCurTokenBegin - 1 + && *m_pRealNameEnd != ' ')) + m_bRealNameReparse = true; + m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd; + } +} + +//============================================================================ +// +// SvAddressParser_Impl +// +//============================================================================ + +bool SvAddressParser_Impl::readToken() +{ + m_nCurToken = m_eType; + m_bCurTokenReparse = false; + switch (m_eType) + { + case TOKEN_QUOTED: + { + m_pCurTokenBegin = m_pInputPos - 1; + m_pCurTokenContentBegin = m_pInputPos; + bool bEscaped = false; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + sal_Unicode cChar = *m_pInputPos++; + if (bEscaped) + { + m_bCurTokenReparse = true; + bEscaped = false; + } + else if (cChar == '"') + { + m_pCurTokenEnd = m_pInputPos; + m_pCurTokenContentEnd = m_pInputPos - 1; + return true; + } + else if (cChar == '\\') + bEscaped = true; + } + } + + case TOKEN_DOMAIN: + { + m_pCurTokenBegin = m_pInputPos - 1; + m_pCurTokenContentBegin = m_pInputPos; + bool bEscaped = false; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + sal_Unicode cChar = *m_pInputPos++; + if (bEscaped) + bEscaped = false; + else if (cChar == ']') + { + m_pCurTokenEnd = m_pInputPos; + return true; + } + else if (cChar == '\\') + bEscaped = true; + } + } + + case TOKEN_COMMENT: + { + m_pCurTokenBegin = m_pInputPos - 1; + m_pCurTokenContentBegin = 0; + m_pCurTokenContentEnd = 0; + bool bEscaped = false; + xub_StrLen nLevel = 0; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + sal_Unicode cChar = *m_pInputPos++; + if (bEscaped) + { + m_bCurTokenReparse = true; + m_pCurTokenContentEnd = m_pInputPos; + bEscaped = false; + } + else if (cChar == '(') + { + if (!m_pCurTokenContentBegin) + m_pCurTokenContentBegin = m_pInputPos - 1; + m_pCurTokenContentEnd = m_pInputPos; + ++nLevel; + } + else if (cChar == ')') + if (nLevel) + { + m_pCurTokenContentEnd = m_pInputPos; + --nLevel; + } + else + return true; + else if (cChar == '\\') + { + if (!m_pCurTokenContentBegin) + m_pCurTokenContentBegin = m_pInputPos - 1; + bEscaped = true; + } + else if (cChar > ' ' && cChar != 0x7F) // DEL + { + if (!m_pCurTokenContentBegin) + m_pCurTokenContentBegin = m_pInputPos - 1; + m_pCurTokenContentEnd = m_pInputPos; + } + } + } + + default: + { + sal_Unicode cChar; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + cChar = *m_pInputPos++; + if (cChar > ' ' && cChar != 0x7F) // DEL + break; + } + m_pCurTokenBegin = m_pInputPos - 1; + if (cChar == '"' || cChar == '(' || cChar == ')' || cChar == ',' + || cChar == '.' || cChar == ':' || cChar == ';' + || cChar == '<' || cChar == '>' || cChar == '@' + || cChar == '[' || cChar == '\\' || cChar == ']') + { + m_nCurToken = cChar; + m_pCurTokenEnd = m_pInputPos; + return true; + } + else + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + { + m_pCurTokenEnd = m_pInputPos; + return true; + } + cChar = *m_pInputPos++; + if (cChar <= ' ' || cChar == '"' || cChar == '(' + || cChar == ')' || cChar == ',' || cChar == '.' + || cChar == ':' || cChar == ';' || cChar == '<' + || cChar == '>' || cChar == '@' || cChar == '[' + || cChar == '\\' || cChar == ']' + || cChar == 0x7F) // DEL + { + m_pCurTokenEnd = --m_pInputPos; + return true; + } + } + } + } +} + +//============================================================================ +// static +UniString SvAddressParser_Impl::reparse(sal_Unicode const * pBegin, + sal_Unicode const * pEnd, + bool bAddrSpec) +{ + UniString aResult; + TokenType eMode = TOKEN_ATOM; + bool bEscaped = false; + bool bEndsWithSpace = false; + xub_StrLen nLevel = 0; + while (pBegin < pEnd) + { + sal_Unicode cChar = *pBegin++; + switch (eMode) + { + case TOKEN_QUOTED: + if (bEscaped) + { + aResult += cChar; + bEscaped = false; + } + else if (cChar == '"') + { + if (bAddrSpec) + aResult += cChar; + eMode = TOKEN_ATOM; + } + else if (cChar == '\\') + { + if (bAddrSpec) + aResult += cChar; + bEscaped = true; + } + else + aResult += cChar; + break; + + case TOKEN_DOMAIN: + if (bEscaped) + { + aResult += cChar; + bEscaped = false; + } + else if (cChar == ']') + { + aResult += cChar; + eMode = TOKEN_ATOM; + } + else if (cChar == '\\') + { + if (bAddrSpec) + aResult += cChar; + bEscaped = true; + } + else + aResult += cChar; + break; + + case TOKEN_COMMENT: + if (bEscaped) + bEscaped = false; + else if (cChar == '(') + ++nLevel; + else if (cChar == ')') + if (nLevel) + --nLevel; + else + eMode = TOKEN_ATOM; + else if (cChar == '\\') + bEscaped = true; + break; + + case TOKEN_ATOM: + if (cChar <= ' ' || cChar == 0x7F) // DEL + { + if (!bAddrSpec && !bEndsWithSpace) + { + aResult += ' '; + bEndsWithSpace = true; + } + } + else if (cChar == '(') + { + if (!bAddrSpec && !bEndsWithSpace) + { + aResult += ' '; + bEndsWithSpace = true; + } + eMode = TOKEN_COMMENT; + } + else + { + bEndsWithSpace = false; + if (cChar == '"') + { + if (bAddrSpec) + aResult += cChar; + eMode = TOKEN_QUOTED; + } + else if (cChar == '[') + { + aResult += cChar; + eMode = TOKEN_QUOTED; + } + else + aResult += cChar; + } + break; + } + } + return aResult; +} + +//============================================================================ +// static +UniString SvAddressParser_Impl::reparseComment(sal_Unicode const * pBegin, + sal_Unicode const * pEnd) +{ + UniString aResult; + while (pBegin < pEnd) + { + sal_Unicode cChar = *pBegin++; + if (cChar == '\\') + cChar = *pBegin++; + aResult += cChar; + } + return aResult; +} + +//============================================================================ +SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, + UniString const & rInput) +{ + m_pInputPos = rInput.GetBuffer(); + m_pInputEnd = m_pInputPos + rInput.Len(); + + reset(); + bool bDone = false; + for (;;) + { + if (!readToken()) + { + m_bRealNameFinished = true; + if (m_eState == AFTER_LESS) + m_nCurToken = '>'; + else + { + m_nCurToken = ','; + bDone = true; + } + } + switch (m_nCurToken) + { + case TOKEN_QUOTED: + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_bAtFound + || m_pAddrSpec->m_eLastElem <= ELEMENT_DELIM) + m_pAddrSpec->reset(); + addTokenToAddrSpec(ELEMENT_ITEM); + } + if (!m_bRealNameFinished && m_eState != AFTER_LESS) + { + if (m_bCurTokenReparse) + { + if (!m_pRealNameBegin) + m_pRealNameBegin = m_pCurTokenBegin; + m_pRealNameEnd = m_pCurTokenEnd; + m_bRealNameReparse = true; + } + else if (m_bRealNameReparse) + m_pRealNameEnd = m_pCurTokenEnd; + else if (!m_pRealNameBegin) + { + m_pRealNameBegin = m_pCurTokenBegin; + m_pRealNameContentBegin = m_pCurTokenContentBegin; + m_pRealNameEnd = m_pRealNameContentEnd + = m_pCurTokenContentEnd; + } + else + { + m_pRealNameEnd = m_pCurTokenEnd; + m_bRealNameReparse = true; + } + } + m_eType = TOKEN_ATOM; + break; + + case TOKEN_DOMAIN: + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_bAtFound + && m_pAddrSpec->m_eLastElem == ELEMENT_DELIM) + addTokenToAddrSpec(ELEMENT_ITEM); + else + m_pAddrSpec->reset(); + } + addTokenToRealName(); + m_eType = TOKEN_ATOM; + break; + + case TOKEN_COMMENT: + if (!m_bRealNameFinished && m_eState != AFTER_LESS + && !m_pFirstCommentBegin && m_pCurTokenContentBegin) + { + m_pFirstCommentBegin = m_pCurTokenContentBegin; + m_pFirstCommentEnd = m_pCurTokenContentEnd; + m_bFirstCommentReparse = m_bCurTokenReparse; + } + m_eType = TOKEN_ATOM; + break; + + case TOKEN_ATOM: + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM) + m_pAddrSpec->reset(); + addTokenToAddrSpec(ELEMENT_ITEM); + } + addTokenToRealName(); + break; + + case '(': + m_eType = TOKEN_COMMENT; + break; + + case ')': + case '\\': + case ']': + m_pAddrSpec->finish(); + addTokenToRealName(); + break; + + case '<': + switch (m_eState) + { + case BEFORE_COLON: + case BEFORE_LESS: + m_aOuterAddrSpec.finish(); + if (m_pRealNameBegin) + m_bRealNameFinished = true; + m_pAddrSpec = &m_aInnerAddrSpec; + m_eState = AFTER_LESS; + break; + + case AFTER_LESS: + m_aInnerAddrSpec.finish(); + break; + + case AFTER_GREATER: + m_aOuterAddrSpec.finish(); + addTokenToRealName(); + break; + } + break; + + case '>': + if (m_eState == AFTER_LESS) + { + m_aInnerAddrSpec.finish(); + if (m_aInnerAddrSpec.isValid()) + m_aOuterAddrSpec.m_eLastElem = ELEMENT_END; + m_pAddrSpec = &m_aOuterAddrSpec; + m_eState = AFTER_GREATER; + } + else + { + m_aOuterAddrSpec.finish(); + addTokenToRealName(); + } + break; + + case '@': + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (!m_pAddrSpec->m_bAtFound + && m_pAddrSpec->m_eLastElem == ELEMENT_ITEM) + { + addTokenToAddrSpec(ELEMENT_DELIM); + m_pAddrSpec->m_bAtFound = true; + } + else + m_pAddrSpec->reset(); + } + addTokenToRealName(); + break; + + case ',': + case ';': + if (m_eState == AFTER_LESS) + if (m_nCurToken == ',') + { + if (m_aInnerAddrSpec.m_eLastElem + != ELEMENT_END) + m_aInnerAddrSpec.reset(); + } + else + m_aInnerAddrSpec.finish(); + else + { + m_pAddrSpec = m_aInnerAddrSpec.isValid() + || (!m_aOuterAddrSpec.isValid() + && m_aInnerAddrSpec.isPoorlyValid()) ? + &m_aInnerAddrSpec : + m_aOuterAddrSpec.isPoorlyValid() ? + &m_aOuterAddrSpec : 0; + if (m_pAddrSpec) + { + UniString aTheAddrSpec; + if (m_pAddrSpec->m_bReparse) + aTheAddrSpec = reparse(m_pAddrSpec->m_pBegin, + m_pAddrSpec->m_pEnd, true); + else + { + xub_StrLen nLen = + sal::static_int_cast< xub_StrLen >( + m_pAddrSpec->m_pEnd + - m_pAddrSpec->m_pBegin); + if (nLen == rInput.Len()) + aTheAddrSpec = rInput; + else + aTheAddrSpec + = rInput.Copy( + sal::static_int_cast< xub_StrLen >( + m_pAddrSpec->m_pBegin + - rInput.GetBuffer()), + nLen); + } + UniString aTheRealName; + if (!m_pRealNameBegin + || (m_pAddrSpec == &m_aOuterAddrSpec + && m_pRealNameBegin + == m_aOuterAddrSpec.m_pBegin + && m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd + && m_pFirstCommentBegin)) + if (!m_pFirstCommentBegin) + aTheRealName = aTheAddrSpec; + else if (m_bFirstCommentReparse) + aTheRealName + = reparseComment(m_pFirstCommentBegin, + m_pFirstCommentEnd); + else + aTheRealName + = rInput.Copy( + sal::static_int_cast< xub_StrLen >( + m_pFirstCommentBegin + - rInput.GetBuffer()), + sal::static_int_cast< xub_StrLen >( + m_pFirstCommentEnd + - m_pFirstCommentBegin)); + else if (m_bRealNameReparse) + aTheRealName = reparse(m_pRealNameBegin, + m_pRealNameEnd, false); + else + { + xub_StrLen nLen = + sal::static_int_cast< xub_StrLen >( + m_pRealNameContentEnd + - m_pRealNameContentBegin); + if (nLen == rInput.Len()) + aTheRealName = rInput; + else + aTheRealName + = rInput.Copy( + sal::static_int_cast< xub_StrLen >( + m_pRealNameContentBegin + - rInput.GetBuffer()), + nLen); + } + if (pParser->m_bHasFirst) + pParser->m_aRest.Insert(new SvAddressEntry_Impl( + aTheAddrSpec, + aTheRealName), + LIST_APPEND); + else + { + pParser->m_bHasFirst = true; + pParser->m_aFirst.m_aAddrSpec = aTheAddrSpec; + pParser->m_aFirst.m_aRealName = aTheRealName; + } + } + if (bDone) + return; + reset(); + } + break; + + case ':': + switch (m_eState) + { + case BEFORE_COLON: + m_aOuterAddrSpec.reset(); + resetRealNameAndFirstComment(); + m_eState = BEFORE_LESS; + break; + + case BEFORE_LESS: + case AFTER_GREATER: + m_aOuterAddrSpec.finish(); + addTokenToRealName(); + break; + + case AFTER_LESS: + m_aInnerAddrSpec.reset(); + break; + } + break; + + case '"': + m_eType = TOKEN_QUOTED; + break; + + case '.': + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM) + addTokenToAddrSpec(ELEMENT_DELIM); + else + m_pAddrSpec->reset(); + } + addTokenToRealName(); + break; + + case '[': + m_eType = TOKEN_DOMAIN; + break; + } + } +} + +//============================================================================ +// +// SvAddressParser +// +//============================================================================ + +SvAddressParser::SvAddressParser(UniString const & rInput): m_bHasFirst(false) +{ + SvAddressParser_Impl(this, rInput); +} + +//============================================================================ +SvAddressParser::~SvAddressParser() +{ + for (ULONG i = m_aRest.Count(); i != 0;) + delete m_aRest.Remove(--i); +} + +//============================================================================ +// static +bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, + String const & rAddrSpec, + String & rMailbox) +{ + String aTheAddrSpec; + sal_Unicode const * p = rAddrSpec.GetBuffer(); + sal_Unicode const * pEnd = p + rAddrSpec.Len(); + {for (bool bSegment = false;;) + { + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + return false; + if (bSegment) + { + sal_Unicode c = *p++; + if (c == '@') + break; + else if (c != '.') + return false; + aTheAddrSpec += '.'; + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + return false; + } + else + bSegment = true; + if (*p == '"') + { + aTheAddrSpec += *p++; + for (;;) + { + if (INetMIME::startsWithLineFolding(p, pEnd)) + p += 2; + if (p == pEnd) + return false; + if (*p == '"') + break; + if (*p == '\x0D' || (*p == '\\' && ++p == pEnd) + || !INetMIME::isUSASCII(*p)) + return false; + if (INetMIME::needsQuotedStringEscape(*p)) + aTheAddrSpec += '\\'; + aTheAddrSpec += *p++; + } + aTheAddrSpec += *p++; + } + else if (INetMIME::isAtomChar(*p)) + while (p != pEnd && INetMIME::isAtomChar(*p)) + aTheAddrSpec += *p++; + else + return false; + }} + aTheAddrSpec += '@'; + {for (bool bSegment = false;;) + { + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + { + if (bSegment) + break; + else + return false; + } + if (bSegment) + { + if (*p++ != '.') + return false; + aTheAddrSpec += '.'; + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + return false; + } + else + bSegment = true; + if (*p == '[') + { + aTheAddrSpec += *p++; + for (;;) + { + if (INetMIME::startsWithLineFolding(p, pEnd)) + p += 2; + if (p == pEnd) + return false; + if (*p == ']') + break; + if (*p == '\x0D' || *p == '[' || (*p == '\\' && ++p == pEnd) + || !INetMIME::isUSASCII(*p)) + return false; + if (*p >= '[' && *p <= ']') + aTheAddrSpec += '\\'; + aTheAddrSpec += *p++; + } + aTheAddrSpec += *p++; + } + else if (INetMIME::isAtomChar(*p)) + while (p != pEnd && INetMIME::isAtomChar(*p)) + aTheAddrSpec += *p++; + else + return false; + }} + + if (rPhrase.Len() == 0) + rMailbox = aTheAddrSpec; + else + { + bool bQuotedString = false; + p = rPhrase.GetBuffer(); + pEnd = p + rPhrase.Len(); + for (;p != pEnd; ++p) + if (!(INetMIME::isAtomChar(*p))) + { + bQuotedString = true; + break; + } + String aTheMailbox; + if (bQuotedString) + { + aTheMailbox = '"'; + for (p = rPhrase.GetBuffer(); p != pEnd; ++p) + { + if (INetMIME::needsQuotedStringEscape(*p)) + aTheMailbox += '\\'; + aTheMailbox += *p; + } + aTheMailbox += '"'; + } + else + aTheMailbox = rPhrase; + aTheMailbox.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" <")); + aTheMailbox += aTheAddrSpec; + aTheMailbox += '>'; + rMailbox = aTheMailbox; + } + return true; +} + diff --git a/svl/source/misc/documentlockfile.cxx b/svl/source/misc/documentlockfile.cxx new file mode 100644 index 000000000000..b0c4148749e7 --- /dev/null +++ b/svl/source/misc/documentlockfile.cxx @@ -0,0 +1,238 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: documentlockfile.cxx,v $ + * + * $Revision: 1.3.82.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <stdio.h> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> + +#include <osl/time.h> +#include <osl/security.hxx> +#include <osl/socket.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/processfactory.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/bootstrap.hxx> + +#include <ucbhelper/content.hxx> + +#include <unotools/useroptions.hxx> + +#include <svl/documentlockfile.hxx> + +using namespace ::com::sun::star; + +namespace svt { + +sal_Bool DocumentLockFile::m_bAllowInteraction = sal_True; + +// ---------------------------------------------------------------------- +DocumentLockFile::DocumentLockFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".~lock." ) ) ) +{ +} + +// ---------------------------------------------------------------------- +DocumentLockFile::~DocumentLockFile() +{ +} + +// ---------------------------------------------------------------------- +void DocumentLockFile::WriteEntryToStream( uno::Sequence< ::rtl::OUString > aEntry, uno::Reference< io::XOutputStream > xOutput ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ::rtl::OUStringBuffer aBuffer; + + for ( sal_Int32 nEntryInd = 0; nEntryInd < aEntry.getLength(); nEntryInd++ ) + { + aBuffer.append( EscapeCharacters( aEntry[nEntryInd] ) ); + if ( nEntryInd < aEntry.getLength() - 1 ) + aBuffer.append( (sal_Unicode)',' ); + else + aBuffer.append( (sal_Unicode)';' ); + } + + ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) ); + uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() ); + xOutput->writeBytes( aData ); +} + +// ---------------------------------------------------------------------- +sal_Bool DocumentLockFile::CreateOwnLockFile() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + try + { + uno::Reference< io::XStream > xTempFile( + m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW ); + + uno::Reference< io::XInputStream > xInput = xTempFile->getInputStream(); + uno::Reference< io::XOutputStream > xOutput = xTempFile->getOutputStream(); + + if ( !xInput.is() || !xOutput.is() ) + throw uno::RuntimeException(); + + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + WriteEntryToStream( aNewEntry, xOutput ); + xOutput->closeOutput(); + + xSeekable->seek( 0 ); + + uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv; + ::ucbhelper::Content aTargetContent( m_aURL, xEnv ); + + ucb::InsertCommandArgument aInsertArg; + aInsertArg.Data = xInput; + aInsertArg.ReplaceExisting = sal_False; + uno::Any aCmdArg; + aCmdArg <<= aInsertArg; + aTargetContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ), aCmdArg ); + + // try to let the file be hidden if possible + try { + aTargetContent.setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), uno::makeAny( sal_True ) ); + } catch( uno::Exception& ) {} + } + catch( ucb::NameClashException& ) + { + return sal_False; + } + + return sal_True; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > DocumentLockFile::GetLockData() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< io::XInputStream > xInput = OpenStream(); + if ( !xInput.is() ) + throw uno::RuntimeException(); + + const sal_Int32 nBufLen = 32000; + uno::Sequence< sal_Int8 > aBuffer( nBufLen ); + + sal_Int32 nRead = 0; + + nRead = xInput->readBytes( aBuffer, nBufLen ); + xInput->closeInput(); + + if ( nRead == nBufLen ) + throw io::WrongFormatException(); + + sal_Int32 nCurPos = 0; + return ParseEntry( aBuffer, nCurPos ); +} + +// ---------------------------------------------------------------------- +uno::Reference< io::XInputStream > DocumentLockFile::OpenStream() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), + uno::UNO_QUERY_THROW ); + + // the file can be opened readonly, no locking will be done + return xSimpleFileAccess->openFileRead( m_aURL ); +} + +// ---------------------------------------------------------------------- +sal_Bool DocumentLockFile::OverwriteOwnLockFile() +{ + // allows to overwrite the lock file with the current data + try + { + uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv; + ::ucbhelper::Content aTargetContent( m_aURL, xEnv ); + + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + + uno::Reference< io::XStream > xStream = aTargetContent.openWriteableStreamNoLock(); + uno::Reference< io::XOutputStream > xOutput = xStream->getOutputStream(); + uno::Reference< io::XTruncate > xTruncate( xOutput, uno::UNO_QUERY_THROW ); + + xTruncate->truncate(); + WriteEntryToStream( aNewEntry, xOutput ); + xOutput->closeOutput(); + } + catch( uno::Exception& ) + { + return sal_False; + } + + return sal_True; +} + +// ---------------------------------------------------------------------- +void DocumentLockFile::RemoveFile() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO/LATER: the removing is not atomar, is it possible in general to make it atomar? + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + uno::Sequence< ::rtl::OUString > aFileData = GetLockData(); + + if ( aFileData.getLength() < LOCKFILE_ENTRYSIZE ) + throw io::WrongFormatException(); + + if ( !aFileData[LOCKFILE_SYSUSERNAME_ID].equals( aNewEntry[LOCKFILE_SYSUSERNAME_ID] ) + || !aFileData[LOCKFILE_LOCALHOST_ID].equals( aNewEntry[LOCKFILE_LOCALHOST_ID] ) + || !aFileData[LOCKFILE_USERURL_ID].equals( aNewEntry[LOCKFILE_USERURL_ID] ) ) + throw io::IOException(); // not the owner, access denied + + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), + uno::UNO_QUERY_THROW ); + xSimpleFileAccess->kill( m_aURL ); +} + +} // namespace svt + diff --git a/svl/source/misc/filenotation.cxx b/svl/source/misc/filenotation.cxx new file mode 100644 index 000000000000..d50645c97439 --- /dev/null +++ b/svl/source/misc/filenotation.cxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: filenotation.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include "filenotation.hxx" +#include <osl/file.h> +#include <osl/diagnose.h> +#include <tools/urlobj.hxx> + +//......................................................................... +namespace svt +{ +//......................................................................... + + //===================================================================== + //= OFileNotation + //===================================================================== + //--------------------------------------------------------------------- + OFileNotation::OFileNotation( const ::rtl::OUString& _rUrlOrPath ) + { + construct( _rUrlOrPath ); + } + + //--------------------------------------------------------------------- + OFileNotation::OFileNotation( const ::rtl::OUString& _rUrlOrPath, NOTATION _eInputNotation ) + { + if ( _eInputNotation == N_URL ) + { + INetURLObject aParser( _rUrlOrPath ); + if ( aParser.GetProtocol() == INET_PROT_FILE ) + implInitWithURLNotation( _rUrlOrPath ); + else + m_sSystem = m_sFileURL = _rUrlOrPath; + } + else + implInitWithSystemNotation( _rUrlOrPath ); + } + + //--------------------------------------------------------------------- + bool OFileNotation::implInitWithSystemNotation( const ::rtl::OUString& _rSystemPath ) + { + bool bSuccess = false; + + m_sSystem = _rSystemPath; + if ( ( osl_File_E_None != osl_getFileURLFromSystemPath( m_sSystem.pData, &m_sFileURL.pData ) ) + && ( 0 == m_sFileURL.getLength() ) + ) + { + if ( _rSystemPath.getLength() ) + { + INetURLObject aSmartParser; + aSmartParser.SetSmartProtocol( INET_PROT_FILE ); + if ( aSmartParser.SetSmartURL( _rSystemPath ) ) + { + m_sFileURL = aSmartParser.GetMainURL( INetURLObject::NO_DECODE ); + osl_getSystemPathFromFileURL( m_sFileURL.pData, &m_sSystem.pData ); + bSuccess = true; + } + } + } + else + bSuccess = true; + return bSuccess; + } + + //--------------------------------------------------------------------- + bool OFileNotation::implInitWithURLNotation( const ::rtl::OUString& _rURL ) + { + m_sFileURL = _rURL; + osl_getSystemPathFromFileURL( _rURL.pData, &m_sSystem.pData ); + return true; + } + + //--------------------------------------------------------------------- + void OFileNotation::construct( const ::rtl::OUString& _rUrlOrPath ) + { + bool bSuccess = false; + // URL notation? + INetURLObject aParser( _rUrlOrPath ); + switch ( aParser.GetProtocol() ) + { + case INET_PROT_FILE: + // file URL + bSuccess = implInitWithURLNotation( _rUrlOrPath ); + break; + + case INET_PROT_NOT_VALID: + // assume system notation + bSuccess = implInitWithSystemNotation( _rUrlOrPath ); + break; + + default: + // it's a known scheme, but no file-URL -> assume that bothe the URL representation and the + // system representation are the URL itself + m_sSystem = m_sFileURL = _rUrlOrPath; + bSuccess = true; + break; + } + + OSL_ENSURE( bSuccess, "OFileNotation::OFileNotation: could not detect the format!" ); + } + + //--------------------------------------------------------------------- + ::rtl::OUString OFileNotation::get(NOTATION _eOutputNotation) + { + switch (_eOutputNotation) + { + case N_SYSTEM: return m_sSystem; + case N_URL: return m_sFileURL; + } + + OSL_ENSURE(sal_False, "OFileNotation::get: inavlid enum value!"); + return ::rtl::OUString(); + } + +//......................................................................... +} // namespace svt +//......................................................................... + diff --git a/svl/source/misc/folderrestriction.cxx b/svl/source/misc/folderrestriction.cxx new file mode 100644 index 000000000000..9ec7ead0a4be --- /dev/null +++ b/svl/source/misc/folderrestriction.cxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: folderrestriction.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "folderrestriction.hxx" +#include "osl/process.h" +#include "tools/urlobj.hxx" +#include "unotools/localfilehelper.hxx" + +//----------------------------------------------------------------------------- + +static void convertStringListToUrls ( + const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash ) +{ + const sal_Unicode s_cSeparator = +#if defined(WNT) + ';' +#else + ':' +#endif + ; + xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator ); + _rTokens.resize( 0 ); _rTokens.reserve( nTokens ); + for ( xub_StrLen i=0; i<nTokens; ++i ) + { + // the current token in the list + String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator ); + if ( !sCurrentToken.Len() ) + continue; + + INetURLObject aCurrentURL; + + String sURL; + if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) ) + aCurrentURL = INetURLObject( sURL ); + else + { + // smart URL parsing, assuming FILE protocol + aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE ); + } + + if ( _bFinalSlash ) + aCurrentURL.setFinalSlash( ); + else + aCurrentURL.removeFinalSlash( ); + _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) ); + } +} + +/** retrieves the value of an environment variable + @return <TRUE/> if and only if the retrieved string value is not empty +*/ +static bool getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue ) +{ + _rValue = ::rtl::OUString(); + ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName ); + osl_getEnvironment( sEnvName.pData, &_rValue.pData ); + return _rValue.getLength() != 0; +} + +//----------------------------------------------------------------------------- + +namespace svt +{ + + void getUnrestrictedFolders( ::std::vector< String >& _rFolders ) + { + _rFolders.resize( 0 ); + ::rtl::OUString sRestrictedPathList; + if ( getEnvironmentValue( "RestrictedPath", sRestrictedPathList ) ) + { + // append a final slash. This ensures that when we later on check + // for unrestricted paths, we don't allow paths like "/home/user35" just because + // "/home/user3" is allowed - with the final slash, we make it "/home/user3/". + convertStringListToUrls( sRestrictedPathList, _rFolders, true ); + } + } + +} // namespace svt + diff --git a/svl/source/misc/fstathelper.cxx b/svl/source/misc/fstathelper.cxx new file mode 100644 index 000000000000..43619e879a91 --- /dev/null +++ b/svl/source/misc/fstathelper.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: fstathelper.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/string.hxx> +#include <ucbhelper/content.hxx> +#include <com/sun/star/util/DateTime.hpp> + +#include <fstathelper.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::rtl; + +sal_Bool FStatHelper::GetModifiedDateTimeOfFile( const UniString& rURL, + Date* pDate, Time* pTime ) +{ + sal_Bool bRet = FALSE; + try + { + ::ucbhelper::Content aTestContent( rURL, + uno::Reference< XCommandEnvironment > ()); + uno::Any aAny = aTestContent.getPropertyValue( + OUString::createFromAscii( "DateModified" ) ); + if( aAny.hasValue() ) + { + bRet = sal_True; + const util::DateTime* pDT = (util::DateTime*)aAny.getValue(); + if( pDate ) + *pDate = Date( pDT->Day, pDT->Month, pDT->Year ); + if( pTime ) + *pTime = Time( pDT->Hours, pDT->Minutes, + pDT->Seconds, pDT->HundredthSeconds ); + } + } + catch(...) + { + } + + return bRet; +} + +sal_Bool FStatHelper::IsDocument( const UniString& rURL ) +{ + BOOL bExist = FALSE; + try + { + ::ucbhelper::Content aTestContent( rURL, + uno::Reference< XCommandEnvironment > ()); + bExist = aTestContent.isDocument(); + } + catch(...) + { + } + return bExist; +} + +sal_Bool FStatHelper::IsFolder( const UniString& rURL ) +{ + BOOL bExist = FALSE; + try + { + ::ucbhelper::Content aTestContent( rURL, + uno::Reference< XCommandEnvironment > ()); + bExist = aTestContent.isFolder(); + } + catch(...) + { + } + return bExist; +} + diff --git a/svl/source/misc/inethist.cxx b/svl/source/misc/inethist.cxx new file mode 100644 index 000000000000..290312c0efd8 --- /dev/null +++ b/svl/source/misc/inethist.cxx @@ -0,0 +1,545 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: inethist.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/inethist.hxx> + +#ifndef INCLUDED_ALGORITHM +#include <algorithm> +#define INCLUDED_ALGORITHM +#endif +#include "rtl/instance.hxx" +#include "rtl/crc.h" +#include "rtl/memory.h" +#include <tools/solar.h> +#include <tools/debug.hxx> +#include <tools/string.hxx> +#include <tools/urlobj.hxx> + +/*======================================================================== + * + * INetURLHistory internals. + * + *======================================================================*/ +#define INETHIST_DEF_FTP_PORT 21 +#define INETHIST_DEF_HTTP_PORT 80 +#define INETHIST_DEF_HTTPS_PORT 443 + +#define INETHIST_SIZE_LIMIT 1024 +#define INETHIST_MAGIC_HEAD 0x484D4849UL + +/* + * INetURLHistoryHint implementation. + */ +IMPL_PTRHINT (INetURLHistoryHint, const INetURLObject); + +/*======================================================================== + * + * INetURLHistory_Impl interface. + * + *======================================================================*/ +class INetURLHistory_Impl +{ + /** head_entry. + */ + struct head_entry + { + /** Representation. + */ + UINT32 m_nMagic; + UINT16 m_nNext; + UINT16 m_nMBZ; + + /** Initialization. + */ + void initialize (void) + { + m_nMagic = INETHIST_MAGIC_HEAD; + m_nNext = 0; + m_nMBZ = 0; + } + }; + + /** hash_entry. + */ + struct hash_entry + { + /** Representation. + */ + UINT32 m_nHash; + UINT16 m_nLru; + UINT16 m_nMBZ; + + /** Initialization. + */ + void initialize (UINT16 nLru, UINT32 nHash = 0) + { + m_nHash = nHash; + m_nLru = nLru; + m_nMBZ = 0; + } + + /** Comparison. + */ + BOOL operator== (const hash_entry &rOther) const + { + return (m_nHash == rOther.m_nHash); + } + BOOL operator< (const hash_entry &rOther) const + { + return (m_nHash < rOther.m_nHash); + } + + BOOL operator== (UINT32 nHash) const + { + return (m_nHash == nHash); + } + BOOL operator< (UINT32 nHash) const + { + return (m_nHash < nHash); + } + }; + + /** lru_entry. + */ + struct lru_entry + { + /** Representation. + */ + UINT32 m_nHash; + UINT16 m_nNext; + UINT16 m_nPrev; + + /** Initialization. + */ + void initialize (UINT16 nThis, UINT32 nHash = 0) + { + m_nHash = nHash; + m_nNext = nThis; + m_nPrev = nThis; + } + }; + + /** Representation. + */ + head_entry m_aHead; + hash_entry m_pHash[INETHIST_SIZE_LIMIT]; + lru_entry m_pList[INETHIST_SIZE_LIMIT]; + + /** Initialization. + */ + void initialize (void); + + void downheap (hash_entry a[], UINT16 n, UINT16 k); + void heapsort (hash_entry a[], UINT16 n); + + /** capacity. + */ + UINT16 capacity (void) const + { + return (UINT16)(INETHIST_SIZE_LIMIT); + } + + /** crc32. + */ + UINT32 crc32 (UniString const & rData) const + { + return rtl_crc32 (0, rData.GetBuffer(), rData.Len() * sizeof(sal_Unicode)); + } + + /** find. + */ + UINT16 find (UINT32 nHash) const; + + /** move. + */ + void move (UINT16 nSI, UINT16 nDI); + + /** backlink. + */ + void backlink (UINT16 nThis, UINT16 nTail) + { + register lru_entry &rThis = m_pList[nThis]; + register lru_entry &rTail = m_pList[nTail]; + + rTail.m_nNext = nThis; + rTail.m_nPrev = rThis.m_nPrev; + rThis.m_nPrev = nTail; + m_pList[rTail.m_nPrev].m_nNext = nTail; + } + + /** unlink. + */ + void unlink (UINT16 nThis) + { + register lru_entry &rThis = m_pList[nThis]; + + m_pList[rThis.m_nPrev].m_nNext = rThis.m_nNext; + m_pList[rThis.m_nNext].m_nPrev = rThis.m_nPrev; + rThis.m_nNext = nThis; + rThis.m_nPrev = nThis; + } + + /** Not implemented. + */ + INetURLHistory_Impl (const INetURLHistory_Impl&); + INetURLHistory_Impl& operator= (const INetURLHistory_Impl&); + +public: + INetURLHistory_Impl (void); + ~INetURLHistory_Impl (void); + + /** putUrl/queryUrl. + */ + void putUrl (const String &rUrl); + BOOL queryUrl (const String &rUrl); +}; + +/*======================================================================== + * + * INetURLHistory_Impl implementation. + * + *======================================================================*/ +/* + * INetURLHistory_Impl. + */ +INetURLHistory_Impl::INetURLHistory_Impl (void) +{ + initialize(); +} + +/* + * ~INetURLHistory_Impl. + */ +INetURLHistory_Impl::~INetURLHistory_Impl (void) +{ +} + +/* + * initialize. + */ +void INetURLHistory_Impl::initialize (void) +{ + m_aHead.initialize(); + + USHORT i, n = capacity(); + for (i = 0; i < n; i++) + m_pHash[i].initialize(i); + for (i = 0; i < n; i++) + m_pList[i].initialize(i); + for (i = 1; i < n; i++) + backlink (m_aHead.m_nNext, i); +} + +/* + * downheap. + */ +void INetURLHistory_Impl::downheap (hash_entry a[], UINT16 n, UINT16 k) +{ + hash_entry h = a[k]; + while (k < n / 2) + { + UINT16 i = k + k + 1; + if (((i + 1) < n) && (a[i] < a[i + 1])) i++; + if (!(h < a[i])) break; + a[k] = a[i]; + k = i; + } + a[k] = h; +} + +/* + * heapsort. + */ +void INetURLHistory_Impl::heapsort (hash_entry a[], UINT16 n) +{ + hash_entry h; + + for (UINT16 k = (n - 1) / 2 + 1; k > 0; k--) + downheap (a, n, k - 1); + + while (n > 0) + { + h = a[0 ]; + a[0 ] = a[n - 1]; + a[n - 1] = h; + downheap (a, --n, 0); + } +} + +/* + * find. + */ +UINT16 INetURLHistory_Impl::find (UINT32 nHash) const +{ + UINT16 l = 0; + UINT16 r = capacity() - 1; + UINT16 c = capacity(); + + while ((l < r) && (r < c)) + { + UINT16 m = (l + r) / 2; + if (m_pHash[m] == nHash) + return m; + + if (m_pHash[m] < nHash) + l = m + 1; + else + r = m - 1; + } + return l; +} + +/* + * move. + */ +void INetURLHistory_Impl::move (UINT16 nSI, UINT16 nDI) +{ + hash_entry e = m_pHash[nSI]; + if (nSI < nDI) + { + // shift left. + rtl_moveMemory ( + &m_pHash[nSI ], + &m_pHash[nSI + 1], + (nDI - nSI) * sizeof(hash_entry)); + } + if (nSI > nDI) + { + // shift right. + rtl_moveMemory ( + &m_pHash[nDI + 1], + &m_pHash[nDI ], + (nSI - nDI) * sizeof(hash_entry)); + } + m_pHash[nDI] = e; +} + +/* + * putUrl. + */ +void INetURLHistory_Impl::putUrl (const String &rUrl) +{ + UINT32 h = crc32 (rUrl); + UINT16 k = find (h); + if ((k < capacity()) && (m_pHash[k] == h)) + { + // Cache hit. + UINT16 nMRU = m_pHash[k].m_nLru; + if (nMRU != m_aHead.m_nNext) + { + // Update LRU chain. + unlink (nMRU); + backlink (m_aHead.m_nNext, nMRU); + + // Rotate LRU chain. + m_aHead.m_nNext = m_pList[m_aHead.m_nNext].m_nPrev; + } + } + else + { + // Cache miss. Obtain least recently used. + UINT16 nLRU = m_pList[m_aHead.m_nNext].m_nPrev; + + UINT16 nSI = find (m_pList[nLRU].m_nHash); + if (!(nLRU == m_pHash[nSI].m_nLru)) + { + // Update LRU chain. + nLRU = m_pHash[nSI].m_nLru; + unlink (nLRU); + backlink (m_aHead.m_nNext, nLRU); + } + + // Rotate LRU chain. + m_aHead.m_nNext = m_pList[m_aHead.m_nNext].m_nPrev; + + // Check source and destination. + UINT16 nDI = std::min (k, UINT16(capacity() - 1)); + if (nSI < nDI) + { + if (!(m_pHash[nDI] < h)) + nDI -= 1; + } + if (nDI < nSI) + { + if (m_pHash[nDI] < h) + nDI += 1; + } + + // Assign data. + m_pList[m_aHead.m_nNext].m_nHash = m_pHash[nSI].m_nHash = h; + move (nSI, nDI); + } +} + +/* + * queryUrl. + */ +BOOL INetURLHistory_Impl::queryUrl (const String &rUrl) +{ + UINT32 h = crc32 (rUrl); + UINT16 k = find (h); + if ((k < capacity()) && (m_pHash[k] == h)) + { + // Cache hit. + return TRUE; + } + else + { + // Cache miss. + return FALSE; + } +} + +/*======================================================================== + * + * INetURLHistory::StaticInstance implementation. + * + *======================================================================*/ +INetURLHistory * INetURLHistory::StaticInstance::operator ()() +{ + static INetURLHistory g_aInstance; + return &g_aInstance; +} + +/*======================================================================== + * + * INetURLHistory implementation. + * + *======================================================================*/ +/* + * INetURLHistory. + */ +INetURLHistory::INetURLHistory() : m_pImpl (new INetURLHistory_Impl()) +{ +} + +/* + * ~INetURLHistory. + */ +INetURLHistory::~INetURLHistory() +{ + DELETEZ (m_pImpl); +} + +/* + * GetOrCreate. + */ +INetURLHistory* INetURLHistory::GetOrCreate() +{ + return rtl_Instance< + INetURLHistory, StaticInstance, + osl::MutexGuard, osl::GetGlobalMutex >::create ( + StaticInstance(), osl::GetGlobalMutex()); +} + +/* + * NormalizeUrl_Impl. + */ +void INetURLHistory::NormalizeUrl_Impl (INetURLObject &rUrl) +{ + switch (rUrl.GetProtocol()) + { + case INET_PROT_FILE: + if (!rUrl.IsCaseSensitive()) + { + String aPath (rUrl.GetURLPath(INetURLObject::NO_DECODE)); + aPath.ToLowerAscii(); + rUrl.SetURLPath (aPath, INetURLObject::NOT_CANONIC); + } + break; + + case INET_PROT_FTP: + if (!rUrl.HasPort()) + rUrl.SetPort (INETHIST_DEF_FTP_PORT); + break; + + case INET_PROT_HTTP: + if (!rUrl.HasPort()) + rUrl.SetPort (INETHIST_DEF_HTTP_PORT); + if (!rUrl.HasURLPath()) + rUrl.SetURLPath ("/"); + break; + + case INET_PROT_HTTPS: + if (!rUrl.HasPort()) + rUrl.SetPort (INETHIST_DEF_HTTPS_PORT); + if (!rUrl.HasURLPath()) + rUrl.SetURLPath ("/"); + break; + + default: + break; + } +} + +/* + * PutUrl_Impl. + */ +void INetURLHistory::PutUrl_Impl (const INetURLObject &rUrl) +{ + DBG_ASSERT (m_pImpl, "PutUrl_Impl(): no Implementation"); + if (m_pImpl) + { + INetURLObject aHistUrl (rUrl); + NormalizeUrl_Impl (aHistUrl); + + m_pImpl->putUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); + Broadcast (INetURLHistoryHint (&rUrl)); + + if (aHistUrl.HasMark()) + { + aHistUrl.SetURL (aHistUrl.GetURLNoMark(INetURLObject::NO_DECODE), + INetURLObject::NOT_CANONIC); + + m_pImpl->putUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); + Broadcast (INetURLHistoryHint (&aHistUrl)); + } + } +} + +/* + * QueryUrl_Impl. + */ +BOOL INetURLHistory::QueryUrl_Impl (const INetURLObject &rUrl) +{ + DBG_ASSERT (m_pImpl, "QueryUrl_Impl(): no Implementation"); + if (m_pImpl) + { + INetURLObject aHistUrl (rUrl); + NormalizeUrl_Impl (aHistUrl); + + return m_pImpl->queryUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); + } + return FALSE; +} + + diff --git a/svl/source/misc/inettype.cxx b/svl/source/misc/inettype.cxx new file mode 100644 index 000000000000..47183be1d7b2 --- /dev/null +++ b/svl/source/misc/inettype.cxx @@ -0,0 +1,1348 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: inettype.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/table.hxx> +#include <tools/wldcrd.hxx> +#include <svl/inettype.hxx> +#include <svl/svldata.hxx> +#ifndef _SVTOOLS_HRC +#include <svl/svtools.hrc> +#endif + +#ifndef _SVSTDARR_STRINGSSORT_DECL +#define _SVSTDARR_STRINGSSORT +#include <svl/svstdarr.hxx> +#undef _SVSTDARR_STRINGSSORT +#endif + +namespace unnamed_svl_inettype {} +using namespace unnamed_svl_inettype; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svl_inettype { + +//============================================================================ +struct MediaTypeEntry +{ + sal_Char const * m_pTypeName; + INetContentType m_eTypeID; + sal_Char const * m_pExtension; +}; + +//============================================================================ +struct TypeIDMapEntry +{ + UniString m_aTypeName; + UniString m_aPresentation; + UniString m_aSystemFileType; +}; + +//============================================================================ +struct TypeNameMapEntry: public UniString +{ + UniString m_aExtension; + INetContentType m_eTypeID; + + TypeNameMapEntry(const UniString & rType): + UniString(rType), m_eTypeID(CONTENT_TYPE_UNKNOWN) {} +}; + +//============================================================================ +struct ExtensionMapEntry: public UniString +{ + INetContentType m_eTypeID; + + ExtensionMapEntry(const UniString & rExt): + UniString(rExt), m_eTypeID(CONTENT_TYPE_UNKNOWN) {} +}; + +//============================================================================ +class Registration +{ + static Registration * m_pRegistration; + + Table m_aTypeIDMap; // map TypeID to TypeName, Presentation + SvStringsSort m_aTypeNameMap; // map TypeName to TypeID, Extension + SvStringsSort m_aExtensionMap; // map Extension to TypeID + sal_uInt32 m_nNextDynamicID; + +public: + Registration(): m_nNextDynamicID(CONTENT_TYPE_LAST + 1) {} + + ~Registration(); + + static inline void deinitialize(); + + static inline TypeIDMapEntry * getEntry(INetContentType eTypeID); + + static TypeNameMapEntry * getExtensionEntry(UniString const & rTypeName); + + static INetContentType RegisterContentType(UniString const & rTypeName, + UniString const & + rPresentation, + UniString const * pExtension, + UniString const * + pSystemFileType); + + static INetContentType GetContentType(UniString const & rTypeName); + + static UniString GetContentType(INetContentType eTypeID); + + static UniString GetPresentation(INetContentType eTypeID); + + static UniString GetExtension(const UniString & rTypeName); + + static INetContentType GetContentType4Extension(UniString const & + rExtension); + +}; + +// static +inline void Registration::deinitialize() +{ + delete m_pRegistration; + m_pRegistration = 0; +} + +// static +inline TypeIDMapEntry * Registration::getEntry(INetContentType eTypeID) +{ + return + m_pRegistration ? + static_cast< TypeIDMapEntry * >(m_pRegistration-> + m_aTypeIDMap.Get(eTypeID)) : + 0; +} + +//============================================================================ +MediaTypeEntry const * seekEntry(UniString const & rTypeName, + MediaTypeEntry const * pMap, sal_Size nSize); + +//============================================================================ +/** A mapping from type names to type ids and extensions. Sorted by type + name. + */ +MediaTypeEntry const aStaticTypeNameMap[CONTENT_TYPE_LAST + 1] + = { { " ", CONTENT_TYPE_UNKNOWN, "" }, + { CONTENT_TYPE_STR_X_CNT_DOCUMENT, CONTENT_TYPE_X_CNT_DOCUMENT, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSBOX, CONTENT_TYPE_X_CNT_FSYSBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDROM_VOLUME, + CONTENT_TYPE_X_CNT_CDROM_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_DISK_35, CONTENT_TYPE_X_CNT_DISK_35, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_DISK_525, CONTENT_TYPE_X_CNT_DISK_525, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSFILE, CONTENT_TYPE_X_CNT_FSYSFILE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FIXED_VOLUME, + CONTENT_TYPE_X_CNT_FIXED_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSFOLDER, CONTENT_TYPE_X_CNT_FSYSFOLDER, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_RAM_VOLUME, CONTENT_TYPE_X_CNT_RAM_VOLUME, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_REMOTE_VOLUME, + CONTENT_TYPE_X_CNT_REMOTE_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_REMOVEABLE_VOLUME, + CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFILE, + CONTENT_TYPE_X_CNT_FSYSSPECIALFILE, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFOLDER, + CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_TAPEDRIVE, CONTENT_TYPE_X_CNT_TAPEDRIVE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSURLFILE, CONTENT_TYPE_X_CNT_FSYSURLFILE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPBOX, CONTENT_TYPE_X_CNT_FTPBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPFILE, CONTENT_TYPE_X_CNT_FTPFILE, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPFOLDER, CONTENT_TYPE_X_CNT_FTPFOLDER, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPLINK, CONTENT_TYPE_X_CNT_FTPLINK, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_HTTPBOX, CONTENT_TYPE_X_CNT_HTTPBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_HTTPFILE, CONTENT_TYPE_X_CNT_HTTPFILE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_IMAPBOX, CONTENT_TYPE_X_CNT_IMAPBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_IMAPFOLDER, CONTENT_TYPE_X_CNT_IMAPFOLDER, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_MESSAGE, CONTENT_TYPE_X_CNT_MESSAGE, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_NEWSBOX, CONTENT_TYPE_X_CNT_NEWSBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_NEWSGROUP, CONTENT_TYPE_X_CNT_NEWSGROUP, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_OUTBOX, CONTENT_TYPE_X_CNT_OUTBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_POP3BOX, CONTENT_TYPE_X_CNT_POP3BOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_PUBLISHBOX, CONTENT_TYPE_X_CNT_PUBLISHBOX, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_SEARCHBOX, CONTENT_TYPE_X_CNT_SEARCHBOX, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_SEPARATOR, CONTENT_TYPE_X_CNT_SEPARATOR, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_BOOKMARK, CONTENT_TYPE_X_CNT_BOOKMARK, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_SUBSCRIBEBOX, + CONTENT_TYPE_X_CNT_SUBSCRIBEBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDF, CONTENT_TYPE_X_CNT_CDF, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDFITEM, CONTENT_TYPE_X_CNT_CDFITEM, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDFSUB, CONTENT_TYPE_X_CNT_CDFSUB, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_STARCHANNEL, CONTENT_TYPE_X_CNT_STARCHANNEL, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_TRASHBOX, CONTENT_TYPE_X_CNT_TRASHBOX, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_TRASH, CONTENT_TYPE_X_CNT_TRASH, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMBBOARD, CONTENT_TYPE_X_CNT_VIMBBOARD, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMBBOARDBOX, + CONTENT_TYPE_X_CNT_VIMBBOARDBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMBOX, CONTENT_TYPE_X_CNT_VIMBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMINBOX, CONTENT_TYPE_X_CNT_VIMINBOX, + "tmp" }, + { CONTENT_TYPE_STR_APP_OCTSTREAM, CONTENT_TYPE_APP_OCTSTREAM, "tmp" }, + { CONTENT_TYPE_STR_APP_PDF, CONTENT_TYPE_APP_PDF, "pdf" }, + { CONTENT_TYPE_STR_APP_RTF, CONTENT_TYPE_APP_RTF, "rtf" }, + { CONTENT_TYPE_STR_APP_VND_CALC, CONTENT_TYPE_APP_VND_CALC, "sdc" }, + { CONTENT_TYPE_STR_APP_VND_CHART, CONTENT_TYPE_APP_VND_CHART, "sds" }, + { CONTENT_TYPE_STR_APP_VND_DRAW, CONTENT_TYPE_APP_VND_DRAW, "sda" }, + { CONTENT_TYPE_STR_APP_VND_IMAGE, CONTENT_TYPE_APP_VND_IMAGE, "sim" }, + { CONTENT_TYPE_STR_APP_VND_IMPRESS, CONTENT_TYPE_APP_VND_IMPRESS, + "sdd" }, + { CONTENT_TYPE_STR_APP_VND_IMPRESSPACKED, + CONTENT_TYPE_APP_VND_IMPRESSPACKED, "sdp" }, + { CONTENT_TYPE_STR_APP_VND_MAIL, CONTENT_TYPE_APP_VND_MAIL, "sdm" }, + { CONTENT_TYPE_STR_APP_VND_MATH, CONTENT_TYPE_APP_VND_MATH, "smf" }, + { CONTENT_TYPE_STR_APP_VND_NEWS, CONTENT_TYPE_APP_VND_NEWS, "sdm" }, + { CONTENT_TYPE_STR_APP_VND_OUTTRAY, CONTENT_TYPE_APP_VND_OUTTRAY, + "sdm" }, + { CONTENT_TYPE_STR_APP_VND_TEMPLATE, CONTENT_TYPE_APP_VND_TEMPLATE, + "vor" }, + { CONTENT_TYPE_STR_APP_VND_WRITER, CONTENT_TYPE_APP_VND_WRITER, + "sdw" }, + { CONTENT_TYPE_STR_APP_VND_WRITER_GLOBAL, + CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "sgl" }, + { CONTENT_TYPE_STR_APP_VND_WRITER_WEB, + CONTENT_TYPE_APP_VND_WRITER_WEB, "htm" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_CALC, CONTENT_TYPE_APP_VND_SUN_XML_CALC, "sxc" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_CHART, CONTENT_TYPE_APP_VND_SUN_XML_CHART, "sxs" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_DRAW, CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "sxd" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESS, CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "sxi" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESSPACKED, CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, "sxp" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_MATH, CONTENT_TYPE_APP_VND_SUN_XML_MATH, "sxm" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER, CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "sxw" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER_GLOBAL, CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, "sxg" }, + { CONTENT_TYPE_STR_APP_FRAMESET, CONTENT_TYPE_APP_FRAMESET, "sfs" }, + { CONTENT_TYPE_STR_APP_GALLERY, CONTENT_TYPE_APP_GALLERY, "gal" }, + { CONTENT_TYPE_STR_APP_GALLERY_THEME, CONTENT_TYPE_APP_GALLERY_THEME, + "thm" }, + { CONTENT_TYPE_STR_APP_JAR, CONTENT_TYPE_APP_JAR, "jar" }, + { CONTENT_TYPE_STR_APP_MACRO, CONTENT_TYPE_APP_MACRO, "tmp" }, + { CONTENT_TYPE_STR_APP_MSEXCEL, CONTENT_TYPE_APP_MSEXCEL, "xls" }, + { CONTENT_TYPE_STR_APP_MSEXCEL_TEMPL, CONTENT_TYPE_APP_MSEXCEL_TEMPL, + "xlt" }, + { CONTENT_TYPE_STR_APP_MSPPOINT, CONTENT_TYPE_APP_MSPPOINT, "ppt" }, + { CONTENT_TYPE_STR_APP_MSPPOINT_TEMPL, + CONTENT_TYPE_APP_MSPPOINT_TEMPL, "pot" }, + { CONTENT_TYPE_STR_APP_MSWORD, CONTENT_TYPE_APP_MSWORD, "doc" }, + { CONTENT_TYPE_STR_APP_MSWORD_TEMPL, CONTENT_TYPE_APP_MSWORD_TEMPL, + "dot" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_CMB, CONTENT_TYPE_APP_SCHEDULE, + "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_EVT, CONTENT_TYPE_APP_SCHEDULE_EVT, + "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_FEVT, + CONTENT_TYPE_APP_SCHEDULE_FORM_EVT, "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_FTASK, + CONTENT_TYPE_APP_SCHEDULE_FORM_TASK, "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_TASK, CONTENT_TYPE_APP_SCHEDULE_TASK, + "tmp" }, + { CONTENT_TYPE_STR_APP_STARCALC, CONTENT_TYPE_APP_STARCALC, "sdc" }, + { CONTENT_TYPE_STR_APP_STARCHART, CONTENT_TYPE_APP_STARCHART, "sds" }, + { CONTENT_TYPE_STR_APP_STARDRAW, CONTENT_TYPE_APP_STARDRAW, "sda" }, + { CONTENT_TYPE_STR_APP_STARHELP, CONTENT_TYPE_APP_STARHELP, "svh" }, + { CONTENT_TYPE_STR_APP_STARIMAGE, CONTENT_TYPE_APP_STARIMAGE, "sim" }, + { CONTENT_TYPE_STR_APP_STARIMPRESS, CONTENT_TYPE_APP_STARIMPRESS, + "sdd" }, + { CONTENT_TYPE_STR_APP_STARMAIL_SDM, CONTENT_TYPE_APP_STARMAIL_SDM, + "sdm" }, + { CONTENT_TYPE_STR_APP_STARMAIL_SMD, CONTENT_TYPE_APP_STARMAIL_SMD, + "smd" }, + { CONTENT_TYPE_STR_APP_STARMATH, CONTENT_TYPE_APP_STARMATH, "smf" }, + { CONTENT_TYPE_STR_APP_STARWRITER, CONTENT_TYPE_APP_STARWRITER, + "sdw" }, + { CONTENT_TYPE_STR_APP_STARWRITER_GLOB, + CONTENT_TYPE_APP_STARWRITER_GLOB, "sgl" }, + { CONTENT_TYPE_STR_APP_CDE_CALENDAR_APP, + CONTENT_TYPE_APP_CDE_CALENDAR_APP, "appt" }, + { CONTENT_TYPE_STR_APP_ZIP, CONTENT_TYPE_APP_ZIP, "zip" }, + { CONTENT_TYPE_STR_AUDIO_AIFF, CONTENT_TYPE_AUDIO_AIFF, "aif" }, + { CONTENT_TYPE_STR_AUDIO_BASIC, CONTENT_TYPE_AUDIO_BASIC, "au" }, + { CONTENT_TYPE_STR_AUDIO_MIDI, CONTENT_TYPE_AUDIO_MIDI, "mid" }, + { CONTENT_TYPE_STR_AUDIO_WAV, CONTENT_TYPE_AUDIO_WAV, "wav" }, + { CONTENT_TYPE_STR_IMAGE_GENERIC, CONTENT_TYPE_IMAGE_GENERIC, "tmp" }, + { CONTENT_TYPE_STR_IMAGE_GIF, CONTENT_TYPE_IMAGE_GIF, "gif" }, + { CONTENT_TYPE_STR_IMAGE_JPEG, CONTENT_TYPE_IMAGE_JPEG, "jpg" }, + { CONTENT_TYPE_STR_IMAGE_PCX, CONTENT_TYPE_IMAGE_PCX, "pcx" }, + { CONTENT_TYPE_STR_IMAGE_PNG, CONTENT_TYPE_IMAGE_PNG, "png" }, + { CONTENT_TYPE_STR_IMAGE_TIFF, CONTENT_TYPE_IMAGE_TIFF, "tif" }, + { CONTENT_TYPE_STR_IMAGE_BMP, CONTENT_TYPE_IMAGE_BMP, "bmp" }, + { CONTENT_TYPE_STR_INET_MSG_RFC822, CONTENT_TYPE_INET_MESSAGE_RFC822, + "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_ALTERNATIVE, + CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_DIGEST, + CONTENT_TYPE_INET_MULTIPART_DIGEST, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_MIXED, + CONTENT_TYPE_INET_MULTIPART_MIXED, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_PARALLEL, + CONTENT_TYPE_INET_MULTIPART_PARALLEL, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_RELATED, + CONTENT_TYPE_INET_MULTIPART_RELATED, "tmp" }, + { CONTENT_TYPE_STR_TEXT_ICALENDAR, CONTENT_TYPE_TEXT_ICALENDAR, + "ics" }, + { CONTENT_TYPE_STR_TEXT_HTML, CONTENT_TYPE_TEXT_HTML, "htm" }, + { CONTENT_TYPE_STR_TEXT_PLAIN, CONTENT_TYPE_TEXT_PLAIN, "txt" }, + { CONTENT_TYPE_STR_TEXT_XMLICALENDAR, CONTENT_TYPE_TEXT_XMLICALENDAR, + "xcs" }, + { CONTENT_TYPE_STR_TEXT_URL, CONTENT_TYPE_TEXT_URL, "url" }, + { CONTENT_TYPE_STR_TEXT_VCALENDAR, CONTENT_TYPE_TEXT_VCALENDAR, + "vcs" }, + { CONTENT_TYPE_STR_TEXT_VCARD, CONTENT_TYPE_TEXT_VCARD, "vcf" }, + { CONTENT_TYPE_STR_VIDEO_VDO, CONTENT_TYPE_VIDEO_VDO, "vdo" }, + { CONTENT_TYPE_STR_VIDEO_MSVIDEO, CONTENT_TYPE_VIDEO_MSVIDEO, "avi" }, + { CONTENT_TYPE_STR_X_STARMAIL, CONTENT_TYPE_X_STARMAIL, "smd" }, + { CONTENT_TYPE_STR_X_VRML, CONTENT_TYPE_X_VRML, "wrl" } +}; + +//============================================================================ +/** A mapping from type IDs to presentation resource IDs. Sorted by type ID. + */ +USHORT const aStaticResourceIDMap[CONTENT_TYPE_LAST + 1] + = { STR_SVT_MIMETYPE_APP_OCTSTREAM, // CONTENT_TYPE_UNKNOWN + STR_SVT_MIMETYPE_APP_OCTSTREAM, // CONTENT_TYPE_APP_OCTSTREAM + STR_SVT_MIMETYPE_APP_PDF, // CONTENT_TYPE_APP_PDF + STR_SVT_MIMETYPE_APP_RTF, // CONTENT_TYPE_APP_RTF + STR_SVT_MIMETYPE_APP_MSWORD, // CONTENT_TYPE_APP_MSWORD + STR_SVT_MIMETYPE_APP_MSWORD, // CONTENT_TYPE_APP_MSWORD_TEMPL //@todo new presentation string? + STR_SVT_MIMETYPE_APP_STARCALC, // CONTENT_TYPE_APP_STARCALC + STR_SVT_MIMETYPE_APP_STARCHART, // CONTENT_TYPE_APP_STARCHART + STR_SVT_MIMETYPE_APP_STARDRAW, // CONTENT_TYPE_APP_STARDRAW + STR_SVT_MIMETYPE_APP_STARHELP, // CONTENT_TYPE_APP_STARHELP + STR_SVT_MIMETYPE_APP_STARIMAGE, // CONTENT_TYPE_APP_STARIMAGE + STR_SVT_MIMETYPE_APP_STARIMPRESS, // CONTENT_TYPE_APP_STARIMPRESS + STR_SVT_MIMETYPE_APP_STARMATH, // CONTENT_TYPE_APP_STARMATH + STR_SVT_MIMETYPE_APP_STARWRITER, // CONTENT_TYPE_APP_STARWRITER + STR_SVT_MIMETYPE_APP_ZIP, // CONTENT_TYPE_APP_ZIP + STR_SVT_MIMETYPE_AUDIO_AIFF, // CONTENT_TYPE_AUDIO_AIFF + STR_SVT_MIMETYPE_AUDIO_BASIC, // CONTENT_TYPE_AUDIO_BASIC + STR_SVT_MIMETYPE_AUDIO_MIDI, // CONTENT_TYPE_AUDIO_MIDI + STR_SVT_MIMETYPE_AUDIO_WAV, // CONTENT_TYPE_AUDIO_WAV + STR_SVT_MIMETYPE_IMAGE_GIF, // CONTENT_TYPE_IMAGE_GIF + STR_SVT_MIMETYPE_IMAGE_JPEG, // CONTENT_TYPE_IMAGE_JPEG + STR_SVT_MIMETYPE_IMAGE_PCX, // CONTENT_TYPE_IMAGE_PCX + STR_SVT_MIMETYPE_IMAGE_PNG, // CONTENT_TYPE_IMAGE_PNG + STR_SVT_MIMETYPE_IMAGE_TIFF, // CONTENT_TYPE_IMAGE_TIFF + STR_SVT_MIMETYPE_IMAGE_BMP, // CONTENT_TYPE_IMAGE_BMP + STR_SVT_MIMETYPE_TEXT_HTML, // CONTENT_TYPE_TEXT_HTML + STR_SVT_MIMETYPE_TEXT_PLAIN, // CONTENT_TYPE_TEXT_PLAIN + STR_SVT_MIMETYPE_TEXT_URL, // CONTENT_TYPE_TEXT_URL + STR_SVT_MIMETYPE_TEXT_VCARD, // CONTENT_TYPE_TEXT_VCARD + STR_SVT_MIMETYPE_VIDEO_VDO, // CONTENT_TYPE_VIDEO_VDO + STR_SVT_MIMETYPE_VIDEO_MSVIDEO, // CONTENT_TYPE_VIDEO_MSVIDEO + STR_SVT_MIMETYPE_CNT_MSG, // CONTENT_TYPE_X_CNT_MESSAGE + STR_SVT_MIMETYPE_CNT_DOCUMENT, // CONTENT_TYPE_X_CNT_DOCUMENT + STR_SVT_MIMETYPE_CNT_POP3BOX, // CONTENT_TYPE_X_CNT_POP3BOX + STR_SVT_MIMETYPE_CNT_IMAPBOX, // CONTENT_TYPE_X_CNT_IMAPBOX + STR_SVT_MIMETYPE_CNT_IMAPFLD, // CONTENT_TYPE_X_CNT_IMAPFOLDER + STR_SVT_MIMETYPE_CNT_VIMBOX, // CONTENT_TYPE_X_CNT_VIMBOX + STR_SVT_MIMETYPE_CNT_VIMINBOX, // CONTENT_TYPE_X_CNT_VIMINBOX + STR_SVT_MIMETYPE_CNT_BBBOX, // CONTENT_TYPE_X_CNT_VIMBBOARDBOX + STR_SVT_MIMETYPE_CNT_VIM_BB, // CONTENT_TYPE_X_CNT_VIMBBOARD + STR_SVT_MIMETYPE_CNT_NEWSBOX, // CONTENT_TYPE_X_CNT_NEWSBOX + STR_SVT_MIMETYPE_CNT_NEWSGRP, // CONTENT_TYPE_X_CNT_NEWSGROUP + STR_SVT_MIMETYPE_CNT_OUTBOX, // CONTENT_TYPE_X_CNT_OUTBOX + STR_SVT_MIMETYPE_CNT_FTPBOX, // CONTENT_TYPE_X_CNT_FTPBOX + STR_SVT_MIMETYPE_CNT_FTPFLD, // CONTENT_TYPE_X_CNT_FTPFOLDER + STR_SVT_MIMETYPE_CNT_FTPFILE, // CONTENT_TYPE_X_CNT_FTPFILE + STR_SVT_MIMETYPE_CNT_FTPLINK, // CONTENT_TYPE_X_CNT_FTPLINK + STR_SVT_MIMETYPE_CNT_HTTPBOX, // CONTENT_TYPE_X_CNT_HTTPBOX + STR_SVT_MIMETYPE_CNT_FSYSBOX, // CONTENT_TYPE_X_CNT_FSYSBOX + STR_SVT_MIMETYPE_CNT_FSYSFLD, // CONTENT_TYPE_X_CNT_FSYSFOLDER + STR_SVT_MIMETYPE_CNT_FSYSFILE, // CONTENT_TYPE_X_CNT_FSYSFILE + STR_SVT_MIMETYPE_CNT_FSYSURLFILE, // CONTENT_TYPE_X_CNT_FSYSURLFILE + STR_SVT_MIMETYPE_CNT_PUBLBOX, // CONTENT_TYPE_X_CNT_PUBLISHBOX + STR_SVT_MIMETYPE_CNT_SRCHBOX, // CONTENT_TYPE_X_CNT_SEARCHBOX + STR_SVT_MIMETYPE_CNT_SUBSCRBOX, // CONTENT_TYPE_X_CNT_SUBSCRIBEBOX + STR_SVT_MIMETYPE_CNT_BOOKMARK, // CONTENT_TYPE_X_CNT_BOOKMARK + STR_SVT_MIMETYPE_CNT_CDF, // CONTENT_TYPE_X_CNT_CDF + STR_SVT_MIMETYPE_CNT_CDFSUB, // CONTENT_TYPE_X_CNT_CDFSUB + STR_SVT_MIMETYPE_CNT_CDFITEM, // CONTENT_TYPE_X_CNT_CDFITEM + STR_SVT_MIMETYPE_CNT_TRASHBOX, // CONTENT_TYPE_X_CNT_TRASHBOX + STR_SVT_MIMETYPE_CNT_TRASH, // CONTENT_TYPE_X_CNT_TRASH + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_X_STARMAIL + STR_SVT_MIMETYPE_X_VRML, // CONTENT_TYPE_X_VRML + STR_SVT_MIMETYPE_CNT_REMOV_VOL, + // CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME + STR_SVT_MIMETYPE_CNT_FIX_VOL, // CONTENT_TYPE_X_CNT_FIXED_VOLUME + STR_SVT_MIMETYPE_CNT_REM_VOL, // CONTENT_TYPE_X_CNT_REMOTE_VOLUME + STR_SVT_MIMETYPE_CNT_RAM_VOL, // CONTENT_TYPE_X_CNT_RAM_VOLUME + STR_SVT_MIMETYPE_CNT_CDROM, // CONTENT_TYPE_X_CNT_CDROM_VOLUME + STR_SVT_MIMETYPE_CNT_DISK_35, // CONTENT_TYPE_X_CNT_DISK_35 + STR_SVT_MIMETYPE_CNT_DISK_525, // CONTENT_TYPE_X_CNT_DISK_525 + STR_SVT_MIMETYPE_CNT_TAPEDRIVE, // CONTENT_TYPE_X_CNT_TAPEDRIVE + STR_SVT_MIMETYPE_APP_GAL, // CONTENT_TYPE_APP_GALLERY + STR_SVT_MIMETYPE_APP_GAL_THEME, // CONTENT_TYPE_APP_GALLERY_THEME + STR_SVT_MIMETYPE_CNT_STARCHANNEL, // CONTENT_TYPE_X_CNT_STARCHANNEL + STR_SVT_MIMETYPE_CNT_SEPARATOR, // CONTENT_TYPE_X_CNT_SEPARATOR + STR_SVT_MIMETYPE_APP_STARW_GLOB, // CONTENT_TYPE_APP_STARWRITER_GLOB + STR_SVT_MIMETYPE_APP_SDM, // CONTENT_TYPE_APP_STARMAIL_SDM + STR_SVT_MIMETYPE_APP_SMD, // CONTENT_TYPE_APP_STARMAIL_SMD + STR_SVT_MIMETYPE_APP_STARCALC, // CONTENT_TYPE_APP_VND_CALC + STR_SVT_MIMETYPE_APP_STARCHART, // CONTENT_TYPE_APP_VND_CHART + STR_SVT_MIMETYPE_APP_STARDRAW, // CONTENT_TYPE_APP_VND_DRAW + STR_SVT_MIMETYPE_APP_STARIMAGE, // CONTENT_TYPE_APP_VND_IMAGE + STR_SVT_MIMETYPE_APP_STARIMPRESS, // CONTENT_TYPE_APP_VND_IMPRESS + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_MAIL + STR_SVT_MIMETYPE_APP_STARMATH, // CONTENT_TYPE_APP_VND_MATH + STR_SVT_MIMETYPE_APP_STARWRITER, // CONTENT_TYPE_APP_VND_WRITER + STR_SVT_MIMETYPE_APP_STARW_GLOB, // CONTENT_TYPE_APP_VND_WRITER_GLOBAL + STR_SVT_MIMETYPE_APP_STARW_WEB, // CONTENT_TYPE_APP_VND_WRITER_WEB + STR_SVT_MIMETYPE_SCHEDULE, // CONTENT_TYPE_APP_SCHEDULE + STR_SVT_MIMETYPE_SCHEDULE_EVT, // CONTENT_TYPE_APP_SCHEDULE_EVT + STR_SVT_MIMETYPE_SCHEDULE_TASK, // CONTENT_TYPE_APP_SCHEDULE_TASK + STR_SVT_MIMETYPE_SCHEDULE_FEVT, // CONTENT_TYPE_APP_SCHEDULE_FORM_EVT + STR_SVT_MIMETYPE_SCHEDULE_FTASK, + // CONTENT_TYPE_APP_SCHEDULE_FORM_TASK + STR_SVT_MIMETYPE_FRAMESET, // CONTENT_TYPE_APP_FRAMESET + STR_SVT_MIMETYPE_MACRO, // CONTENT_TYPE_APP_MACRO + STR_SVT_MIMETYPE_CNT_SFSYSFOLDER, + // CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER + STR_SVT_MIMETYPE_CNT_SFSYSFILE, // CONTENT_TYPE_X_CNT_FSYSSPECIALFILE + STR_SVT_MIMETYPE_APP_TEMPLATE, // CONTENT_TYPE_APP_VND_TEMPLATE + STR_SVT_MIMETYPE_IMAGE_GENERIC, // CONTENT_TYPE_IMAGE_GENERIC + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_NEWS + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_OUTTRAY + STR_SVT_MIMETYPE_TEXT_HTML, // CONTENT_TYPE_X_CNT_HTTPFILE + STR_SVT_MIMETYPE_APP_MSEXCEL, // CONTENT_TYPE_APP_MSEXCEL + STR_SVT_MIMETYPE_APP_MSEXCEL_TEMPL, // CONTENT_TYPE_APP_MSEXCEL_TEMPL + STR_SVT_MIMETYPE_APP_MSPPOINT, // CONTENT_TYPE_APP_MSPPOINT + STR_SVT_MIMETYPE_APP_MSPPOINT, // CONTENT_TYPE_APP_MSPPOINT_TEMPL //@todo new presentation string? + STR_SVT_MIMETYPE_TEXT_VCALENDAR, // CONTENT_TYPE_TEXT_VCALENDAR + STR_SVT_MIMETYPE_TEXT_ICALENDAR, // CONTENT_TYPE_TEXT_ICALENDAR + STR_SVT_MIMETYPE_TEXT_XMLICALENDAR, // CONTENT_TYPE_TEXT_XMLICALENDAR + STR_SVT_MIMETYPE_TEXT_CDE_CALENDAR_APP, + // CONTENT_TYPE_APP_CDE_CALENDAR_APP + STR_SVT_MIMETYPE_INET_MSG_RFC822, // CONTENT_TYPE_INET_MESSAGE_RFC822 + STR_SVT_MIMETYPE_INET_MULTI_ALTERNATIVE, + // CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE + STR_SVT_MIMETYPE_INET_MULTI_DIGEST, + // CONTENT_TYPE_INET_MULTIPART_DIGEST + STR_SVT_MIMETYPE_INET_MULTI_PARALLEL, + // CONTENT_TYPE_INET_MULTIPART_PARALLEL + STR_SVT_MIMETYPE_INET_MULTI_RELATED, + // CONTENT_TYPE_INET_MULTIPART_RELATED + STR_SVT_MIMETYPE_INET_MULTI_MIXED, + // CONTENT_TYPE_INET_MULTIPART_MIXED + STR_SVT_MIMETYPE_APP_IMPRESSPACKED, + // CONTENT_TYPE_APP_VND_IMPRESSPACKED + STR_SVT_MIMETYPE_APP_JAR, // CONTENT_TYPE_APP_JAR + STR_SVT_MIMETYPE_APP_SXWRITER, // CONTENT_TYPE_APP_VND_SUN_XML_WRITER + STR_SVT_MIMETYPE_APP_SXCALC, // CONTENT_TYPE_APP_VND_SUN_XML_CALC + STR_SVT_MIMETYPE_APP_SXIMPRESS, // CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS + STR_SVT_MIMETYPE_APP_SXDRAW, // CONTENT_TYPE_APP_VND_SUN_XML_DRAW + STR_SVT_MIMETYPE_APP_SXCHART, // CONTENT_TYPE_APP_VND_SUN_XML_CHART + STR_SVT_MIMETYPE_APP_SXMATH, // CONTENT_TYPE_APP_VND_SUN_XML_MATH + STR_SVT_MIMETYPE_APP_SXGLOBAL, // CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL + STR_SVT_MIMETYPE_APP_SXIPACKED, // CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED + }; + +//============================================================================ +/** A mapping from extensions to type IDs. Sorted by extension. + */ +MediaTypeEntry const aStaticExtensionMap[] + = { { "aif", CONTENT_TYPE_AUDIO_AIFF, "" }, + { "aiff", CONTENT_TYPE_AUDIO_AIFF, "" }, + { "appt", CONTENT_TYPE_APP_CDE_CALENDAR_APP, "" }, + { "au", CONTENT_TYPE_AUDIO_BASIC, "" }, + { "avi", CONTENT_TYPE_VIDEO_MSVIDEO, "" }, + { "bmp", CONTENT_TYPE_IMAGE_BMP, "" }, + { "cgm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "doc", CONTENT_TYPE_APP_MSWORD, "" }, + { "dot", CONTENT_TYPE_APP_MSWORD_TEMPL, "" }, + { "dxf", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "eps", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "gal", CONTENT_TYPE_APP_GALLERY, "" }, + { "gif", CONTENT_TYPE_IMAGE_GIF, "" }, + { "htm", CONTENT_TYPE_TEXT_HTML, "" }, + { "html", CONTENT_TYPE_TEXT_HTML, "" }, + { "ics", CONTENT_TYPE_TEXT_ICALENDAR, "" }, + { "jar", CONTENT_TYPE_APP_JAR, "" }, + { "jpeg", CONTENT_TYPE_IMAGE_JPEG, "" }, + { "jpg", CONTENT_TYPE_IMAGE_JPEG, "" }, + { "met", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "mid", CONTENT_TYPE_AUDIO_MIDI, "" }, + { "midi", CONTENT_TYPE_AUDIO_MIDI, "" }, + { "pbm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "pcd", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "pct", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "pcx", CONTENT_TYPE_IMAGE_PCX, "" }, + { "pdf", CONTENT_TYPE_APP_PDF, "" }, + { "pgm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "png", CONTENT_TYPE_IMAGE_PNG, "" }, + { "pot", CONTENT_TYPE_APP_MSPPOINT_TEMPL, "" }, + { "ppm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "ppt", CONTENT_TYPE_APP_MSPPOINT, "" }, + { "psd", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "ras", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "rtf", CONTENT_TYPE_APP_RTF, "" }, + { "sda", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "sdc", CONTENT_TYPE_APP_VND_CALC, "" }, + { "sdd", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "sdm", CONTENT_TYPE_APP_VND_MAIL, "" }, + { "sdp", CONTENT_TYPE_APP_VND_IMPRESSPACKED, "" }, + { "sds", CONTENT_TYPE_APP_VND_CHART, "" }, + { "sdw", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "sd~", CONTENT_TYPE_X_STARMAIL, "" }, + { "sfs", CONTENT_TYPE_APP_FRAMESET , "" }, + { "sgl", CONTENT_TYPE_APP_VND_WRITER_GLOBAL , "" }, + { "sim", CONTENT_TYPE_APP_VND_IMAGE, "" }, + { "smd", CONTENT_TYPE_APP_STARMAIL_SMD, "" }, //CONTENT_TYPE_X_STARMAIL + { "smf", CONTENT_TYPE_APP_VND_MATH, "" }, + { "svh", CONTENT_TYPE_APP_STARHELP, "" }, + { "svm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "sxc", CONTENT_TYPE_APP_VND_SUN_XML_CALC, "" }, + { "sxd", CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "" }, + { "sxg", CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, "" }, + { "sxi", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "" }, + { "sxm", CONTENT_TYPE_APP_VND_SUN_XML_MATH, "" }, + { "sxp", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, "" }, + { "sxs", CONTENT_TYPE_APP_VND_SUN_XML_CHART, "" }, + { "sxw", CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "" }, + { "tga", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "thm", CONTENT_TYPE_APP_GALLERY_THEME, "" }, + { "tif", CONTENT_TYPE_IMAGE_TIFF, "" }, + { "tiff", CONTENT_TYPE_IMAGE_TIFF, "" }, + { "txt", CONTENT_TYPE_TEXT_PLAIN, "" }, + { "url", CONTENT_TYPE_TEXT_URL, "" }, + { "vcf", CONTENT_TYPE_TEXT_VCARD, "" }, + { "vcs", CONTENT_TYPE_TEXT_VCALENDAR, "" }, + { "vdo", CONTENT_TYPE_VIDEO_VDO, "" }, + { "vor", CONTENT_TYPE_APP_VND_TEMPLATE, "" }, + { "wav", CONTENT_TYPE_AUDIO_WAV, "" }, + { "wmf", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "wrl", CONTENT_TYPE_X_VRML, "" }, + { "xbm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "xcs", CONTENT_TYPE_TEXT_XMLICALENDAR, "" }, + { "xls", CONTENT_TYPE_APP_MSEXCEL, "" }, + { "xlt", CONTENT_TYPE_APP_MSEXCEL_TEMPL, "" }, + { "xlw", CONTENT_TYPE_APP_MSEXCEL, "" }, + { "xpm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "zip", CONTENT_TYPE_APP_ZIP, "" } }; + +//============================================================================ +/** A mapping from presentations to type IDs. Sorted by presentations. + */ +MediaTypeEntry const aStaticPresentationMap[] + = { { "Binary Data", CONTENT_TYPE_APP_OCTSTREAM, "" }, + { "Bitmap", CONTENT_TYPE_IMAGE_BMP, "" }, + { "DOS Command File", CONTENT_TYPE_APP_OCTSTREAM, "" }, + { "Digital Video", CONTENT_TYPE_VIDEO_MSVIDEO, "" }, + { "Executable", CONTENT_TYPE_APP_OCTSTREAM, "" }, + { "Grafik", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "HTM", CONTENT_TYPE_TEXT_HTML, "" }, + { "HTML", CONTENT_TYPE_TEXT_HTML, "" }, + { "Hypertext", CONTENT_TYPE_TEXT_HTML, "" }, + { "Icon", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "Image File", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "MIDI", CONTENT_TYPE_AUDIO_MIDI, "" }, + { "Master Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "Plain Text", CONTENT_TYPE_TEXT_PLAIN, "" }, + { "StarCalc", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc 3.0", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc 4.0", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc 5.0", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc Datei", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc Document", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc File", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarChart 3.0", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarChart 4.0", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarChart 5.0", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarChart Document", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarDraw 3.0", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarDraw 5.0", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarDraw", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarDraw Document", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarImpress 4.0", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "StarImpress 5.0 (packed)", CONTENT_TYPE_APP_VND_IMPRESSPACKED, "" }, + { "StarImpress 5.0", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "StarImpress Document", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "StarMath 3.0", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMath 4.0", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMath 5.0", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMath Document", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMessage5", CONTENT_TYPE_APP_VND_MAIL, "" }, + { "StarOffice XML (Calc)", CONTENT_TYPE_APP_VND_SUN_XML_CALC, "" }, + { "StarOffice XML (Impress)", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "" }, + { "StarOffice XML (Draw)", CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "" }, + { "StarOffice XML (Chart)", CONTENT_TYPE_APP_VND_SUN_XML_CHART, "" }, + { "StarOffice XML (Writer)", CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "" }, + { "StarWriter", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter 3.0", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter 4.0", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter 5.0", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter Document", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter/Global 5.0", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "StarWriter/Global Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "StarWriter/Web 5.0", CONTENT_TYPE_APP_VND_WRITER_WEB, "" }, + { "StarWriterGlobal Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "StarWriterHtml Document", CONTENT_TYPE_APP_VND_WRITER_WEB, "" }, + { "UniformResourceLocator", CONTENT_TYPE_TEXT_URL, "" }, + { "text/html", CONTENT_TYPE_TEXT_HTML, "" } }; + +} + +//============================================================================ +// +// Registration +// +//============================================================================ + +// static +Registration * Registration::m_pRegistration = 0; + +//============================================================================ +Registration::~Registration() +{ + {for (ULONG i = 0; i < m_aTypeIDMap.Count(); ++i) + delete static_cast< TypeIDMapEntry * >(m_aTypeIDMap.GetObject(i)); + } + m_aTypeIDMap.Clear(); + {for (USHORT i = 0; i < m_aTypeNameMap.Count(); ++i) + delete static_cast< TypeNameMapEntry * >(m_aTypeNameMap.GetObject(i)); + } + m_aTypeNameMap.Remove(USHORT(0), m_aTypeNameMap.Count()); + {for (USHORT i = 0; i < m_aExtensionMap.Count(); ++i) + delete + static_cast< ExtensionMapEntry * >(m_aExtensionMap.GetObject(i)); + } + m_aExtensionMap.Remove(USHORT(0), m_aExtensionMap.Count()); +} + +//============================================================================ +// static +TypeNameMapEntry * Registration::getExtensionEntry(UniString const & + rTypeName) +{ + if (m_pRegistration) + { + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + USHORT nPos; + if (m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos)) + return static_cast< TypeNameMapEntry * >(m_pRegistration-> + m_aTypeNameMap. + GetObject(nPos)); + } + return 0; +} + +//============================================================================ +// static +INetContentType Registration::RegisterContentType(UniString const & rTypeName, + UniString const & + rPresentation, + UniString const * + pExtension, + UniString const * + pSystemFileType) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + DBG_ASSERT(GetContentType(rTypeName) == CONTENT_TYPE_UNKNOWN, + "Registration::RegisterContentType(): Already registered"); + + INetContentType eTypeID + = INetContentType(m_pRegistration->m_nNextDynamicID++); + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + + TypeIDMapEntry * pTypeIDMapEntry = new TypeIDMapEntry; + pTypeIDMapEntry->m_aTypeName = aTheTypeName; + pTypeIDMapEntry->m_aPresentation = rPresentation; + if (pSystemFileType) + pTypeIDMapEntry->m_aSystemFileType = *pSystemFileType; + m_pRegistration->m_aTypeIDMap.Insert(eTypeID, pTypeIDMapEntry); + + TypeNameMapEntry * pTypeNameMapEntry = new TypeNameMapEntry(aTheTypeName); + if (pExtension) + pTypeNameMapEntry->m_aExtension = *pExtension; + pTypeNameMapEntry->m_eTypeID = eTypeID; + m_pRegistration->m_aTypeNameMap.Insert(pTypeNameMapEntry); + + if (pExtension) + { + ExtensionMapEntry * pExtensionMapEntry + = new ExtensionMapEntry(*pExtension); + pExtensionMapEntry->m_eTypeID = eTypeID; + m_pRegistration->m_aExtensionMap.Insert(pExtensionMapEntry); + } + + return eTypeID; +} + +//============================================================================ +// static +INetContentType Registration::GetContentType(UniString const & rTypeName) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + USHORT nPos; + return m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos) ? + static_cast< TypeNameMapEntry * >(m_pRegistration-> + m_aTypeNameMap. + GetObject(nPos))-> + m_eTypeID : + CONTENT_TYPE_UNKNOWN; +} + +//============================================================================ +// static +UniString Registration::GetContentType(INetContentType eTypeID) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + TypeIDMapEntry * pEntry + = static_cast< TypeIDMapEntry * >(m_pRegistration-> + m_aTypeIDMap.Get(eTypeID)); + return pEntry ? pEntry->m_aTypeName : UniString(); +} + +//============================================================================ +// static +UniString Registration::GetPresentation(INetContentType eTypeID) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + TypeIDMapEntry * pEntry + = static_cast< TypeIDMapEntry * >(m_pRegistration-> + m_aTypeIDMap.Get(eTypeID)); + return pEntry ? pEntry->m_aPresentation : UniString(); +} + +//============================================================================ +// static +UniString Registration::GetExtension(UniString const & rTypeName) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + USHORT nPos; + return m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos) ? + static_cast< TypeNameMapEntry * >(m_pRegistration-> + m_aTypeNameMap. + GetObject(nPos))-> + m_aExtension : + UniString(); +} + +//============================================================================ +// static +INetContentType Registration::GetContentType4Extension(UniString const & + rExtension) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + USHORT nPos; + return m_pRegistration-> + m_aExtensionMap. + Seek_Entry(const_cast< UniString * >(&rExtension), + &nPos) ? + static_cast< ExtensionMapEntry * >(m_pRegistration-> + m_aExtensionMap. + GetObject(nPos))-> + m_eTypeID : + CONTENT_TYPE_UNKNOWN; +} + +//============================================================================ +// +// seekEntry +// +//============================================================================ + +namespace unnamed_svl_inettype { + +MediaTypeEntry const * seekEntry(UniString const & rTypeName, + MediaTypeEntry const * pMap, sal_Size nSize) +{ +#if defined DBG_UTIL || defined INETTYPE_DEBUG + static bool bChecked = false; + if (!bChecked) + { + for (sal_Size i = 0; i < nSize - 1; ++i) + DBG_ASSERT(pMap[i].m_pTypeName < pMap[i + 1].m_pTypeName, + "seekEntry(): Bad map"); + bChecked = true; + } +#endif // DBG_UTIL, INETTYPE_DEBUG + + sal_Size nLow = 0; + sal_Size nHigh = nSize; + while (nLow != nHigh) + { + sal_Size nMiddle = (nLow + nHigh) / 2; + MediaTypeEntry const * pEntry = pMap + nMiddle; + switch (rTypeName.CompareIgnoreCaseToAscii(pEntry->m_pTypeName)) + { + case COMPARE_LESS: + nHigh = nMiddle; + break; + + case COMPARE_EQUAL: + return pEntry; + + case COMPARE_GREATER: + nLow = nMiddle + 1; + break; + } + } + return 0; +} + +} + +//============================================================================ +// +// INetContentTypes +// +//============================================================================ + +//static +void INetContentTypes::Uninitialize() +{ + Registration::deinitialize(); +} + +//============================================================================ +//static +INetContentType INetContentTypes::RegisterContentType(UniString const & + rTypeName, + UniString const & + rPresentation, + UniString const * + pExtension, + UniString const * + pSystemFileType) +{ + INetContentType eTypeID = GetContentType(rTypeName); + if (eTypeID == CONTENT_TYPE_UNKNOWN) + eTypeID = Registration::RegisterContentType(rTypeName, rPresentation, + pExtension, + pSystemFileType); + else if (eTypeID > CONTENT_TYPE_LAST) + { + TypeIDMapEntry * pTypeEntry = Registration::getEntry(eTypeID); + if (pTypeEntry) + { + if (rPresentation.Len() != 0) + pTypeEntry->m_aPresentation = rPresentation; + if (pSystemFileType) + pTypeEntry->m_aSystemFileType = *pSystemFileType; + } + if (pExtension) + { + TypeNameMapEntry * pEntry + = Registration::getExtensionEntry(rTypeName); + if (pEntry) + pEntry->m_aExtension = *pExtension; + } + } + return eTypeID; +} + +//============================================================================ +// static +INetContentType INetContentTypes::GetContentType(UniString const & rTypeName) +{ + UniString aType; + UniString aSubType; + if (parse(rTypeName, aType, aSubType)) + { + aType += '/'; + aType += aSubType; + MediaTypeEntry const * pEntry = seekEntry(aType, aStaticTypeNameMap, + CONTENT_TYPE_LAST + 1); + return pEntry ? pEntry->m_eTypeID : + Registration::GetContentType(aType); + } + else + return + rTypeName.EqualsIgnoreCaseAscii(CONTENT_TYPE_STR_X_STARMAIL) ? + CONTENT_TYPE_X_STARMAIL : CONTENT_TYPE_UNKNOWN; + // the content type "x-starmail" has no sub type +} + +//============================================================================ +//static +UniString INetContentTypes::GetContentType(INetContentType eTypeID) +{ + static sal_Char const * aMap[CONTENT_TYPE_LAST + 1]; + static bool bInitialized = false; + if (!bInitialized) + { + for (sal_Size i = 0; i <= CONTENT_TYPE_LAST; ++i) + aMap[aStaticTypeNameMap[i].m_eTypeID] + = aStaticTypeNameMap[i].m_pTypeName; + aMap[CONTENT_TYPE_UNKNOWN] = CONTENT_TYPE_STR_APP_OCTSTREAM; + aMap[CONTENT_TYPE_TEXT_PLAIN] = CONTENT_TYPE_STR_TEXT_PLAIN + "; charset=iso-8859-1"; + bInitialized = true; + } + + UniString aTypeName = eTypeID <= CONTENT_TYPE_LAST ? + UniString::CreateFromAscii(aMap[eTypeID]) : + Registration::GetContentType(eTypeID); + if (aTypeName.Len() == 0) + { + DBG_ERROR("INetContentTypes::GetContentType(): Bad ID"); + return + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( + CONTENT_TYPE_STR_APP_OCTSTREAM)); + } + return aTypeName; +} + +//============================================================================ +//static +UniString INetContentTypes::GetPresentation(INetContentType eTypeID, + const ::com::sun::star::lang::Locale& aLocale) +{ + USHORT nResID = USHORT(); + if (eTypeID <= CONTENT_TYPE_LAST) + nResID = aStaticResourceIDMap[eTypeID]; + else + { + UniString aPresentation = Registration::GetPresentation(eTypeID); + if (aPresentation.Len() == 0) + nResID = STR_SVT_MIMETYPE_APP_OCTSTREAM; + else + return aPresentation; + } + return SvtSimpleResId(nResID, aLocale); +} + +//============================================================================ +//static +UniString INetContentTypes::GetExtension(UniString const & rTypeName) +{ + MediaTypeEntry const * pEntry = seekEntry(rTypeName, aStaticTypeNameMap, + CONTENT_TYPE_LAST + 1); + if (pEntry) + return UniString::CreateFromAscii(pEntry->m_pExtension); + + UniString aExtension = Registration::GetExtension(rTypeName); + if (aExtension.Len() != 0) + return aExtension; + // special handling of text types, which come in uncounted variations: + return rTypeName.EqualsIgnoreCaseAscii("text", 0, + RTL_CONSTASCII_LENGTH("text")) ? + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("txt")) : + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("tmp")); +} + +//============================================================================ +//static +INetContentType INetContentTypes::GetContentType4Extension(UniString const & + rExtension) +{ + MediaTypeEntry const * pEntry = seekEntry(rExtension, aStaticExtensionMap, + sizeof aStaticExtensionMap + / sizeof (MediaTypeEntry)); + if (pEntry) + return pEntry->m_eTypeID; + INetContentType eTypeID + = Registration::GetContentType4Extension(rExtension); + return eTypeID == CONTENT_TYPE_UNKNOWN ? CONTENT_TYPE_APP_OCTSTREAM : + eTypeID; +} + +//============================================================================ +//static +INetContentType INetContentTypes::GetContentTypeFromURL(UniString const & + rURL) +{ + INetContentType eTypeID = CONTENT_TYPE_UNKNOWN; + UniString aToken = rURL.GetToken(0, ':'); + if (aToken.Len() != 0) + { + if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_FILE)) + if (rURL.GetChar(rURL.Len() - 1) == '/') // folder + if (rURL.Len() > RTL_CONSTASCII_LENGTH("file:///")) + if (WildCard(UniString(RTL_CONSTASCII_USTRINGPARAM( + "*/{*}/"))). + Matches(rURL)) // special folder + eTypeID = CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER; + else + // drive? -> "file:///?|/" + if (rURL.Len() == 11 + && rURL.GetChar(rURL.Len() - 2) == '|') + { + // Drives need further processing, because of + // dynamic type according to underlying volume, + // which cannot be determined here. + } + else // normal folder + eTypeID = CONTENT_TYPE_X_CNT_FSYSFOLDER; + else // file system root + eTypeID = CONTENT_TYPE_X_CNT_FSYSBOX; + else // file + { + //@@@ + } + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_HTTP) + || aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_HTTPS)) + eTypeID = CONTENT_TYPE_TEXT_HTML; + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_PRIVATE)) + { + UniString aSecondPart = rURL.GetToken(1, ':'); + aToken = aSecondPart.GetToken(0, '/'); + if (aToken.EqualsAscii(INETTYPE_URL_SUB_FACTORY)) + { + aToken = aSecondPart.GetToken(1, '/'); + if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SWRITER)) + { + aToken = aSecondPart.GetToken(2, '/'); + eTypeID = aToken.EqualsAscii(INETTYPE_URL_SSSUB_WEB) ? + CONTENT_TYPE_APP_VND_WRITER_WEB : + aToken.EqualsAscii(INETTYPE_URL_SSSUB_GLOB) ? + CONTENT_TYPE_APP_VND_WRITER_GLOBAL : + CONTENT_TYPE_APP_VND_WRITER; + } + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SCALC)) + eTypeID = CONTENT_TYPE_APP_VND_CALC; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SDRAW)) + eTypeID = CONTENT_TYPE_APP_VND_DRAW; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SIMPRESS)) + eTypeID = CONTENT_TYPE_APP_VND_IMPRESS; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SCHART)) + eTypeID = CONTENT_TYPE_APP_VND_CHART; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SIMAGE)) + eTypeID = CONTENT_TYPE_APP_VND_IMAGE; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SMATH)) + eTypeID = CONTENT_TYPE_APP_VND_MATH; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_FRAMESET)) + eTypeID = CONTENT_TYPE_APP_FRAMESET; + } + else if (aToken.EqualsAscii(INETTYPE_URL_SUB_HELPID)) + eTypeID = CONTENT_TYPE_APP_STARHELP; + } + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_COMPONENT)) + { + aToken = rURL.GetToken(1, ':'); // aToken now equals ss / * + aToken = aToken.GetToken(0, '/'); + if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SS)) + eTypeID = rURL.SearchAscii(INETTYPE_URL_SCHED_CMB) + == STRING_NOTFOUND + && rURL.SearchAscii(INETTYPE_URL_SCHED_FORM) + == STRING_NOTFOUND ? + CONTENT_TYPE_APP_SCHEDULE : + rURL.SearchAscii(INETTYPE_URL_SCHED_TASK) + == STRING_NOTFOUND ? + CONTENT_TYPE_APP_SCHEDULE_EVT : + CONTENT_TYPE_APP_SCHEDULE_TASK; + } + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_MAILTO)) + eTypeID = CONTENT_TYPE_APP_VND_OUTTRAY; + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_MACRO)) + eTypeID = CONTENT_TYPE_APP_MACRO; + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_DATA)) + { + UniString aSecondPart = rURL.GetToken(1, ':'); + aToken = aSecondPart.GetToken(0, ','); + eTypeID = GetContentType(aToken); + } + } + if (eTypeID == CONTENT_TYPE_UNKNOWN) + { + UniString aExtension; + if (GetExtensionFromURL(rURL, aExtension)) + eTypeID = GetContentType4Extension(aExtension); + } + return eTypeID; +} + +//============================================================================ +//static +bool INetContentTypes::GetExtensionFromURL(UniString const & rURL, + UniString & rExtension) +{ + xub_StrLen nSlashPos = 0; + xub_StrLen i = 0; + while (i != STRING_NOTFOUND) + { + nSlashPos = i; + i = rURL.Search('/', i + 1); + } + if (nSlashPos != 0) + { + xub_StrLen nLastDotPos = i = rURL.Search('.', nSlashPos); + while (i != STRING_NOTFOUND) + { + nLastDotPos = i; + i = rURL.Search('.', i + 1); + } + if (nLastDotPos != STRING_NOTFOUND) + rExtension = rURL.Copy(nLastDotPos + 1); + return true; + } + return false; +} + +//============================================================================ +//static +INetContentType INetContentTypes::MapStringToContentType(UniString const & + rPresentation) +{ + MediaTypeEntry const * pEntry = seekEntry(rPresentation, + aStaticPresentationMap, + sizeof aStaticPresentationMap + / sizeof (MediaTypeEntry)); + return pEntry ? pEntry->m_eTypeID : CONTENT_TYPE_UNKNOWN; +} + +//============================================================================ +// static +bool INetContentTypes::parse(ByteString const & rMediaType, + ByteString & rType, ByteString & rSubType, + INetContentTypeParameterList * pParameters) +{ + sal_Char const * p = rMediaType.GetBuffer(); + sal_Char const * pEnd = p + rMediaType.Len(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + sal_Char const * pToken = p; + bool bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rType = ByteString(pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rType.ToLowerAscii(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd || *p++ != '/') + return false; + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + pToken = p; + bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rSubType = ByteString( + pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rSubType.ToLowerAscii(); + + return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd; +} + +//============================================================================ +// static +bool INetContentTypes::parse(UniString const & rMediaType, + UniString & rType, UniString & rSubType, + INetContentTypeParameterList * pParameters) +{ + sal_Unicode const * p = rMediaType.GetBuffer(); + sal_Unicode const * pEnd = p + rMediaType.Len(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + sal_Unicode const * pToken = p; + bool bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rType = UniString(pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rType.ToLowerAscii(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd || *p++ != '/') + return false; + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + pToken = p; + bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rSubType = UniString( + pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rSubType.ToLowerAscii(); + + return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd; +} + +//============================================================================ +// static +ByteString INetContentTypes::appendUSASCIIParameter(ByteString const & + rMediaType, + ByteString const & + rAttribute, + ByteString const & rValue) +{ + ByteString aResult = rMediaType; + aResult.Append(RTL_CONSTASCII_STRINGPARAM("; ")); + aResult += rAttribute; + aResult += '='; + bool bQuote = false; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // When the value contains any ' characters, use a quoted string + // instead of a token, in order to avoid confusion with RFC 2231 + // extensions: + sal_uInt32 nChar = sal_uChar(rValue.GetChar(i)); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter(): Bad value"); + if (!INetMIME::isTokenChar(nChar) || nChar == '\'') + { + bQuote = true; + break; + } + } + if (bQuote) + { + aResult += '"'; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // Escape LF as well as CR to avoid confusion with line folding: + sal_uInt32 nChar = sal_uChar(rValue.GetChar(i)); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter():" + " Bad value"); + switch (nChar) + { + case 0x0A: // LF + case 0x0D: // CR + case '"': + case '\\': + aResult += '\\'; + default: + aResult += static_cast< char >(nChar); + break; + } + } + aResult += '"'; + } + else + aResult += rValue; + return aResult; +} + +//============================================================================ +// static +UniString INetContentTypes::appendUSASCIIParameter(UniString const & + rMediaType, + UniString const & + rAttribute, + UniString const & rValue) +{ + UniString aResult = rMediaType; + aResult.AppendAscii(RTL_CONSTASCII_STRINGPARAM("; ")); + aResult += rAttribute; + aResult += '='; + bool bQuote = false; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // When the value contains any ' characters, use a quoted string + // instead of a token, in order to avoid confusion with RFC 2231 + // extensions: + sal_uInt32 nChar = rValue.GetChar(i); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter(): Bad value"); + if (!INetMIME::isTokenChar(nChar) || nChar == '\'') + { + bQuote = true; + break; + } + } + if (bQuote) + { + aResult += '"'; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // Escape LF as well as CR to avoid confusion with line folding: + sal_uInt32 nChar = rValue.GetChar(i); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter():" + " Bad value"); + switch (nChar) + { + case 0x0A: // LF + case 0x0D: // CR + case '"': + case '\\': + aResult += '\\'; + default: + aResult += sal_Unicode(nChar); + break; + } + } + aResult += '"'; + } + else + aResult += rValue; + return aResult; +} + diff --git a/svl/source/misc/lngmisc.cxx b/svl/source/misc/lngmisc.cxx new file mode 100644 index 000000000000..df7c28d22b1d --- /dev/null +++ b/svl/source/misc/lngmisc.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lngmisc.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <lngmisc.hxx> +#include <tools/solar.h> +#include <tools/string.hxx> +#include <tools/debug.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> + + +using namespace rtl; + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + +INT32 GetNumControlChars( const OUString &rTxt ) +{ + INT32 nCnt = 0; + INT32 nLen = rTxt.getLength(); + for (INT32 i = 0; i < nLen; ++i) + { + if (IsControlChar( rTxt[i] )) + ++nCnt; + } + return nCnt; +} + + +BOOL RemoveHyphens( OUString &rTxt ) +{ + BOOL bModified = FALSE; + if (HasHyphens( rTxt )) + { + String aTmp( rTxt ); + aTmp.EraseAllChars( SVT_SOFT_HYPHEN ); + aTmp.EraseAllChars( SVT_HARD_HYPHEN ); + rTxt = aTmp; + bModified = TRUE; + } + return bModified; +} + + +BOOL RemoveControlChars( OUString &rTxt ) +{ + BOOL bModified = FALSE; + INT32 nCtrlChars = GetNumControlChars( rTxt ); + if (nCtrlChars) + { + INT32 nLen = rTxt.getLength(); + INT32 nSize = nLen - nCtrlChars; + OUStringBuffer aBuf( nSize ); + aBuf.setLength( nSize ); + INT32 nCnt = 0; + for (INT32 i = 0; i < nLen; ++i) + { + sal_Unicode cChar = rTxt[i]; + if (!IsControlChar( cChar )) + { + DBG_ASSERT( nCnt < nSize, "index out of range" ); + aBuf.setCharAt( nCnt++, cChar ); + } + } + DBG_ASSERT( nCnt == nSize, "wrong size" ); + rTxt = aBuf.makeStringAndClear(); + bModified = TRUE; + } + return bModified; +} + + +// non breaking field character +#define CH_TXTATR_INWORD ((sal_Char) 0x02) + +BOOL ReplaceControlChars( rtl::OUString &rTxt, sal_Char /*aRplcChar*/ ) +{ + // the resulting string looks like this: + // 1. non breaking field characters get removed + // 2. remaining control characters will be replaced by ' ' + + BOOL bModified = FALSE; + INT32 nCtrlChars = GetNumControlChars( rTxt ); + if (nCtrlChars) + { + INT32 nLen = rTxt.getLength(); + OUStringBuffer aBuf( nLen ); + INT32 nCnt = 0; + for (INT32 i = 0; i < nLen; ++i) + { + sal_Unicode cChar = rTxt[i]; + if (CH_TXTATR_INWORD != cChar) + { + if (IsControlChar( cChar )) + cChar = ' '; + DBG_ASSERT( nCnt < nLen, "index out of range" ); + aBuf.setCharAt( nCnt++, cChar ); + } + } + aBuf.setLength( nCnt ); + rTxt = aBuf.makeStringAndClear(); + bModified = TRUE; + } + return bModified; +} + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + diff --git a/svl/source/misc/lockfilecommon.cxx b/svl/source/misc/lockfilecommon.cxx new file mode 100644 index 000000000000..f13ed574a87f --- /dev/null +++ b/svl/source/misc/lockfilecommon.cxx @@ -0,0 +1,276 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ,v $ + * + * $Revision: $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <stdio.h> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> + +#include <osl/time.h> +#include <osl/security.hxx> +#include <osl/socket.hxx> +#include <osl/file.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/processfactory.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/bootstrap.hxx> + +#include <ucbhelper/content.hxx> + +#include <unotools/useroptions.hxx> + +#include <svl/lockfilecommon.hxx> + +using namespace ::com::sun::star; + +namespace svt { + +// ---------------------------------------------------------------------- +LockFileCommon::LockFileCommon( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory, const ::rtl::OUString& aPrefix ) +: m_xFactory( xFactory ) +{ + if ( !m_xFactory.is() ) + m_xFactory = ::comphelper::getProcessServiceFactory(); + + INetURLObject aDocURL = ResolveLinks( INetURLObject( aOrigURL ) ); + + ::rtl::OUString aShareURLString = aDocURL.GetPartBeforeLastName(); + aShareURLString += aPrefix; + aShareURLString += aDocURL.GetName(); + aShareURLString += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "#" ) ); + m_aURL = INetURLObject( aShareURLString ).GetMainURL( INetURLObject::NO_DECODE ); +} + +// ---------------------------------------------------------------------- +LockFileCommon::~LockFileCommon() +{ +} + +// ---------------------------------------------------------------------- +INetURLObject LockFileCommon::ResolveLinks( const INetURLObject& aDocURL ) +{ + if ( aDocURL.HasError() ) + throw lang::IllegalArgumentException(); + + ::rtl::OUString aURLToCheck = aDocURL.GetMainURL( INetURLObject::NO_DECODE ); + + sal_Bool bNeedsChecking = sal_True; + sal_Int32 nMaxLinkCount = 128; + sal_Int32 nCount = 0; + + while( bNeedsChecking ) + { + bNeedsChecking = sal_False; + + // do not allow too deep links + if ( nCount++ >= nMaxLinkCount ) + throw io::IOException(); + + // there is currently no UCB functionality to resolve the symbolic links; + // since the lock files are used only for local file systems the osl functionality is used directly + + ::osl::FileStatus aStatus( FileStatusMask_Type | FileStatusMask_LinkTargetURL ); + ::osl::DirectoryItem aItem; + if ( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aURLToCheck, aItem ) + && aItem.is() && ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) ) + { + if ( aStatus.isValid( FileStatusMask_Type ) + && aStatus.isValid( FileStatusMask_LinkTargetURL ) + && aStatus.getFileType() == ::osl::FileStatus::Link ) + { + aURLToCheck = aStatus.getLinkTargetURL(); + bNeedsChecking = sal_True; + } + } + } + + return INetURLObject( aURLToCheck ); +} + +// ---------------------------------------------------------------------- +uno::Sequence< uno::Sequence< ::rtl::OUString > > LockFileCommon::ParseList( const uno::Sequence< sal_Int8 >& aBuffer ) +{ + sal_Int32 nCurPos = 0; + sal_Int32 nCurEntry = 0; + uno::Sequence< uno::Sequence< ::rtl::OUString > > aResult( 10 ); + + while ( nCurPos < aBuffer.getLength() ) + { + if ( nCurEntry >= aResult.getLength() ) + aResult.realloc( nCurEntry + 10 ); + aResult[nCurEntry] = ParseEntry( aBuffer, nCurPos ); + nCurEntry++; + } + + aResult.realloc( nCurEntry ); + return aResult; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > LockFileCommon::ParseEntry( const uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& io_nCurPos ) +{ + uno::Sequence< ::rtl::OUString > aResult( LOCKFILE_ENTRYSIZE ); + + for ( int nInd = 0; nInd < LOCKFILE_ENTRYSIZE; nInd++ ) + { + aResult[nInd] = ParseName( aBuffer, io_nCurPos ); + if ( io_nCurPos >= aBuffer.getLength() + || ( nInd < LOCKFILE_ENTRYSIZE - 1 && aBuffer[io_nCurPos++] != ',' ) + || ( nInd == LOCKFILE_ENTRYSIZE - 1 && aBuffer[io_nCurPos++] != ';' ) ) + throw io::WrongFormatException(); + } + + return aResult; +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::ParseName( const uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& io_nCurPos ) +{ + ::rtl::OStringBuffer aResult; + sal_Bool bHaveName = sal_False; + sal_Bool bEscape = sal_False; + + while( !bHaveName ) + { + if ( io_nCurPos >= aBuffer.getLength() ) + throw io::WrongFormatException(); + + if ( bEscape ) + { + if ( aBuffer[io_nCurPos] == ',' || aBuffer[io_nCurPos] == ';' || aBuffer[io_nCurPos] == '\\' ) + aResult.append( (sal_Char)aBuffer[io_nCurPos] ); + else + throw io::WrongFormatException(); + + bEscape = sal_False; + io_nCurPos++; + } + else if ( aBuffer[io_nCurPos] == ',' || aBuffer[io_nCurPos] == ';' ) + bHaveName = sal_True; + else + { + if ( aBuffer[io_nCurPos] == '\\' ) + bEscape = sal_True; + else + aResult.append( (sal_Char)aBuffer[io_nCurPos] ); + + io_nCurPos++; + } + } + + return ::rtl::OStringToOUString( aResult.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::EscapeCharacters( const ::rtl::OUString& aSource ) +{ + ::rtl::OUStringBuffer aBuffer; + const sal_Unicode* pStr = aSource.getStr(); + for ( sal_Int32 nInd = 0; nInd < aSource.getLength() && pStr[nInd] != 0; nInd++ ) + { + if ( pStr[nInd] == '\\' || pStr[nInd] == ';' || pStr[nInd] == ',' ) + aBuffer.append( (sal_Unicode)'\\' ); + aBuffer.append( pStr[nInd] ); + } + + return aBuffer.makeStringAndClear(); +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::GetOOOUserName() +{ + SvtUserOptions aUserOpt; + ::rtl::OUString aName = aUserOpt.GetFirstName(); + if ( aName.getLength() ) + aName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ); + aName += aUserOpt.GetLastName(); + + return aName; +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::GetCurrentLocalTime() +{ + ::rtl::OUString aTime; + + TimeValue aSysTime; + if ( osl_getSystemTime( &aSysTime ) ) + { + TimeValue aLocTime; + if ( osl_getLocalTimeFromSystemTime( &aSysTime, &aLocTime ) ) + { + oslDateTime aDateTime; + if ( osl_getDateTimeFromTimeValue( &aLocTime, &aDateTime ) ) + { + char pDateTime[20]; + sprintf( pDateTime, "%02d.%02d.%4d %02d:%02d", aDateTime.Day, aDateTime.Month, aDateTime.Year, aDateTime.Hours, aDateTime.Minutes ); + aTime = ::rtl::OUString::createFromAscii( pDateTime ); + } + } + } + + return aTime; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > LockFileCommon::GenerateOwnEntry() +{ + uno::Sequence< ::rtl::OUString > aResult( LOCKFILE_ENTRYSIZE ); + + aResult[LOCKFILE_OOOUSERNAME_ID] = GetOOOUserName(); + + ::osl::Security aSecurity; + aSecurity.getUserName( aResult[LOCKFILE_SYSUSERNAME_ID] ); + + aResult[LOCKFILE_LOCALHOST_ID] = ::osl::SocketAddr::getLocalHostname(); + + aResult[LOCKFILE_EDITTIME_ID] = GetCurrentLocalTime(); + + ::utl::Bootstrap::locateUserInstallation( aResult[LOCKFILE_USERURL_ID] ); + + + return aResult; +} + +} // namespace svt + diff --git a/svl/source/misc/makefile.mk b/svl/source/misc/makefile.mk new file mode 100644 index 000000000000..adc659a7b60b --- /dev/null +++ b/svl/source/misc/makefile.mk @@ -0,0 +1,74 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=svl +TARGET=misc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES=\ + $(SLO)$/documentlockfile.obj \ + $(SLO)$/folderrestriction.obj \ + $(SLO)$/fstathelper.obj \ + $(SLO)$/lockfilecommon.obj \ + $(SLO)$/ownlist.obj \ + $(SLO)$/restrictedpaths.obj \ + $(SLO)$/sharecontrolfile.obj \ + $(SLO)$/strmadpt.obj \ + $(SLO)$/svldata.obj \ + $(SLO)$/urihelper.obj + +SLOFILES=\ + $(EXCEPTIONSFILES) \ + $(SLO)$/adrparse.obj \ + $(SLO)$/filenotation.obj \ + $(SLO)$/inethist.obj \ + $(SLO)$/inettype.obj \ + $(SLO)$/lngmisc.obj \ + $(SLO)$/PasswordHelper.obj + +SRS1NAME=$(TARGET) +SRC1FILES=\ + mediatyp.src + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + + + + diff --git a/svl/source/misc/mediatyp.src b/svl/source/misc/mediatyp.src new file mode 100644 index 000000000000..63033af29d03 --- /dev/null +++ b/svl/source/misc/mediatyp.src @@ -0,0 +1,610 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: mediatyp.src,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +//============================================================================ +// +// Internet Media Type Presentations +// +// $Author: rt $ $Date: 2008-04-10 21:44:39 $ $Revision: 1.7 $ +//============================================================================ + +#ifndef _SVTOOLS_HRC +#include <svl/svtools.hrc> +#endif + +String STR_SVT_MIMETYPE_APP_OCTSTREAM +{ + Text [ en-US ] = "Binary file" ; +}; + +String STR_SVT_MIMETYPE_APP_PDF +{ + Text [ en-US ] = "PDF file" ; +}; + +String STR_SVT_MIMETYPE_APP_RTF +{ + Text [ en-US ] = "RTF File" ; +}; + +String STR_SVT_MIMETYPE_APP_MSWORD +{ + Text [ en-US ] = "MS-Word document" ; +}; + +String STR_SVT_MIMETYPE_APP_STARCALC +{ + Text [ en-US ] = "%PRODUCTNAME Spreadsheet" ; +}; + +String STR_SVT_MIMETYPE_APP_STARCHART +{ + Text [ en-US ] = "%PRODUCTNAME Chart" ; +}; + +String STR_SVT_MIMETYPE_APP_STARDRAW +{ + Text [ en-US ] = "%PRODUCTNAME Drawing" ; +}; + +String STR_SVT_MIMETYPE_APP_STARIMAGE +{ + Text [ en-US ] = "%PRODUCTNAME Image" ; +}; + +String STR_SVT_MIMETYPE_APP_STARMATH +{ + Text [ en-US ] = "%PRODUCTNAME Formula" ; +}; + +String STR_SVT_MIMETYPE_APP_STARWRITER +{ + Text [ en-US ] = "%PRODUCTNAME Text" ; +}; + +String STR_SVT_MIMETYPE_APP_ZIP +{ + Text [ en-US ] = "ZIP file" ; +}; + +String STR_SVT_MIMETYPE_APP_JAR +{ + Text [ en-US ] = "JAR file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_AIFF +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_BASIC +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_MIDI +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_WAV +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_GIF +{ + Text [ en-US ] = "Graphics" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_JPEG +{ + Text [ en-US ] = "Graphics" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_PCX +{ + Text [ en-US ] = "Graphics" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_BMP +{ + Text [ en-US ] = "Bitmap" ; +}; + +String STR_SVT_MIMETYPE_TEXT_HTML +{ + Text [ en-US ] = "HTML document" ; +}; + +String STR_SVT_MIMETYPE_TEXT_PLAIN +{ + Text [ en-US ] = "Text file" ; +}; + +String STR_SVT_MIMETYPE_TEXT_URL +{ + Text [ en-US ] = "Bookmark" ; +}; + +String STR_SVT_MIMETYPE_TEXT_VCARD +{ + Text [ en-US ] = "vCard file" ; +}; + +String STR_SVT_MIMETYPE_VIDEO_VDO +{ + Text [ en-US ] = "Video file" ; +}; + +String STR_SVT_MIMETYPE_VIDEO_MSVIDEO +{ + Text [ en-US ] = "Video file" ; +}; + +String STR_SVT_MIMETYPE_X_STARMAIL +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_X_VRML +{ + Text [ en-US ] = "VRML file" ; +}; + +String STR_SVT_MIMETYPE_APP_STARIMPRESS +{ + Text [ en-US ] = "%PRODUCTNAME Presentation" ; +}; + +String STR_SVT_MIMETYPE_APP_IMPRESSPACKED +{ + Text [ en-US ] = "%PRODUCTNAME Presentation (packed)"; +}; + +String STR_SVT_MIMETYPE_APP_STARHELP +{ + Text [ en-US ] = "%PRODUCTNAME Help" ; +}; + + +String STR_SVT_MIMETYPE_CNT_MSG +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_CNT_DOCUMENT +{ + Text [ en-US ] = "Document" ; +}; + +String STR_SVT_MIMETYPE_CNT_POP3BOX +{ + Text [ en-US ] = "POP3 Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_IMAPBOX +{ + Text [ en-US ] = "IMAP Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_IMAPFLD +{ + Text [ en-US ] = "Folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_VIMBOX +{ + Text [ en-US ] = "VIM Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_VIMINBOX +{ + Text [ en-US ] = "Inbox" ; +}; + +String STR_SVT_MIMETYPE_CNT_BBBOX +{ + Text [ en-US ] = "Newsgroups" ; +}; + +String STR_SVT_MIMETYPE_CNT_VIM_BB +{ + Text [ en-US ] = "Newsgroup" ; +}; + +String STR_SVT_MIMETYPE_CNT_NEWSBOX +{ + Text [ en-US ] = "News" ; +}; + +String STR_SVT_MIMETYPE_CNT_NEWSGRP +{ + Text [ en-US ] = "Group" ; +}; + +String STR_SVT_MIMETYPE_CNT_OUTBOX +{ + Text [ en-US ] = "Outbox" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPBOX +{ + Text [ en-US ] = "FTP Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPFLD +{ + Text [ en-US ] = "FTP Folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPFILE +{ + Text [ en-US ] = "FTP File" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPLINK +{ + Text [ en-US ] = "FTP Link" ; +}; + +String STR_SVT_MIMETYPE_CNT_HTTPBOX +{ + Text [ en-US ] = "HTTP" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSBOX +{ + Text [ en-US ] = "Workplace" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSFLD +{ + Text [ en-US ] = "Folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSFILE +{ + Text [ en-US ] = "File" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSURLFILE +{ + Text [ en-US ] = "Link" ; +}; + +String STR_SVT_MIMETYPE_CNT_PUBLBOX +{ + Text [ en-US ] = "Project" ; +}; + +String STR_SVT_MIMETYPE_CNT_SRCHBOX +{ + Text [ en-US ] = "Find" ; +}; + +String STR_SVT_MIMETYPE_CNT_SUBSCRBOX +{ + Text [ en-US ] = "Subscriptions" ; +}; + +String STR_SVT_MIMETYPE_CNT_BOOKMARK +{ + Text [ en-US ] = "Bookmark subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDF +{ + Text [ en-US ] = "Channel subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDFSUB +{ + Text [ en-US ] = "Channel subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDFITEM +{ + Text [ en-US ] = "Channel subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_STARCHANNEL +{ + Text [ en-US ] = "StarChannel" ; +}; + +String STR_SVT_MIMETYPE_CNT_TRASHBOX +{ + Text [ en-US ] = "Recycle Bin" ; +}; + +String STR_SVT_MIMETYPE_CNT_TRASH +{ + Text [ en-US ] = "Deleted Object" ; +}; + +String STR_SVT_MIMETYPE_CNT_REMOV_VOL +{ + Text [ en-US ] = "Local drive" ; +}; + +String STR_SVT_MIMETYPE_CNT_FIX_VOL +{ + Text [ en-US ] = "Local drive" ; +}; + +String STR_SVT_MIMETYPE_CNT_REM_VOL +{ + Text [ en-US ] = "Network connection" ; +}; + +String STR_SVT_MIMETYPE_CNT_RAM_VOL +{ + Text [ en-US ] = "RAM Disk" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDROM +{ + Text [ en-US ] = "CD-ROM drive" ; +}; + +String STR_SVT_MIMETYPE_CNT_DISK_35 +{ + Text [ en-US ] = "3.5'' Disk" ; +}; + +String STR_SVT_MIMETYPE_CNT_DISK_525 +{ + Text [ en-US ] = "5.25'' Disk" ; +}; + +String STR_SVT_MIMETYPE_CNT_TAPEDRIVE +{ + Text [ en-US ] = "Tape drive" ; +}; + +String STR_SVT_MIMETYPE_APP_GAL +{ + Text [ en-US ] = "Gallery"; +}; + +String STR_SVT_MIMETYPE_APP_GAL_THEME +{ + Text [ en-US ] = "Gallery theme" ; +}; + +String STR_SVT_MIMETYPE_CNT_SEPARATOR +{ + Text = "CntMenuView-Separator" ; +}; + +String STR_SVT_MIMETYPE_APP_STARW_GLOB +{ + Text [ en-US ] = "%PRODUCTNAME Master Document" ; +}; + +String STR_SVT_MIMETYPE_APP_SDM +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_APP_SMD +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_APP_STARW_WEB +{ + Text [ en-US ] = "%PRODUCTNAME Writer/Web" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE +{ + Text [ en-US ] = "Tasks & Events" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_EVT +{ + Text [ en-US ] = "%PRODUCTNAME Events View" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_TASK +{ + Text [ en-US ] = "%PRODUCTNAME Task View" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_FEVT +{ + Text [ en-US ] = "%PRODUCTNAME Event" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_FTASK +{ + Text [ en-US ] = "%PRODUCTNAME Task" ; +}; + +String STR_SVT_MIMETYPE_FRAMESET +{ + Text [ en-US ] = "Frameset Document" ; +}; + +String STR_SVT_MIMETYPE_MACRO +{ + Text [ en-US ] = "Macro file" ; +}; + +String STR_SVT_MIMETYPE_CNT_SFSYSFOLDER +{ + Text [ en-US ] = "System folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_SFSYSFILE +{ + Text [ en-US ] = "System object" ; +}; + +String STR_SVT_MIMETYPE_APP_TEMPLATE +{ + Text [ en-US ] = "%PRODUCTNAME Template"; +}; + +String STR_SVT_MIMETYPE_IMAGE_GENERIC +{ + Text [ en-US ] = "Graphics"; +}; + +String STR_SVT_MIMETYPE_APP_MSEXCEL +{ + Text [ en-US ] = "MS Excel document" ; +}; + +String STR_SVT_MIMETYPE_APP_MSEXCEL_TEMPL +{ + Text [ en-US ] = "MS Excel Template" ; +}; + +String STR_SVT_MIMETYPE_APP_MSPPOINT +{ + Text [ en-US ] = "MS PowerPoint document" ; +}; + +String STR_SVT_MIMETYPE_TEXT_VCALENDAR +{ + Text [ en-US ] = "vCalendar-file" ; +}; + +String STR_SVT_MIMETYPE_TEXT_ICALENDAR +{ + Text [ en-US ] = "iCalendar-File"; +}; + +String STR_SVT_MIMETYPE_TEXT_XMLICALENDAR +{ + Text [ en-US ] = "XML-iCalendar-File"; +}; + +String STR_SVT_MIMETYPE_TEXT_CDE_CALENDAR_APP +{ + Text [ en-US ] = "CDE-Calendar-File"; +}; + +String STR_SVT_MIMETYPE_INET_MSG_RFC822 +{ + Text [ en-US ] = "message/rfc822" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_ALTERNATIVE +{ + Text [ en-US ] = "multipart/alternative" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_DIGEST +{ + Text [ en-US ] = "multipart/digest" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_PARALLEL +{ + Text [ en-US ] = "multipart/parallel" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_RELATED +{ + Text [ en-US ] = "multipart/related" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_MIXED +{ + Text [ en-US ] = "multipart/mixed" ; +}; + +String STR_SVT_MIMETYPE_APP_SXCALC +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Spreadsheet" ; +}; + +String STR_SVT_MIMETYPE_APP_SXCHART +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Chart" ; +}; + +String STR_SVT_MIMETYPE_APP_SXDRAW +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Drawing" ; +}; + +String STR_SVT_MIMETYPE_APP_SXMATH +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Formula" ; +}; + +String STR_SVT_MIMETYPE_APP_SXWRITER +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Text Document" ; +}; + +String STR_SVT_MIMETYPE_APP_SXIMPRESS +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Presentation" ; +}; + +String STR_SVT_MIMETYPE_APP_SXGLOBAL +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Master Document" ; +}; + +String STR_SVT_MIMETYPE_APP_SXIPACKED +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Presentation (packed)" ; +}; + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svl/source/misc/ownlist.cxx b/svl/source/misc/ownlist.cxx new file mode 100644 index 000000000000..def341d57b7c --- /dev/null +++ b/svl/source/misc/ownlist.cxx @@ -0,0 +1,330 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ownlist.cxx,v $ + * $Revision: 1.6.136.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <ctype.h> +#include <stdio.h> +#include <com/sun/star/beans/PropertyValues.hpp> + +#include <svl/ownlist.hxx> + +using namespace com::sun::star; + +//========================================================================= +//============== SvCommandList ============================================ +//========================================================================= +PRV_SV_IMPL_OWNER_LIST(SvCommandList,SvCommand) + + +static String parseString(const String & rCmd, USHORT * pIndex) +{ + String result; + + if(rCmd.GetChar( *pIndex ) == '\"') { + (*pIndex) ++; + + USHORT begin = *pIndex; + + while(*pIndex < rCmd.Len() && rCmd.GetChar((*pIndex) ++) != '\"') ; + + result = String(rCmd.Copy(begin, *pIndex - begin - 1)); + } + + return result; +} + +static String parseWord(const String & rCmd, USHORT * pIndex) +{ + USHORT begin = *pIndex; + + while(*pIndex < rCmd.Len() && !isspace(rCmd.GetChar(*pIndex)) && rCmd.GetChar(*pIndex) != '=') + (*pIndex) ++; + + return String(rCmd.Copy(begin, *pIndex - begin)); +} + +static void eatSpace(const String & rCmd, USHORT * pIndex) +{ + while(*pIndex < rCmd.Len() && isspace(rCmd.GetChar(*pIndex))) + (*pIndex) ++; +} + + +//========================================================================= +BOOL SvCommandList::AppendCommands +( + const String & rCmd, /* Dieser Text wird in Kommandos umgesetzt */ + USHORT * pEaten /* Anzahl der Zeichen, die gelesen wurden */ +) +/* [Beschreibung] + + Es wird eine Text geparsed und die einzelnen Kommandos werden an + die Liste angeh"angt. + + [R"uckgabewert] + + BOOL TRUE, der Text wurde korrekt geparsed. + FALSE, der Text wurde nicht korrekt geparsed. +*/ +{ + USHORT index = 0; + while(index < rCmd.Len()) + { + + eatSpace(rCmd, &index); + String name = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index); + + eatSpace(rCmd, &index); + String value; + if(index < rCmd.Len() && rCmd.GetChar(index) == '=') + { + index ++; + + eatSpace(rCmd, &index); + value = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index); + } + + SvCommand * pCmd = new SvCommand(name, value); + aTypes.Insert(pCmd, LIST_APPEND); + } + + *pEaten = index; + +// USHORT nPos = 0; +// while( nPos < rCmd.Len() ) +// { +// // ein Zeichen ? Dann faengt hier eine Option an +// if( isalpha( rCmd[nPos] ) ) +// { +// String aValue; +// USHORT nStt = nPos; +// register char c; + +// while( nPos < rCmd.Len() && +// ( isalnum(c=rCmd[nPos]) || '-'==c || '.'==c ) ) +// nPos++; + +// String aToken( rCmd.Copy( nStt, nPos-nStt ) ); + +// while( nPos < rCmd.Len() && +// ( !String::IsPrintable( (c=rCmd[nPos]), +// RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) ) +// nPos++; + +// // hat die Option auch einen Wert? +// if( nPos!=rCmd.Len() && '='==c ) +// { +// nPos++; + +// while( nPos < rCmd.Len() && +// ( !String::IsPrintable( (c=rCmd[nPos]), +// RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) ) +// nPos++; + +// if( nPos != rCmd.Len() ) +// { +// USHORT nLen = 0; +// nStt = nPos; +// if( '"' == c ) +// { +// nPos++; nStt++; +// while( nPos < rCmd.Len() && +// '"' != rCmd[nPos] ) +// nPos++, nLen++; +// if( nPos!=rCmd.Len() ) +// nPos++; +// } +// else +// // hier sind wir etwas laxer als der +// // Standard und erlauben alles druckbare +// while( nPos < rCmd.Len() && +// String::IsPrintable( (c=rCmd[nPos]), +// RTL_TEXTENCODING_MS_1252 ) && +// !isspace( c ) ) +// nPos++, nLen++; + +// if( nLen ) +// aValue = rCmd( nStt, nLen ); +// } +// } + +// SvCommand * pCmd = new SvCommand( aToken, aValue ); +// aTypes.Insert( pCmd, LIST_APPEND ); +// } +// else +// // white space un unerwartete Zeichen ignorieren wie +// nPos++; +// } +// *pEaten = nPos; + return TRUE; +} + +//========================================================================= +String SvCommandList::GetCommands() const +/* [Beschreibung] + + Die Kommandos in der Liste werden als Text hintereinander, durch ein + Leerzeichen getrennt geschrieben. Der Text muss nicht genauso + aussehen wie der in <SvCommandList::AppendCommands()> "ubergebene. + + [R"uckgabewert] + + String Die Kommandos werden zur"uckgegeben. +*/ +{ + String aRet; + for( ULONG i = 0; i < aTypes.Count(); i++ ) + { + if( i != 0 ) + aRet += ' '; + SvCommand * pCmd = (SvCommand *)aTypes.GetObject( i ); + aRet += pCmd->GetCommand(); + if( pCmd->GetArgument().Len() ) + { + aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "=\"" ) ); + aRet += pCmd->GetArgument(); + aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ) ); + } + } + return aRet; +} + +//========================================================================= +SvCommand & SvCommandList::Append +( + const String & rCommand, /* das Kommando */ + const String & rArg /* dasArgument des Kommandos */ +) +/* [Beschreibung] + + Es wird eine Objekt vom Typ SvCommand erzeugt und an die Liste + angeh"angt. + + [R"uckgabewert] + + SvCommand & Das erteugte Objekt wird zur"uckgegeben. +*/ +{ + SvCommand * pCmd = new SvCommand( rCommand, rArg ); + aTypes.Insert( pCmd, LIST_APPEND ); + return *pCmd; +} + +//========================================================================= +SvStream & operator >> +( + SvStream & rStm, /* Stream aus dem gelesen wird */ + SvCommandList & rThis /* Die zu f"ullende Liste */ +) +/* [Beschreibung] + + Die Liste mit ihren Elementen wird gelesen. Das Format ist: + 1. Anzahl der Elemente + 2. Alle Elemente + + [R"uckgabewert] + + SvStream & Der "ubergebene Stream. +*/ +{ + UINT32 nCount = 0; + rStm >> nCount; + if( !rStm.GetError() ) + { + while( nCount-- ) + { + SvCommand * pCmd = new SvCommand(); + rStm >> *pCmd; + rThis.aTypes.Insert( pCmd, LIST_APPEND ); + } + } + return rStm; +} + +//========================================================================= +SvStream & operator << +( + SvStream & rStm, /* Stream in den geschrieben wird */ + const SvCommandList & rThis /* Die zu schreibende Liste */ +) +/* [Beschreibung] + + Die Liste mit ihren Elementen wir geschrieben. Das Format ist: + 1. Anzahl der Elemente + 2. Alle Elemente + + [R"uckgabewert] + + SvStream & Der "ubergebene Stream. +*/ +{ + UINT32 nCount = rThis.aTypes.Count(); + rStm << nCount; + + for( UINT32 i = 0; i < nCount; i++ ) + { + SvCommand * pCmd = (SvCommand *)rThis.aTypes.GetObject( i ); + rStm << *pCmd; + } + return rStm; +} + +BOOL SvCommandList::FillFromSequence( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence ) +{ + const sal_Int32 nCount = aCommandSequence.getLength(); + String aCommand, aArg; + ::rtl::OUString aApiArg; + for( sal_Int32 nIndex=0; nIndex<nCount; nIndex++ ) + { + aCommand = aCommandSequence[nIndex].Name; + if( !( aCommandSequence[nIndex].Value >>= aApiArg ) ) + return sal_False; + aArg = aApiArg; + Append( aCommand, aArg ); + } + + return TRUE; +} + +void SvCommandList::FillSequence( com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence ) +{ + const sal_Int32 nCount = Count(); + aCommandSequence.realloc( nCount ); + for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) + { + const SvCommand& rCommand = (*this)[ nIndex ]; + aCommandSequence[nIndex].Name = rCommand.GetCommand(); + aCommandSequence[nIndex].Handle = -1; + aCommandSequence[nIndex].Value = uno::makeAny( ::rtl::OUString( rCommand.GetArgument() ) ); + aCommandSequence[nIndex].State = beans::PropertyState_DIRECT_VALUE; + } +} + diff --git a/svl/source/misc/restrictedpaths.cxx b/svl/source/misc/restrictedpaths.cxx new file mode 100644 index 000000000000..9eda454604b1 --- /dev/null +++ b/svl/source/misc/restrictedpaths.cxx @@ -0,0 +1,217 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: restrictedpaths.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/restrictedpaths.hxx> + +#include <algorithm> +#include <osl/process.h> +#include <tools/urlobj.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/syslocale.hxx> + +namespace svt +{ + namespace + { + // ---------------------------------------------------------------- + /** retrieves the value of an environment variable + @return <TRUE/> if and only if the retrieved string value is not empty + */ + bool lcl_getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue ) + { + _rValue = ::rtl::OUString(); + ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName ); + osl_getEnvironment( sEnvName.pData, &_rValue.pData ); + return _rValue.getLength() != 0; + } + + //----------------------------------------------------------------- + void lcl_convertStringListToUrls( const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash ) + { + const sal_Unicode s_cSeparator = + #if defined(WNT) + ';' + #else + ':' + #endif + ; + xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator ); + _rTokens.resize( 0 ); _rTokens.reserve( nTokens ); + for ( xub_StrLen i=0; i<nTokens; ++i ) + { + // the current token in the list + String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator ); + if ( !sCurrentToken.Len() ) + continue; + + INetURLObject aCurrentURL; + + String sURL; + if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) ) + aCurrentURL = INetURLObject( sURL ); + else + { + // smart URL parsing, assuming FILE protocol + aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE ); + } + + if ( _bFinalSlash ) + aCurrentURL.setFinalSlash( ); + else + aCurrentURL.removeFinalSlash( ); + _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) ); + } + } + + } + + //===================================================================== + //= CheckURLAllowed + //===================================================================== + struct CheckURLAllowed + { + protected: + #ifdef WNT + SvtSysLocale m_aSysLocale; + #endif + String m_sCheckURL; // the URL to check + bool m_bAllowParent; + public: + inline CheckURLAllowed( const String& _rCheckURL, bool bAllowParent = true ) + :m_sCheckURL( _rCheckURL ), m_bAllowParent( bAllowParent ) + { + #ifdef WNT + // on windows, assume that the relevant file systems are case insensitive, + // thus normalize the URL + m_sCheckURL = m_aSysLocale.GetCharClass().toLower( m_sCheckURL, 0, m_sCheckURL.Len() ); + #endif + } + + bool operator()( const String& _rApprovedURL ) + { + #ifdef WNT + // on windows, assume that the relevant file systems are case insensitive, + // thus normalize the URL + String sApprovedURL( m_aSysLocale.GetCharClass().toLower( _rApprovedURL, 0, _rApprovedURL.Len() ) ); + #else + String sApprovedURL( _rApprovedURL ); + #endif + + xub_StrLen nLenApproved = sApprovedURL.Len(); + xub_StrLen nLenChecked = m_sCheckURL.Len(); + + if ( nLenApproved > nLenChecked ) + { + if ( m_bAllowParent ) + { + if ( sApprovedURL.Search( m_sCheckURL ) == 0 ) + { + if ( ( m_sCheckURL.GetChar( nLenChecked - 1 ) == '/' ) + || ( sApprovedURL.GetChar( nLenChecked ) == '/' ) ) + return true; + } + } + else + { + // just a difference in final slash? + if ( ( nLenApproved == ( nLenChecked + 1 ) ) && + ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) ) + return true; + } + return false; + } + else if ( nLenApproved < nLenChecked ) + { + if ( m_sCheckURL.Search( sApprovedURL ) == 0 ) + { + if ( ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) + || ( m_sCheckURL.GetChar( nLenApproved ) == '/' ) ) + return true; + } + return false; + } + else + { + // strings have equal length + return ( sApprovedURL == m_sCheckURL ); + } + } + }; + + //===================================================================== + //= RestrictedPaths + //===================================================================== + //--------------------------------------------------------------------- + RestrictedPaths::RestrictedPaths() + :m_bFilterIsEnabled( true ) + { + ::rtl::OUString sRestrictedPathList; + if ( lcl_getEnvironmentValue( "RestrictedPath", sRestrictedPathList ) ) + // append a final slash. This ensures that when we later on check + // for unrestricted paths, we don't allow paths like "/home/user35" just because + // "/home/user3" is allowed - with the final slash, we make it "/home/user3/". + lcl_convertStringListToUrls( sRestrictedPathList, m_aUnrestrictedURLs, true ); + } + + RestrictedPaths::~RestrictedPaths() {} + + // -------------------------------------------------------------------- + bool RestrictedPaths::isUrlAllowed( const String& _rURL ) const + { + if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled ) + return true; + + ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if( + m_aUnrestrictedURLs.begin(), + m_aUnrestrictedURLs.end(), + CheckURLAllowed( _rURL, true ) + ); + + return ( aApprovedURL != m_aUnrestrictedURLs.end() ); + } + + // -------------------------------------------------------------------- + bool RestrictedPaths::isUrlAllowed( const String& _rURL, bool allowParents ) const + { + if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled ) + return true; + + ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if( + m_aUnrestrictedURLs.begin(), + m_aUnrestrictedURLs.end(), + CheckURLAllowed( _rURL, allowParents ) + ); + + return ( aApprovedURL != m_aUnrestrictedURLs.end() ); + } + +} // namespace svt diff --git a/svl/source/misc/sharecontrolfile.cxx b/svl/source/misc/sharecontrolfile.cxx new file mode 100644 index 000000000000..9249fa3f33de --- /dev/null +++ b/svl/source/misc/sharecontrolfile.cxx @@ -0,0 +1,376 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sharecontrolfile.cxx,v $ + * $Revision: 1.6.82.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <stdio.h> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> + +#include <osl/time.h> +#include <osl/security.hxx> +#include <osl/socket.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/processfactory.hxx> +#include <ucbhelper/content.hxx> + +#include <tools/urlobj.hxx> +#include <tools/stream.hxx> +#include <unotools/bootstrap.hxx> +#include <unotools/streamwrap.hxx> + +#include <unotools/useroptions.hxx> + +#include <svl/sharecontrolfile.hxx> + +using namespace ::com::sun::star; + +namespace svt { + +// ---------------------------------------------------------------------- +ShareControlFile::ShareControlFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".~sharing." ) ) ) +{ + OpenStream(); + + if ( !IsValid() ) + throw io::NotConnectedException(); +} + +// ---------------------------------------------------------------------- +ShareControlFile::~ShareControlFile() +{ + try + { + Close(); + } + catch( uno::Exception& ) + {} +} + +// ---------------------------------------------------------------------- +void ShareControlFile::OpenStream() +{ + // if it is called outside of constructor the mutex must be locked already + + if ( !m_xStream.is() && m_aURL.getLength() ) + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aContent = ::ucbhelper::Content( m_aURL, xDummyEnv ); + + uno::Reference< ucb::XContentIdentifier > xContId( aContent.get().is() ? aContent.get()->getIdentifier() : 0 ); + if ( !xContId.is() || !xContId->getContentProviderScheme().equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file" ) ) ) ) + throw io::IOException(); // the implementation supports only local files for now + + uno::Reference< io::XStream > xStream; + + // Currently the locking of the original document is intended to be used. + // That means that the shared file should be accessed only when the original document is locked and only by user who has locked the document. + // TODO/LATER: should the own file locking be used? + + try + { + xStream = aContent.openWriteableStreamNoLock(); + } + catch ( ucb::InteractiveIOException const & e ) + { + if ( e.Code == ucb::IOErrorCode_NOT_EXISTING ) + { + // Create file... + SvMemoryStream aStream(0,0); + uno::Reference< io::XInputStream > xInput( new ::utl::OInputStreamWrapper( aStream ) ); + ucb::InsertCommandArgument aInsertArg; + aInsertArg.Data = xInput; + aInsertArg.ReplaceExisting = sal_False; + aContent.executeCommand( rtl::OUString::createFromAscii( "insert" ), uno::makeAny( aInsertArg ) ); + + // try to let the file be hidden if possible + try { + aContent.setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), uno::makeAny( sal_True ) ); + } catch( uno::Exception& ) {} + + // Try to open one more time + xStream = aContent.openWriteableStreamNoLock(); + } + else + throw; + } + + m_xSeekable.set( xStream, uno::UNO_QUERY_THROW ); + m_xInputStream.set( xStream->getInputStream(), uno::UNO_QUERY_THROW ); + m_xOutputStream.set( xStream->getOutputStream(), uno::UNO_QUERY_THROW ); + m_xTruncate.set( m_xOutputStream, uno::UNO_QUERY_THROW ); + m_xStream = xStream; + } +} + +// ---------------------------------------------------------------------- +void ShareControlFile::Close() +{ + // if it is called outside of destructor the mutex must be locked + + if ( m_xStream.is() ) + { + try + { + if ( m_xInputStream.is() ) + m_xInputStream->closeInput(); + if ( m_xOutputStream.is() ) + m_xOutputStream->closeOutput(); + } + catch( uno::Exception& ) + {} + + m_xStream = uno::Reference< io::XStream >(); + m_xInputStream = uno::Reference< io::XInputStream >(); + m_xOutputStream = uno::Reference< io::XOutputStream >(); + m_xSeekable = uno::Reference< io::XSeekable >(); + m_xTruncate = uno::Reference< io::XTruncate >(); + m_aUsersData.realloc( 0 ); + } +} + +// ---------------------------------------------------------------------- +uno::Sequence< uno::Sequence< ::rtl::OUString > > ShareControlFile::GetUsersData() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + if ( !m_aUsersData.getLength() ) + { + sal_Int64 nLength = m_xSeekable->getLength(); + if ( nLength > SAL_MAX_INT32 ) + throw uno::RuntimeException(); + + uno::Sequence< sal_Int8 > aBuffer( (sal_Int32)nLength ); + m_xSeekable->seek( 0 ); + + sal_Int32 nRead = m_xInputStream->readBytes( aBuffer, (sal_Int32)nLength ); + nLength -= nRead; + while ( nLength > 0 ) + { + uno::Sequence< sal_Int8 > aTmpBuf( (sal_Int32)nLength ); + nRead = m_xInputStream->readBytes( aTmpBuf, (sal_Int32)nLength ); + if ( nRead > nLength ) + throw uno::RuntimeException(); + + for ( sal_Int32 nInd = 0; nInd < nRead; nInd++ ) + aBuffer[aBuffer.getLength() - (sal_Int32)nLength + nInd] = aTmpBuf[nInd]; + nLength -= nRead; + } + + m_aUsersData = ParseList( aBuffer ); + } + + return m_aUsersData; +} + +// ---------------------------------------------------------------------- +void ShareControlFile::SetUsersDataAndStore( const uno::Sequence< uno::Sequence< ::rtl::OUString > >& aUsersData ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + if ( !m_xTruncate.is() || !m_xOutputStream.is() || !m_xSeekable.is() ) + throw uno::RuntimeException(); + + m_xTruncate->truncate(); + m_xSeekable->seek( 0 ); + + ::rtl::OUStringBuffer aBuffer; + for ( sal_Int32 nInd = 0; nInd < aUsersData.getLength(); nInd++ ) + { + if ( aUsersData[nInd].getLength() != SHARED_ENTRYSIZE ) + throw lang::IllegalArgumentException(); + + for ( sal_Int32 nEntryInd = 0; nEntryInd < SHARED_ENTRYSIZE; nEntryInd++ ) + { + aBuffer.append( EscapeCharacters( aUsersData[nInd][nEntryInd] ) ); + if ( nEntryInd < SHARED_ENTRYSIZE - 1 ) + aBuffer.append( (sal_Unicode)',' ); + else + aBuffer.append( (sal_Unicode)';' ); + } + } + + ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) ); + uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() ); + m_xOutputStream->writeBytes( aData ); + m_aUsersData = aUsersData; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > ShareControlFile::InsertOwnEntry() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + GetUsersData(); + uno::Sequence< ::uno::Sequence< ::rtl::OUString > > aNewData( m_aUsersData.getLength() + 1 ); + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + + sal_Bool bExists = sal_False; + sal_Int32 nNewInd = 0; + for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); nInd++ ) + { + if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE ) + { + if ( m_aUsersData[nInd][SHARED_LOCALHOST_ID] == aNewEntry[SHARED_LOCALHOST_ID] + && m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] == aNewEntry[SHARED_SYSUSERNAME_ID] + && m_aUsersData[nInd][SHARED_USERURL_ID] == aNewEntry[SHARED_USERURL_ID] ) + { + if ( !bExists ) + { + aNewData[nNewInd] = aNewEntry; + bExists = sal_True; + } + } + else + { + aNewData[nNewInd] = m_aUsersData[nInd]; + } + + nNewInd++; + } + } + + if ( !bExists ) + aNewData[nNewInd++] = aNewEntry; + + aNewData.realloc( nNewInd ); + SetUsersDataAndStore( aNewData ); + + return aNewEntry; +} + +// ---------------------------------------------------------------------- +bool ShareControlFile::HasOwnEntry() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + { + throw io::NotConnectedException(); + } + + GetUsersData(); + uno::Sequence< ::rtl::OUString > aEntry = GenerateOwnEntry(); + + for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); ++nInd ) + { + if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE && + m_aUsersData[nInd][SHARED_LOCALHOST_ID] == aEntry[SHARED_LOCALHOST_ID] && + m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] == aEntry[SHARED_SYSUSERNAME_ID] && + m_aUsersData[nInd][SHARED_USERURL_ID] == aEntry[SHARED_USERURL_ID] ) + { + return true; + } + } + + return false; +} + +// ---------------------------------------------------------------------- +void ShareControlFile::RemoveEntry( const uno::Sequence< ::rtl::OUString >& aArgEntry ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + GetUsersData(); + + uno::Sequence< ::rtl::OUString > aEntry = aArgEntry; + if ( aEntry.getLength() != SHARED_ENTRYSIZE ) + aEntry = GenerateOwnEntry(); + + uno::Sequence< ::uno::Sequence< ::rtl::OUString > > aNewData( m_aUsersData.getLength() + 1 ); + + sal_Int32 nNewInd = 0; + for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); nInd++ ) + { + if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE ) + { + if ( m_aUsersData[nInd][SHARED_LOCALHOST_ID] != aEntry[SHARED_LOCALHOST_ID] + || m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] != aEntry[SHARED_SYSUSERNAME_ID] + || m_aUsersData[nInd][SHARED_USERURL_ID] != aEntry[SHARED_USERURL_ID] ) + { + aNewData[nNewInd] = m_aUsersData[nInd]; + nNewInd++; + } + } + } + + aNewData.realloc( nNewInd ); + SetUsersDataAndStore( aNewData ); + + if ( !nNewInd ) + { + // try to remove the file if it is empty + RemoveFile(); + } +} + +// ---------------------------------------------------------------------- +void ShareControlFile::RemoveFile() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + Close(); + + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), + uno::UNO_QUERY_THROW ); + xSimpleFileAccess->kill( m_aURL ); +} + +} // namespace svt + diff --git a/svl/source/misc/strmadpt.cxx b/svl/source/misc/strmadpt.cxx new file mode 100644 index 000000000000..9803f2bcc32f --- /dev/null +++ b/svl/source/misc/strmadpt.cxx @@ -0,0 +1,1048 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: strmadpt.cxx,v $ + * $Revision: 1.5.136.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <functional> // needed under Solaris when including <algorithm>... + +#include <algorithm> +#include <limits> +#include <set> +#include <rtl/alloc.h> +#include <rtl/memory.h> +#include <instrm.hxx> +#include <outstrm.hxx> +#include <strmadpt.hxx> + +using namespace com::sun::star; + +//============================================================================ +class SvDataPipe_Impl +{ +public: + enum SeekResult { SEEK_BEFORE_MARKED, SEEK_OK, SEEK_PAST_END }; + +private: + struct Page + { + Page * m_pPrev; + Page * m_pNext; + sal_Int8 * m_pStart; + sal_Int8 * m_pRead; + sal_Int8 * m_pEnd; + sal_uInt32 m_nOffset; + sal_Int8 m_aBuffer[1]; + }; + + std::multiset< sal_uInt32 > m_aMarks; + Page * m_pFirstPage; + Page * m_pReadPage; + Page * m_pWritePage; + sal_Int8 * m_pReadBuffer; + sal_uInt32 m_nReadBufferSize; + sal_uInt32 m_nReadBufferFilled; + sal_uInt32 m_nPageSize; + sal_uInt32 m_nMinPages; + sal_uInt32 m_nMaxPages; + sal_uInt32 m_nPages; + bool m_bEOF; + + bool remove(Page * pPage); + +public: + inline SvDataPipe_Impl(sal_uInt32 nThePageSize = 1000, + sal_uInt32 nTheMinPages = 100, + sal_uInt32 nTheMaxPages + = std::numeric_limits< sal_uInt32 >::max()); + + ~SvDataPipe_Impl(); + + inline void setReadBuffer(sal_Int8 * pBuffer, sal_uInt32 nSize); + + sal_uInt32 read(); + + void clearReadBuffer() { m_pReadBuffer = 0; } + + sal_uInt32 write(sal_Int8 const * pBuffer, sal_uInt32 nSize); + + void setEOF() { m_bEOF = true; } + + inline bool isEOF() const; + + bool addMark(sal_uInt32 nPosition); + + bool removeMark(sal_uInt32 nPosition); + + inline sal_uInt32 getReadPosition() const; + + SeekResult setReadPosition(sal_uInt32 nPosition); +}; + +SvDataPipe_Impl::SvDataPipe_Impl(sal_uInt32 nThePageSize, + sal_uInt32 nTheMinPages, + sal_uInt32 nTheMaxPages): + m_pFirstPage(0), + m_pReadPage(0), + m_pWritePage(0), + m_pReadBuffer(0), + m_nPageSize(std::min< sal_uInt32 >( + std::max< sal_uInt32 >(nThePageSize, sal_uInt32(1)), + sal_uInt32(std::numeric_limits< sal_uInt32 >::max() + - sizeof (Page) + 1))), + m_nMinPages(std::max< sal_uInt32 >(nTheMinPages, sal_uInt32(1))), + m_nMaxPages(std::max< sal_uInt32 >(nTheMaxPages, sal_uInt32(1))), + m_nPages(0), + m_bEOF(false) +{} + +inline void SvDataPipe_Impl::setReadBuffer(sal_Int8 * pBuffer, + sal_uInt32 nSize) +{ + m_pReadBuffer = pBuffer; + m_nReadBufferSize = nSize; + m_nReadBufferFilled = 0; +} + +inline bool SvDataPipe_Impl::isEOF() const +{ + return m_bEOF && m_pReadPage == m_pWritePage + && (!m_pReadPage || m_pReadPage->m_pRead == m_pReadPage->m_pEnd); +} + +inline sal_uInt32 SvDataPipe_Impl::getReadPosition() const +{ + return m_pReadPage == 0 ? 0 : + m_pReadPage->m_nOffset + + (m_pReadPage->m_pRead + - m_pReadPage->m_aBuffer); +} + +//============================================================================ +// +// SvOutputStreamOpenLockBytes +// +//============================================================================ + +TYPEINIT1(SvOutputStreamOpenLockBytes, SvOpenLockBytes) + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::ReadAt(ULONG, void *, ULONG, ULONG *) + const +{ + return ERRCODE_IO_CANTREAD; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::WriteAt(ULONG nPos, void const * pBuffer, + ULONG nCount, ULONG * pWritten) +{ + if (nPos != m_nPosition) + return ERRCODE_IO_CANTWRITE; + return FillAppend(pBuffer, nCount, pWritten); +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::Flush() const +{ + if (!m_xOutputStream.is()) + return ERRCODE_IO_CANTWRITE; + try + { + m_xOutputStream->flush(); + } + catch (io::IOException) + { + return ERRCODE_IO_CANTWRITE; + } + return ERRCODE_NONE; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::SetSize(ULONG) +{ + return ERRCODE_IO_NOTSUPPORTED; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::Stat(SvLockBytesStat * pStat, + SvLockBytesStatFlag) const +{ + if (pStat) + pStat->nSize = m_nPosition; + return ERRCODE_NONE; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::FillAppend(void const * pBuffer, + ULONG nCount, + ULONG * pWritten) +{ + if (!m_xOutputStream.is()) + return ERRCODE_IO_CANTWRITE; + if (nCount > 0 + && nCount > std::numeric_limits< ULONG >::max() - m_nPosition) + { + nCount = std::numeric_limits< ULONG >::max() - m_nPosition; + if (nCount == 0) + return ERRCODE_IO_CANTWRITE; + } + try + { + m_xOutputStream-> + writeBytes(uno::Sequence< sal_Int8 >( + static_cast< sal_Int8 const * >(pBuffer), nCount)); + } + catch (io::IOException) + { + return ERRCODE_IO_CANTWRITE; + } + m_nPosition += nCount; + if (pWritten) + *pWritten = nCount; + return ERRCODE_NONE; +} + +//============================================================================ +// virtual +ULONG SvOutputStreamOpenLockBytes::Tell() const +{ + return m_nPosition; +} + +//============================================================================ +// virtual +ULONG SvOutputStreamOpenLockBytes::Seek(ULONG) +{ + return m_nPosition; +} + +//============================================================================ +// virtual +void SvOutputStreamOpenLockBytes::Terminate() +{ + if (m_xOutputStream.is()) + try + { + m_xOutputStream->closeOutput(); + } + catch (io::IOException) {} +} + +//============================================================================ +// +// SvLockBytesInputStream +// +//============================================================================ + +// virtual +uno::Any SAL_CALL SvLockBytesInputStream::queryInterface(uno::Type const & + rType) + throw (uno::RuntimeException) +{ + uno::Any + aReturn(cppu::queryInterface(rType, + static_cast< io::XInputStream * >(this), + static_cast< io::XSeekable * >(this))); + return aReturn.hasValue() ? aReturn : OWeakObject::queryInterface(rType); +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::acquire() throw () +{ + OWeakObject::acquire(); +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::release() throw () +{ + OWeakObject::release(); +} + +//============================================================================ +// virtual +sal_Int32 SAL_CALL +SvLockBytesInputStream::readBytes(uno::Sequence< sal_Int8 > & rData, + sal_Int32 nBytesToRead) + throw (io::IOException, uno::RuntimeException) +{ + OSL_ASSERT(m_nPosition >= 0); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + if ( + nBytesToRead < 0 || + ( + static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE && + nBytesToRead > 0 + ) + ) + { + throw io::IOException(); + } + rData.realloc(nBytesToRead); + sal_Int32 nSize = 0; + while (nSize < nBytesToRead) + { + sal_Size nCount; + ErrCode nError = m_xLockBytes->ReadAt(static_cast<sal_Size>( + m_nPosition), + rData.getArray() + nSize, + nBytesToRead - nSize, &nCount); + if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING) + throw io::IOException(); + m_nPosition += nCount; + nSize += nCount; + if (nError == ERRCODE_NONE && nCount == 0) + break; + } + rData.realloc(nSize); + return nSize; +} + +//============================================================================ +// virtual +sal_Int32 SAL_CALL +SvLockBytesInputStream::readSomeBytes(uno::Sequence< sal_Int8 > & rData, + sal_Int32 nMaxBytesToRead) + throw (io::IOException, uno::RuntimeException) +{ + OSL_ASSERT(m_nPosition >= 0); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + if (static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE + && nMaxBytesToRead > 0) + throw io::IOException(); + rData.realloc(nMaxBytesToRead); + sal_Size nCount = 0; + if (nMaxBytesToRead > 0) + { + ErrCode nError; + do + { + nError = m_xLockBytes->ReadAt(static_cast<sal_Size>(m_nPosition), + rData.getArray(), + nMaxBytesToRead < 0 ? + 0 : nMaxBytesToRead, + &nCount); + if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING) + throw io::IOException(); + m_nPosition += nCount; + } + while (nCount == 0 && nError == ERRCODE_IO_PENDING); + } + rData.realloc(sal_Int32(nCount)); + return sal_Int32(nCount); +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::skipBytes(sal_Int32 nBytesToSkip) + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + if (nBytesToSkip < 0) + throw io::IOException(); + if (nBytesToSkip > SAL_MAX_INT64 - m_nPosition) + throw io::BufferSizeExceededException(); + m_nPosition += nBytesToSkip; +} + +//============================================================================ +// virtual +sal_Int32 SAL_CALL SvLockBytesInputStream::available() + throw (io::IOException, uno::RuntimeException) +{ + OSL_ASSERT(m_nPosition >= 0); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + SvLockBytesStat aStat; + if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE) + throw io::IOException(); + return aStat.nSize <= static_cast<sal_uInt64>(m_nPosition) ? + 0 : + static_cast<sal_Size>(aStat.nSize - m_nPosition) <= + static_cast<sal_uInt32>(SAL_MAX_INT32) ? + static_cast<sal_Int32>(aStat.nSize - m_nPosition) : + SAL_MAX_INT32; +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::closeInput() + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + m_xLockBytes = 0; +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::seek(sal_Int64 nLocation) + throw (lang::IllegalArgumentException, io::IOException, + uno::RuntimeException) +{ + if (nLocation < 0) + throw lang::IllegalArgumentException(); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + m_nPosition = nLocation; +} + +//============================================================================ +// virtual +sal_Int64 SAL_CALL SvLockBytesInputStream::getPosition() + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + return m_nPosition; +} + +//============================================================================ +// virtual +sal_Int64 SAL_CALL SvLockBytesInputStream::getLength() + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + SvLockBytesStat aStat; + if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE) + throw io::IOException(); +#if SAL_TYPES_SIZEOFPOINTER > 4 // avoid warnings if sal_Size < sal_Int64 + if (aStat.nSize > static_cast<sal_uInt64>(SAL_MAX_INT64)) + throw io::IOException(); +#endif + return aStat.nSize; +} + +//============================================================================ +// +// SvInputStream +// +//============================================================================ + +bool SvInputStream::open() +{ + if (GetError() != ERRCODE_NONE) + return false; + if (!(m_xSeekable.is() || m_pPipe)) + { + if (!m_xStream.is()) + { + SetError(ERRCODE_IO_INVALIDDEVICE); + return false; + } + m_xSeekable + = uno::Reference< io::XSeekable >(m_xStream, uno::UNO_QUERY); + if (!m_xSeekable.is()) + m_pPipe = new SvDataPipe_Impl; + } + return true; +} + +//============================================================================ +// virtual +ULONG SvInputStream::GetData(void * pData, ULONG nSize) +{ + if (!open()) + { + SetError(ERRCODE_IO_CANTREAD); + return 0; + } + sal_uInt32 nRead = 0; + if (m_xSeekable.is()) + { + if (m_nSeekedFrom != STREAM_SEEK_TO_END) + { + try + { + m_xSeekable->seek(m_nSeekedFrom); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTREAD); + return 0; + } + m_nSeekedFrom = STREAM_SEEK_TO_END; + } + for (;;) + { + sal_Int32 nRemain + = sal_Int32( + std::min(ULONG(nSize - nRead), + ULONG(std::numeric_limits< sal_Int32 >::max()))); + if (nRemain == 0) + break; + uno::Sequence< sal_Int8 > aBuffer; + sal_Int32 nCount; + try + { + nCount = m_xStream->readBytes(aBuffer, nRemain); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTREAD); + return nRead; + } + rtl_copyMemory(static_cast< sal_Int8 * >(pData) + nRead, + aBuffer.getConstArray(), sal_uInt32(nCount)); + nRead += nCount; + if (nCount < nRemain) + break; + } + } + else + { + if (m_nSeekedFrom != STREAM_SEEK_TO_END) + { + SetError(ERRCODE_IO_CANTREAD); + return 0; + } + m_pPipe->setReadBuffer(static_cast< sal_Int8 * >(pData), nSize); + nRead = m_pPipe->read(); + if (nRead < nSize && !m_pPipe->isEOF()) + for (;;) + { + sal_Int32 nRemain + = sal_Int32( + std::min( + ULONG(nSize - nRead), + ULONG(std::numeric_limits< sal_Int32 >::max()))); + if (nRemain == 0) + break; + uno::Sequence< sal_Int8 > aBuffer; + sal_Int32 nCount; + try + { + nCount = m_xStream->readBytes(aBuffer, nRemain); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTREAD); + break; + } + m_pPipe->write(aBuffer.getConstArray(), sal_uInt32(nCount)); + nRead += m_pPipe->read(); + if (nCount < nRemain) + { + m_xStream->closeInput(); + m_pPipe->setEOF(); + break; + } + } + m_pPipe->clearReadBuffer(); + } + return nRead; +} + +//============================================================================ +// virtual +ULONG SvInputStream::PutData(void const *, ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); + return 0; +} + +//============================================================================ +// virtual +void SvInputStream::FlushData() +{} + +//============================================================================ +// virtual +ULONG SvInputStream::SeekPos(ULONG nPos) +{ + if (open()) + { + if (nPos == STREAM_SEEK_TO_END) + { + if (m_nSeekedFrom == STREAM_SEEK_TO_END) + { + if (m_xSeekable.is()) + try + { + sal_Int64 nLength = m_xSeekable->getLength(); + OSL_ASSERT(nLength >= 0); + if (static_cast<sal_uInt64>(nLength) + < STREAM_SEEK_TO_END) + { + m_nSeekedFrom = Tell(); + return ULONG(nLength); + } + } + catch (io::IOException) {} + else + return Tell(); //@@@ + } + else + return Tell(); + } + else if (nPos == m_nSeekedFrom) + { + m_nSeekedFrom = STREAM_SEEK_TO_END; + return nPos; + } + else if (m_xSeekable.is()) + try + { + m_xSeekable->seek(nPos); + m_nSeekedFrom = STREAM_SEEK_TO_END; + return nPos; + } + catch (io::IOException) {} + else if (m_pPipe->setReadPosition(nPos) == SvDataPipe_Impl::SEEK_OK) + { + m_nSeekedFrom = STREAM_SEEK_TO_END; + return nPos; + } + } + SetError(ERRCODE_IO_CANTSEEK); + return Tell(); +} + +//============================================================================ +// virtual +void SvInputStream::SetSize(ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); +} + +//============================================================================ +SvInputStream::SvInputStream( + com::sun::star::uno::Reference< com::sun::star::io::XInputStream > + const & + rTheStream): + m_xStream(rTheStream), + m_pPipe(0), + m_nSeekedFrom(STREAM_SEEK_TO_END) +{ + SetBufferSize(0); +} + +//============================================================================ +// virtual +SvInputStream::~SvInputStream() +{ + if (m_xStream.is()) + try + { + m_xStream->closeInput(); + } + catch (io::IOException) {} + delete m_pPipe; +} + +//============================================================================ +// virtual +USHORT SvInputStream::IsA() const +{ + return 0; +} + +//============================================================================ +// virtual +void SvInputStream::AddMark(ULONG nPos) +{ + if (open() && m_pPipe) + m_pPipe->addMark(nPos); +} + +//============================================================================ +// virtual +void SvInputStream::RemoveMark(ULONG nPos) +{ + if (open() && m_pPipe) + m_pPipe->removeMark(nPos); +} + +//============================================================================ +// +// SvOutputStream +// +//============================================================================ + +// virtual +ULONG SvOutputStream::GetData(void *, ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); + return 0; +} + +//============================================================================ +// virtual +ULONG SvOutputStream::PutData(void const * pData, ULONG nSize) +{ + if (!m_xStream.is()) + { + SetError(ERRCODE_IO_CANTWRITE); + return 0; + } + ULONG nWritten = 0; + for (;;) + { + sal_Int32 nRemain + = sal_Int32( + std::min(ULONG(nSize - nWritten), + ULONG(std::numeric_limits< sal_Int32 >::max()))); + if (nRemain == 0) + break; + try + { + m_xStream->writeBytes(uno::Sequence< sal_Int8 >( + static_cast<const sal_Int8 * >(pData) + + nWritten, + nRemain)); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTWRITE); + break; + } + nWritten += nRemain; + } + return nWritten; +} + +//============================================================================ +// virtual +ULONG SvOutputStream::SeekPos(ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); + return 0; +} + +//============================================================================ +// virtual +void SvOutputStream::FlushData() +{ + if (!m_xStream.is()) + { + SetError(ERRCODE_IO_INVALIDDEVICE); + return; + } + try + { + m_xStream->flush(); + } + catch (io::IOException) {} +} + +//============================================================================ +// virtual +void SvOutputStream::SetSize(ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); +} + +//============================================================================ +SvOutputStream::SvOutputStream(uno::Reference< io::XOutputStream > const & + rTheStream): + m_xStream(rTheStream) +{ + SetBufferSize(0); +} + +//============================================================================ +// virtual +SvOutputStream::~SvOutputStream() +{ + if (m_xStream.is()) + try + { + m_xStream->closeOutput(); + } + catch (io::IOException) {} +} + +//============================================================================ +// virtual +USHORT SvOutputStream::IsA() const +{ + return 0; +} + +//============================================================================ +// +// SvDataPipe_Impl +// +//============================================================================ + +bool SvDataPipe_Impl::remove(Page * pPage) +{ + if ( + pPage != m_pFirstPage || + m_pReadPage == m_pFirstPage || + ( + !m_aMarks.empty() && + *m_aMarks.begin() < m_pFirstPage->m_nOffset + m_nPageSize + ) + ) + { + return false; + } + + m_pFirstPage = m_pFirstPage->m_pNext; + + if (m_nPages <= m_nMinPages) + return true; + + pPage->m_pPrev->m_pNext = pPage->m_pNext; + pPage->m_pNext->m_pPrev = pPage->m_pPrev; + rtl_freeMemory(pPage); + --m_nPages; + + return true; +} + +//============================================================================ +SvDataPipe_Impl::~SvDataPipe_Impl() +{ + if (m_pFirstPage != 0) + for (Page * pPage = m_pFirstPage;;) + { + Page * pNext = pPage->m_pNext; + rtl_freeMemory(pPage); + if (pNext == m_pFirstPage) + break; + pPage = pNext; + } +} + +//============================================================================ +sal_uInt32 SvDataPipe_Impl::read() +{ + if (m_pReadBuffer == 0 || m_nReadBufferSize == 0 || m_pReadPage == 0) + return 0; + + sal_uInt32 nSize = m_nReadBufferSize; + sal_uInt32 nRemain = m_nReadBufferSize - m_nReadBufferFilled; + + m_pReadBuffer += m_nReadBufferFilled; + m_nReadBufferSize -= m_nReadBufferFilled; + m_nReadBufferFilled = 0; + + while (nRemain > 0) + { + sal_uInt32 nBlock = std::min(sal_uInt32(m_pReadPage->m_pEnd + - m_pReadPage->m_pRead), + nRemain); + rtl_copyMemory(m_pReadBuffer, m_pReadPage->m_pRead, nBlock); + m_pReadPage->m_pRead += nBlock; + m_pReadBuffer += nBlock; + m_nReadBufferSize -= nBlock; + m_nReadBufferFilled = 0; + nRemain -= nBlock; + + if (m_pReadPage == m_pWritePage) + break; + + if (m_pReadPage->m_pRead == m_pReadPage->m_pEnd) + { + Page * pRemove = m_pReadPage; + m_pReadPage = pRemove->m_pNext; + remove(pRemove); + } + } + + return nSize - nRemain; +} + +//============================================================================ +sal_uInt32 SvDataPipe_Impl::write(sal_Int8 const * pBuffer, sal_uInt32 nSize) +{ + if (nSize == 0) + return 0; + + if (m_pWritePage == 0) + { + m_pFirstPage + = static_cast< Page * >(rtl_allocateMemory(sizeof (Page) + + m_nPageSize + - 1)); + m_pFirstPage->m_pPrev = m_pFirstPage; + m_pFirstPage->m_pNext = m_pFirstPage; + m_pFirstPage->m_pStart = m_pFirstPage->m_aBuffer; + m_pFirstPage->m_pRead = m_pFirstPage->m_aBuffer; + m_pFirstPage->m_pEnd = m_pFirstPage->m_aBuffer; + m_pFirstPage->m_nOffset = 0; + m_pReadPage = m_pFirstPage; + m_pWritePage = m_pFirstPage; + ++m_nPages; + } + + sal_uInt32 nRemain = nSize; + + if (m_pReadBuffer != 0 && m_pReadPage == m_pWritePage + && m_pReadPage->m_pRead == m_pWritePage->m_pEnd) + { + sal_uInt32 nBlock = std::min(nRemain, + sal_uInt32(m_nReadBufferSize + - m_nReadBufferFilled)); + sal_uInt32 nPosition = m_pWritePage->m_nOffset + + (m_pWritePage->m_pEnd + - m_pWritePage->m_aBuffer); + if (!m_aMarks.empty()) + nBlock = *m_aMarks.begin() > nPosition ? + std::min(nBlock, sal_uInt32(*m_aMarks.begin() + - nPosition)) : + 0; + + if (nBlock > 0) + { + rtl_copyMemory(m_pReadBuffer + m_nReadBufferFilled, pBuffer, + nBlock); + m_nReadBufferFilled += nBlock; + nRemain -= nBlock; + + nPosition += nBlock; + m_pWritePage->m_nOffset = (nPosition / m_nPageSize) * m_nPageSize; + m_pWritePage->m_pStart = m_pWritePage->m_aBuffer + + nPosition % m_nPageSize; + m_pWritePage->m_pRead = m_pWritePage->m_pStart; + m_pWritePage->m_pEnd = m_pWritePage->m_pStart; + } + } + + if (nRemain > 0) + for (;;) + { + sal_uInt32 nBlock + = std::min(sal_uInt32(m_pWritePage->m_aBuffer + m_nPageSize + - m_pWritePage->m_pEnd), + nRemain); + rtl_copyMemory(m_pWritePage->m_pEnd, pBuffer, nBlock); + m_pWritePage->m_pEnd += nBlock; + pBuffer += nBlock; + nRemain -= nBlock; + + if (nRemain == 0) + break; + + if (m_pWritePage->m_pNext == m_pFirstPage) + { + if (m_nPages == m_nMaxPages) + break; + + Page * pNew + = static_cast< Page * >(rtl_allocateMemory( + sizeof (Page) + m_nPageSize + - 1)); + pNew->m_pPrev = m_pWritePage; + pNew->m_pNext = m_pWritePage->m_pNext; + + m_pWritePage->m_pNext->m_pPrev = pNew; + m_pWritePage->m_pNext = pNew; + ++m_nPages; + } + + m_pWritePage->m_pNext->m_nOffset = m_pWritePage->m_nOffset + + m_nPageSize; + m_pWritePage = m_pWritePage->m_pNext; + m_pWritePage->m_pStart = m_pWritePage->m_aBuffer; + m_pWritePage->m_pRead = m_pWritePage->m_aBuffer; + m_pWritePage->m_pEnd = m_pWritePage->m_aBuffer; + } + + return nSize - nRemain; +} + +//============================================================================ +bool SvDataPipe_Impl::addMark(sal_uInt32 nPosition) +{ + if (m_pFirstPage != 0 && m_pFirstPage->m_nOffset > nPosition) + return false; + m_aMarks.insert(nPosition); + return true; +} + +//============================================================================ +bool SvDataPipe_Impl::removeMark(sal_uInt32 nPosition) +{ + std::multiset< sal_uInt32 >::iterator t = m_aMarks.find(nPosition); + if (t == m_aMarks.end()) + return false; + m_aMarks.erase(t); + while (remove(m_pFirstPage)) ; + return true; +} + +//============================================================================ +SvDataPipe_Impl::SeekResult SvDataPipe_Impl::setReadPosition(sal_uInt32 + nPosition) +{ + if (m_pFirstPage == 0) + return nPosition == 0 ? SEEK_OK : SEEK_PAST_END; + + if (nPosition + <= m_pReadPage->m_nOffset + + (m_pReadPage->m_pRead - m_pReadPage->m_aBuffer)) + { + if (nPosition + < m_pFirstPage->m_nOffset + + (m_pFirstPage->m_pStart - m_pFirstPage->m_aBuffer)) + return SEEK_BEFORE_MARKED; + + while (nPosition < m_pReadPage->m_nOffset) + { + m_pReadPage->m_pRead = m_pReadPage->m_pStart; + m_pReadPage = m_pReadPage->m_pPrev; + } + } + else + { + if (nPosition + > m_pWritePage->m_nOffset + + (m_pWritePage->m_pEnd - m_pWritePage->m_aBuffer)) + return SEEK_PAST_END; + + while (m_pReadPage != m_pWritePage + && nPosition >= m_pReadPage->m_nOffset + m_nPageSize) + { + Page * pRemove = m_pReadPage; + m_pReadPage = pRemove->m_pNext; + remove(pRemove); + } + } + + m_pReadPage->m_pRead = m_pReadPage->m_aBuffer + + (nPosition - m_pReadPage->m_nOffset); + return SEEK_OK; +} + diff --git a/svl/source/misc/svldata.cxx b/svl/source/misc/svldata.cxx new file mode 100644 index 000000000000..0ba8075069cd --- /dev/null +++ b/svl/source/misc/svldata.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svldata.cxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <map> +#include <tools/resmgr.hxx> +#include <tools/shl.hxx> +#include <vos/process.hxx> +#include <svl/svldata.hxx> + +namespace unnamed_svl_svldata {} +using namespace unnamed_svl_svldata; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svl_svldata { + +typedef std::map< rtl::OUString, SimpleResMgr * > SimpleResMgrMap; + +} + +//============================================================================ +// +// ImpSvlData +// +//============================================================================ + +static ImpSvlData* pSvlData = 0; + +ImpSvlData::~ImpSvlData() +{ + for (SimpleResMgrMap::iterator t + = static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs)->begin(); + t != static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs)->end(); ++t) + delete t->second; + delete static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs); +} + +//============================================================================ +SimpleResMgr* ImpSvlData::GetSimpleRM(const ::com::sun::star::lang::Locale& rLocale) +{ + if (!m_pThreadsafeRMs) + m_pThreadsafeRMs = new SimpleResMgrMap; + rtl::OUString aISOcode = rLocale.Language; + aISOcode += rtl::OStringToOUString("-", RTL_TEXTENCODING_UTF8); + aISOcode += rLocale.Country; + + SimpleResMgr *& rResMgr + = (*static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs))[aISOcode]; + if (!rResMgr) + { + rResMgr = new SimpleResMgr(CREATEVERSIONRESMGR_NAME(svs), rLocale ); + } + return rResMgr; +} + +//============================================================================ +// static +ImpSvlData & ImpSvlData::GetSvlData() +{ + if (!pSvlData) + pSvlData= new ImpSvlData; + return *pSvlData; +} + diff --git a/svl/source/misc/urihelper.cxx b/svl/source/misc/urihelper.cxx new file mode 100644 index 000000000000..5473bf1c995d --- /dev/null +++ b/svl/source/misc/urihelper.cxx @@ -0,0 +1,952 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: urihelper.cxx,v $ + * $Revision: 1.22.136.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <urihelper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" +#include "com/sun/star/lang/XMultiComponentFactory.hpp" +#include "com/sun/star/ucb/Command.hpp" +#include <com/sun/star/ucb/FileSystemNotation.hpp> +#include "com/sun/star/ucb/IllegalIdentifierException.hpp" +#include "com/sun/star/ucb/UnsupportedCommandException.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "com/sun/star/ucb/XCommandProcessor.hpp" +#include "com/sun/star/ucb/XContent.hpp" +#include "com/sun/star/ucb/XContentIdentifierFactory.hpp" +#include "com/sun/star/ucb/XContentProvider.hpp" +#include <com/sun/star/ucb/XContentProviderManager.hpp> +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "com/sun/star/uri/UriReferenceFactory.hpp" +#include "com/sun/star/uri/XUriReference.hpp" +#include "com/sun/star/uri/XUriReferenceFactory.hpp" +#include "cppuhelper/exc_hlp.hxx" +#include "comphelper/processfactory.hxx" +#include "osl/diagnose.h" +#include "rtl/ustrbuf.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include <tools/debug.hxx> +#include <tools/inetmime.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <unotools/charclass.hxx> +#include "rtl/instance.hxx" + +namespace unnamed_svl_urihelper {} +using namespace unnamed_svl_urihelper; + // unnamed namespaces don't work well yet... + +namespace css = com::sun::star; +using namespace com::sun::star; + +//============================================================================ +// +// SmartRel2Abs +// +//============================================================================ + +namespace unnamed_svl_urihelper { + +inline UniString toUniString(ByteString const & rString) +{ + return UniString(rString, RTL_TEXTENCODING_ISO_8859_1); +} + +inline UniString toUniString(UniString const & rString) +{ + return rString; +} + +template< typename Str > +inline UniString SmartRel2Abs_Impl(INetURLObject const & rTheBaseURIRef, + Str const & rTheRelURIRef, + Link const & rMaybeFileHdl, + bool bCheckFileExists, + bool bIgnoreFragment, + INetURLObject::EncodeMechanism + eEncodeMechanism, + INetURLObject::DecodeMechanism + eDecodeMechanism, + rtl_TextEncoding eCharset, + bool bRelativeNonURIs, + INetURLObject::FSysStyle eStyle) +{ + // Backwards compatibility: + if (rTheRelURIRef.Len() != 0 && rTheRelURIRef.GetChar(0) == '#') + return toUniString(rTheRelURIRef); + + INetURLObject aAbsURIRef; + if (rTheBaseURIRef.HasError()) + aAbsURIRef. + SetSmartURL(rTheRelURIRef, eEncodeMechanism, eCharset, eStyle); + else + { + bool bWasAbsolute; + aAbsURIRef = rTheBaseURIRef.smartRel2Abs(rTheRelURIRef, + bWasAbsolute, + bIgnoreFragment, + eEncodeMechanism, + eCharset, + bRelativeNonURIs, + eStyle); + if (bCheckFileExists + && !bWasAbsolute + && (aAbsURIRef.GetProtocol() == INET_PROT_FILE + || aAbsURIRef.GetProtocol() == INET_PROT_VND_SUN_STAR_WFS)) + { + INetURLObject aNonFileURIRef; + aNonFileURIRef.SetSmartURL(rTheRelURIRef, + eEncodeMechanism, + eCharset, + eStyle); + if (!aNonFileURIRef.HasError() + && aNonFileURIRef.GetProtocol() != INET_PROT_FILE) + { + bool bMaybeFile = false; + if (rMaybeFileHdl.IsSet()) + { + UniString aFilePath(toUniString(rTheRelURIRef)); + bMaybeFile = rMaybeFileHdl.Call(&aFilePath) != 0; + } + if (!bMaybeFile) + aAbsURIRef = aNonFileURIRef; + } + } + } + return aAbsURIRef.GetMainURL(eDecodeMechanism, eCharset); +} + +} + +UniString +URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef, + ByteString const & rTheRelURIRef, + Link const & rMaybeFileHdl, + bool bCheckFileExists, + bool bIgnoreFragment, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset, + bool bRelativeNonURIs, + INetURLObject::FSysStyle eStyle) +{ + return SmartRel2Abs_Impl(rTheBaseURIRef, rTheRelURIRef, rMaybeFileHdl, + bCheckFileExists, bIgnoreFragment, + eEncodeMechanism, eDecodeMechanism, eCharset, + bRelativeNonURIs, eStyle); +} + +UniString +URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef, + UniString const & rTheRelURIRef, + Link const & rMaybeFileHdl, + bool bCheckFileExists, + bool bIgnoreFragment, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset, + bool bRelativeNonURIs, + INetURLObject::FSysStyle eStyle) +{ + return SmartRel2Abs_Impl(rTheBaseURIRef, rTheRelURIRef, rMaybeFileHdl, + bCheckFileExists, bIgnoreFragment, + eEncodeMechanism, eDecodeMechanism, eCharset, + bRelativeNonURIs, eStyle); +} + +//============================================================================ +// +// SetMaybeFileHdl +// +//============================================================================ + +namespace { struct MaybeFileHdl : public rtl::Static< Link, MaybeFileHdl > {}; } + +void URIHelper::SetMaybeFileHdl(Link const & rTheMaybeFileHdl) +{ + MaybeFileHdl::get() = rTheMaybeFileHdl; +} + +//============================================================================ +// +// GetMaybeFileHdl +// +//============================================================================ + +Link URIHelper::GetMaybeFileHdl() +{ + return MaybeFileHdl::get(); +} + +namespace { + +bool isAbsoluteHierarchicalUriReference( + css::uno::Reference< css::uri::XUriReference > const & uriReference) +{ + return uriReference.is() && uriReference->isAbsolute() + && uriReference->isHierarchical() && !uriReference->hasRelativePath(); +} + +// To improve performance, assume that if for any prefix URL of a given +// hierarchical URL either a UCB content cannot be created, or the UCB content +// does not support the getCasePreservingURL command, then this will hold for +// any other prefix URL of the given URL, too: +enum Result { Success, GeneralFailure, SpecificFailure }; + +Result normalizePrefix( + css::uno::Reference< css::ucb::XContentProvider > const & broker, + rtl::OUString const & uri, rtl::OUString * normalized) +{ + OSL_ASSERT(broker.is() && normalized != 0); + css::uno::Reference< css::ucb::XContent > content; + try { + content = broker->queryContent( + css::uno::Reference< css::ucb::XContentIdentifierFactory >( + broker, css::uno::UNO_QUERY_THROW)->createContentIdentifier( + uri)); + } catch (css::ucb::IllegalIdentifierException &) {} + if (!content.is()) { + return GeneralFailure; + } + try { + #if OSL_DEBUG_LEVEL > 0 + bool ok = + #endif + (css::uno::Reference< css::ucb::XCommandProcessor >( + content, css::uno::UNO_QUERY_THROW)->execute( + css::ucb::Command( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "getCasePreservingURL")), + -1, css::uno::Any()), + 0, + css::uno::Reference< css::ucb::XCommandEnvironment >()) + >>= *normalized); + OSL_ASSERT(ok); + } catch (css::uno::RuntimeException &) { + throw; + } catch (css::ucb::UnsupportedCommandException &) { + return GeneralFailure; + } catch (css::uno::Exception &) { + return SpecificFailure; + } + return Success; +} + +rtl::OUString normalize( + css::uno::Reference< css::ucb::XContentProvider > const & broker, + css::uno::Reference< css::uri::XUriReferenceFactory > const & uriFactory, + rtl::OUString const & uriReference) +{ + // normalizePrefix can potentially fail (a typically example being a file + // URL that denotes a non-existing resource); in such a case, try to + // normalize as long a prefix of the given URL as possible (i.e., normalize + // all the existing directories within the path): + rtl::OUString normalized; + sal_Int32 n = uriReference.indexOf('#'); + normalized = n == -1 ? uriReference : uriReference.copy(0, n); + switch (normalizePrefix(broker, normalized, &normalized)) { + case Success: + return n == -1 ? normalized : normalized + uriReference.copy(n); + case GeneralFailure: + return uriReference; + case SpecificFailure: + default: + break; + } + css::uno::Reference< css::uri::XUriReference > ref( + uriFactory->parse(uriReference)); + if (!isAbsoluteHierarchicalUriReference(ref)) { + return uriReference; + } + sal_Int32 count = ref->getPathSegmentCount(); + if (count < 2) { + return uriReference; + } + rtl::OUStringBuffer head(ref->getScheme()); + head.append(static_cast< sal_Unicode >(':')); + if (ref->hasAuthority()) { + head.appendAscii(RTL_CONSTASCII_STRINGPARAM("//")); + head.append(ref->getAuthority()); + } + for (sal_Int32 i = count - 1; i > 0; --i) { + rtl::OUStringBuffer buf(head); + for (sal_Int32 j = 0; j < i; ++j) { + buf.append(static_cast< sal_Unicode >('/')); + buf.append(ref->getPathSegment(j)); + } + normalized = buf.makeStringAndClear(); + if (normalizePrefix(broker, normalized, &normalized) != SpecificFailure) + { + buf.append(normalized); + css::uno::Reference< css::uri::XUriReference > preRef( + uriFactory->parse(normalized)); + if (!isAbsoluteHierarchicalUriReference(preRef)) { + // This could only happen if something is inconsistent: + break; + } + sal_Int32 preCount = preRef->getPathSegmentCount(); + // normalizePrefix may have added or removed a final slash: + if (preCount != i) { + if (preCount == i - 1) { + buf.append(static_cast< sal_Unicode >('/')); + } else if (preCount - 1 == i && buf.getLength() > 0 + && buf.charAt(buf.getLength() - 1) == '/') + { + buf.setLength(buf.getLength() - 1); + } else { + // This could only happen if something is inconsistent: + break; + } + } + for (sal_Int32 j = i; j < count; ++j) { + buf.append(static_cast< sal_Unicode >('/')); + buf.append(ref->getPathSegment(j)); + } + if (ref->hasQuery()) { + buf.append(static_cast< sal_Unicode >('?')); + buf.append(ref->getQuery()); + } + if (ref->hasFragment()) { + buf.append(static_cast< sal_Unicode >('#')); + buf.append(ref->getFragment()); + } + return buf.makeStringAndClear(); + } + } + return uriReference; +} + +} + +css::uno::Reference< css::uri::XUriReference > +URIHelper::normalizedMakeRelative( + css::uno::Reference< css::uno::XComponentContext > const & context, + rtl::OUString const & baseUriReference, rtl::OUString const & uriReference) +{ + OSL_ASSERT(context.is()); + css::uno::Reference< css::lang::XMultiComponentFactory > componentFactory( + context->getServiceManager()); + if (!componentFactory.is()) { + throw css::uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "component context has no service manager")), + css::uno::Reference< css::uno::XInterface >()); + } + css::uno::Sequence< css::uno::Any > args(2); + args[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local")); + args[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office")); + css::uno::Reference< css::ucb::XContentProvider > broker; + try { + broker = css::uno::Reference< css::ucb::XContentProvider >( + componentFactory->createInstanceWithArgumentsAndContext( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.ucb.UniversalContentBroker")), + args, context), + css::uno::UNO_QUERY_THROW); + } catch (css::uno::RuntimeException &) { + throw; + } catch (css::uno::Exception &) { + css::uno::Any exception(cppu::getCaughtException()); + throw css::lang::WrappedTargetRuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "creating com.sun.star.ucb.UniversalContentBroker failed")), + css::uno::Reference< css::uno::XInterface >(), + exception); + } + css::uno::Reference< css::uri::XUriReferenceFactory > uriFactory( + css::uri::UriReferenceFactory::create(context)); + return uriFactory->makeRelative( + uriFactory->parse(normalize(broker, uriFactory, baseUriReference)), + uriFactory->parse(normalize(broker, uriFactory, uriReference)), true, + true, false); +} + +rtl::OUString URIHelper::simpleNormalizedMakeRelative( + rtl::OUString const & baseUriReference, rtl::OUString const & uriReference) +{ + com::sun::star::uno::Reference< com::sun::star::uri::XUriReference > rel( + URIHelper::normalizedMakeRelative( + com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext >( + (com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySet >( + comphelper::getProcessServiceFactory(), + com::sun::star::uno::UNO_QUERY_THROW)-> + getPropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("DefaultContext")))), + com::sun::star::uno::UNO_QUERY_THROW), + baseUriReference, uriReference)); + return rel.is() ? rel->getUriReference() : uriReference; +} + +//============================================================================ +// +// FindFirstURLInText +// +//============================================================================ + +namespace unnamed_svl_urihelper { + +inline xub_StrLen nextChar(UniString const & rStr, xub_StrLen nPos) +{ + return INetMIME::isHighSurrogate(rStr.GetChar(nPos)) + && rStr.Len() - nPos >= 2 + && INetMIME::isLowSurrogate(rStr.GetChar(nPos + 1)) ? + nPos + 2 : nPos + 1; +} + +bool isBoundary1(CharClass const & rCharClass, UniString const & rStr, + xub_StrLen nPos, xub_StrLen nEnd) +{ + if (nPos == nEnd) + return true; + if (rCharClass.isLetterNumeric(rStr, nPos)) + return false; + switch (rStr.GetChar(nPos)) + { + case '$': + case '%': + case '&': + case '-': + case '/': + case '@': + case '\\': + return false; + default: + return true; + } +} + +bool isBoundary2(CharClass const & rCharClass, UniString const & rStr, + xub_StrLen nPos, xub_StrLen nEnd) +{ + if (nPos == nEnd) + return true; + if (rCharClass.isLetterNumeric(rStr, nPos)) + return false; + switch (rStr.GetChar(nPos)) + { + case '!': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '*': + case '+': + case '-': + case '/': + case '=': + case '?': + case '@': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': + return false; + default: + return true; + } +} + +bool checkWChar(CharClass const & rCharClass, UniString const & rStr, + xub_StrLen * pPos, xub_StrLen * pEnd, bool bBackslash = false, + bool bPipe = false) +{ + sal_Unicode c = rStr.GetChar(*pPos); + if (INetMIME::isUSASCII(c)) + { + static sal_uInt8 const aMap[128] + = { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 4, 4, 4, 1, // !"#$%&' + 1, 1, 1, 1, 1, 4, 1, 4, // ()*+,-./ + 4, 4, 4, 4, 4, 4, 4, 4, // 01234567 + 4, 4, 1, 1, 0, 1, 0, 1, // 89:;<=>? + 4, 4, 4, 4, 4, 4, 4, 4, // @ABCDEFG + 4, 4, 4, 4, 4, 4, 4, 4, // HIJKLMNO + 4, 4, 4, 4, 4, 4, 4, 4, // PQRSTUVW + 4, 4, 4, 1, 2, 1, 0, 1, // XYZ[\]^_ + 0, 4, 4, 4, 4, 4, 4, 4, // `abcdefg + 4, 4, 4, 4, 4, 4, 4, 4, // hijklmno + 4, 4, 4, 4, 4, 4, 4, 4, // pqrstuvw + 4, 4, 4, 0, 3, 0, 1, 0 }; // xyz{|}~ + switch (aMap[c]) + { + default: // not uric + return false; + + case 1: // uric + ++(*pPos); + return true; + + case 2: // "\" + if (bBackslash) + { + *pEnd = ++(*pPos); + return true; + } + else + return false; + + case 3: // "|" + if (bPipe) + { + *pEnd = ++(*pPos); + return true; + } + else + return false; + + case 4: // alpha, digit, "$", "%", "&", "-", "/", "@" (see + // isBoundary1) + *pEnd = ++(*pPos); + return true; + } + } + else if (rCharClass.isLetterNumeric(rStr, *pPos)) + { + *pEnd = *pPos = nextChar(rStr, *pPos); + return true; + } + else + return false; +} + +sal_uInt32 scanDomain(UniString const & rStr, xub_StrLen * pPos, + xub_StrLen nEnd) +{ + sal_Unicode const * pBuffer = rStr.GetBuffer(); + sal_Unicode const * p = pBuffer + *pPos; + sal_uInt32 nLabels = INetURLObject::scanDomain(p, pBuffer + nEnd, false); + *pPos = sal::static_int_cast< xub_StrLen >(p - pBuffer); + return nLabels; +} + +} + +UniString +URIHelper::FindFirstURLInText(UniString const & rText, + xub_StrLen & rBegin, + xub_StrLen & rEnd, + CharClass const & rCharClass, + INetURLObject::EncodeMechanism eMechanism, + rtl_TextEncoding eCharset, + INetURLObject::FSysStyle eStyle) +{ + if (!(rBegin <= rEnd && rEnd <= rText.Len())) + return UniString(); + + // Search for the first substring of [rBegin..rEnd[ that matches any of the + // following productions (for which the appropriate style bit is set in + // eStyle, if applicable). + // + // 1st Production (known scheme): + // \B1 <one of the known schemes, except file> ":" 1*wchar ["#" 1*wchar] + // \B1 + // + // 2nd Production (file): + // \B1 "FILE:" 1*(wchar / "\" / "|") ["#" 1*wchar] \B1 + // + // 3rd Production (ftp): + // \B1 "FTP" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1 + // + // 4th Production (http): + // \B1 "WWW" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1 + // + // 5th Production (mailto): + // \B2 local-part "@" domain \B1 + // + // 6th Production (UNC file): + // \B1 "\\" domain "\" *(wchar / "\") \B1 + // + // 7th Production (DOS file): + // \B1 ALPHA ":\" *(wchar / "\") \B1 + // + // 8th Production (Unix-like DOS file): + // \B1 ALPHA ":/" *(wchar / "\") \B1 + // + // The productions use the following auxiliary rules. + // + // local-part = atom *("." atom) + // atom = 1*(alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" + // / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" + // / "~") + // domain = label *("." label) + // label = alphanum [*(alphanum / "-") alphanum] + // alphanum = ALPHA / DIGIT + // wchar = <any uric character (ignoring the escaped rule), or "%", or + // a letter or digit (according to rCharClass)> + // + // "\B1" (boundary 1) stands for the beginning or end of the block of text, + // or a character that is neither (a) a letter or digit (according to + // rCharClass), nor (b) any of "$", "%", "&", "-", "/", "@", or "\". + // (FIXME: What was the rationale for this set of punctuation characters?) + // + // "\B2" (boundary 2) stands for the beginning or end of the block of text, + // or a character that is neither (a) a letter or digit (according to + // rCharClass), nor (b) any of "!", "#", "$", "%", "&", "'", "*", "+", "-", + // "/", "=", "?", "@", "^", "_", "`", "{", "|", "}", or "~" (i.e., an RFC + // 822 <atom> character, or "@" from \B1's set above). + // + // Productions 1--4, and 6--8 try to find a maximum-length match, but they + // stop at the first <wchar> character that is a "\B1" character which is + // only followed by "\B1" characters (taking "\" and "|" characters into + // account appropriately). Production 5 simply tries to find a maximum- + // length match. + // + // Productions 1--4 use the given eMechanism and eCharset. Productions 5--9 + // use ENCODE_ALL. + // + // Productions 6--9 are only applicable if the FSYS_DOS bit is set in + // eStyle. + + bool bBoundary1 = true; + bool bBoundary2 = true; + for (xub_StrLen nPos = rBegin; nPos != rEnd; nPos = nextChar(rText, nPos)) + { + sal_Unicode c = rText.GetChar(nPos); + if (bBoundary1) + { + if (INetMIME::isAlpha(c)) + { + xub_StrLen i = nPos; + INetProtocol eScheme + = INetURLObject::CompareProtocolScheme(UniString(rText, i, + rEnd)); + if (eScheme == INET_PROT_FILE) // 2nd + { + while (rText.GetChar(i++) != ':') ; + xub_StrLen nPrefixEnd = i; + xub_StrLen nUriEnd = i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd, true, + true)) ; + if (i != nPrefixEnd && rText.GetChar(i) == '#') + { + ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (nUriEnd != nPrefixEnd + && isBoundary1(rCharClass, rText, nUriEnd, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_FILE, eMechanism, eCharset, + eStyle); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + else if (eScheme != INET_PROT_NOT_VALID) // 1st + { + while (rText.GetChar(i++) != ':') ; + xub_StrLen nPrefixEnd = i; + xub_StrLen nUriEnd = i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + if (i != nPrefixEnd && rText.GetChar(i) == '#') + { + ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (nUriEnd != nPrefixEnd + && (isBoundary1(rCharClass, rText, nUriEnd, rEnd) + || rText.GetChar(nUriEnd) == '\\')) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_HTTP, eMechanism, + eCharset); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + + // 3rd, 4th: + i = nPos; + sal_uInt32 nLabels = scanDomain(rText, &i, rEnd); + if (nLabels >= 3 + && rText.GetChar(nPos + 3) == '.' + && (((rText.GetChar(nPos) == 'w' + || rText.GetChar(nPos) == 'W') + && (rText.GetChar(nPos + 1) == 'w' + || rText.GetChar(nPos + 1) == 'W') + && (rText.GetChar(nPos + 2) == 'w' + || rText.GetChar(nPos + 2) == 'W')) + || ((rText.GetChar(nPos) == 'f' + || rText.GetChar(nPos) == 'F') + && (rText.GetChar(nPos + 1) == 't' + || rText.GetChar(nPos + 1) == 'T') + && (rText.GetChar(nPos + 2) == 'p' + || rText.GetChar(nPos + 2) == 'P')))) + // (note that rText.GetChar(nPos + 3) is guaranteed to be + // valid) + { + xub_StrLen nUriEnd = i; + if (i != rEnd && rText.GetChar(i) == '/') + { + nUriEnd = ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (i != rEnd && rText.GetChar(i) == '#') + { + ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (isBoundary1(rCharClass, rText, nUriEnd, rEnd) + || rText.GetChar(nUriEnd) == '\\') + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_HTTP, eMechanism, + eCharset); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + + if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 3 + && rText.GetChar(nPos + 1) == ':' + && (rText.GetChar(nPos + 2) == '/' + || rText.GetChar(nPos + 2) == '\\')) // 7th, 8th + { + i = nPos + 3; + xub_StrLen nUriEnd = i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + if (isBoundary1(rCharClass, rText, nUriEnd, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_FILE, + INetURLObject::ENCODE_ALL, + RTL_TEXTENCODING_UTF8, + INetURLObject::FSYS_DOS); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + } + else if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 2 + && rText.GetChar(nPos) == '\\' + && rText.GetChar(nPos + 1) == '\\') // 6th + { + xub_StrLen i = nPos + 2; + sal_uInt32 nLabels = scanDomain(rText, &i, rEnd); + if (nLabels >= 1 && i != rEnd && rText.GetChar(i) == '\\') + { + xub_StrLen nUriEnd = ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd, + true)) ; + if (isBoundary1(rCharClass, rText, nUriEnd, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_FILE, + INetURLObject::ENCODE_ALL, + RTL_TEXTENCODING_UTF8, + INetURLObject::FSYS_DOS); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + } + } + if (bBoundary2 && INetMIME::isAtomChar(c)) // 5th + { + bool bDot = false; + for (xub_StrLen i = nPos + 1; i != rEnd; ++i) + { + sal_Unicode c2 = rText.GetChar(i); + if (INetMIME::isAtomChar(c2)) + bDot = false; + else if (bDot) + break; + else if (c2 == '.') + bDot = true; + else + { + if (c2 == '@') + { + ++i; + sal_uInt32 nLabels = scanDomain(rText, &i, rEnd); + if (nLabels >= 1 + && isBoundary1(rCharClass, rText, i, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, i - nPos), + INET_PROT_MAILTO, + INetURLObject::ENCODE_ALL); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = i; + return aUri.GetMainURL( + INetURLObject::DECODE_TO_IURI); + } + } + } + break; + } + } + } + bBoundary1 = isBoundary1(rCharClass, rText, nPos, rEnd); + bBoundary2 = isBoundary2(rCharClass, rText, nPos, rEnd); + } + rBegin = rEnd; + return UniString(); +} + +//============================================================================ +// +// removePassword +// +//============================================================================ + +UniString +URIHelper::removePassword(UniString const & rURI, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset) +{ + INetURLObject aObj(rURI, eEncodeMechanism, eCharset); + return aObj.HasError() ? + rURI : + String(aObj.GetURLNoPass(eDecodeMechanism, eCharset)); +} + +//============================================================================ +// +// queryFSysStyle +// +//============================================================================ + +INetURLObject::FSysStyle URIHelper::queryFSysStyle(UniString const & rFileUrl, + bool bAddConvenienceStyles) + throw (uno::RuntimeException) +{ + ::ucbhelper::ContentBroker const * pBroker = ::ucbhelper::ContentBroker::get(); + uno::Reference< ucb::XContentProviderManager > xManager; + if (pBroker) + xManager = pBroker->getContentProviderManagerInterface(); + uno::Reference< beans::XPropertySet > xProperties; + if (xManager.is()) + xProperties + = uno::Reference< beans::XPropertySet >( + xManager->queryContentProvider(rFileUrl), uno::UNO_QUERY); + sal_Int32 nNotation = ucb::FileSystemNotation::UNKNOWN_NOTATION; + if (xProperties.is()) + try + { + xProperties->getPropertyValue(rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "FileSystemNotation"))) + >>= nNotation; + } + catch (beans::UnknownPropertyException const &) {} + catch (lang::WrappedTargetException const &) {} + + // The following code depends on the fact that the + // com::sun::star::ucb::FileSystemNotation constants range from UNKNOWN to + // MAC, without any holes. The table below has two entries per notation, + // the first is used if bAddConvenienceStyles == false, while the second + // is used if bAddConvenienceStyles == true: + static INetURLObject::FSysStyle const aMap[][2] + = { { INetURLObject::FSysStyle(0), + INetURLObject::FSYS_DETECT }, + // UNKNOWN + { INetURLObject::FSYS_UNX, + INetURLObject::FSysStyle(INetURLObject::FSYS_VOS + | INetURLObject::FSYS_UNX) }, + // UNIX + { INetURLObject::FSYS_DOS, + INetURLObject::FSysStyle(INetURLObject::FSYS_VOS + | INetURLObject::FSYS_UNX + | INetURLObject::FSYS_DOS) }, + // DOS + { INetURLObject::FSYS_MAC, + INetURLObject::FSysStyle(INetURLObject::FSYS_VOS + | INetURLObject::FSYS_UNX + | INetURLObject::FSYS_MAC) } }; + return aMap[nNotation < ucb::FileSystemNotation::UNKNOWN_NOTATION + || nNotation > ucb::FileSystemNotation::MAC_NOTATION ? + 0 : + nNotation + - ucb::FileSystemNotation::UNKNOWN_NOTATION] + [bAddConvenienceStyles]; +} |