summaryrefslogtreecommitdiff
path: root/svl/source/misc
diff options
context:
space:
mode:
Diffstat (limited to 'svl/source/misc')
-rw-r--r--svl/source/misc/PasswordHelper.cxx106
-rw-r--r--svl/source/misc/adrparse.cxx918
-rw-r--r--svl/source/misc/documentlockfile.cxx234
-rw-r--r--svl/source/misc/filenotation.cxx144
-rw-r--r--svl/source/misc/folderrestriction.cxx106
-rw-r--r--svl/source/misc/fstathelper.cxx100
-rw-r--r--svl/source/misc/inethist.cxx542
-rw-r--r--svl/source/misc/inettype.cxx1345
-rw-r--r--svl/source/misc/lngmisc.cxx138
-rw-r--r--svl/source/misc/lockfilecommon.cxx272
-rw-r--r--svl/source/misc/makefile.mk70
-rw-r--r--svl/source/misc/mediatyp.src607
-rw-r--r--svl/source/misc/ownlist.cxx327
-rw-r--r--svl/source/misc/restrictedpaths.cxx214
-rw-r--r--svl/source/misc/sharecontrolfile.cxx373
-rw-r--r--svl/source/misc/strmadpt.cxx1045
-rw-r--r--svl/source/misc/svldata.cxx91
-rw-r--r--svl/source/misc/urihelper.cxx949
18 files changed, 7581 insertions, 0 deletions
diff --git a/svl/source/misc/PasswordHelper.cxx b/svl/source/misc/PasswordHelper.cxx
new file mode 100644
index 000000000000..05e9e8a65897
--- /dev/null
+++ b/svl/source/misc/PasswordHelper.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..fc230856ef7d
--- /dev/null
+++ b/svl/source/misc/adrparse.cxx
@@ -0,0 +1,918 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..0e04a3fd7ae0
--- /dev/null
+++ b/svl/source/misc/documentlockfile.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..abec6bb310fc
--- /dev/null
+++ b/svl/source/misc/filenotation.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..ae50ed3cd55a
--- /dev/null
+++ b/svl/source/misc/folderrestriction.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..329912f9d997
--- /dev/null
+++ b/svl/source/misc/fstathelper.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..28986aca1194
--- /dev/null
+++ b/svl/source/misc/inethist.cxx
@@ -0,0 +1,542 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..bec8b91e7c22
--- /dev/null
+++ b/svl/source/misc/inettype.cxx
@@ -0,0 +1,1345 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..2203cc08458e
--- /dev/null
+++ b/svl/source/misc/lngmisc.cxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..aed62ce30737
--- /dev/null
+++ b/svl/source/misc/lockfilecommon.cxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..a68cb396f22c
--- /dev/null
+++ b/svl/source/misc/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# 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..195b2c640d67
--- /dev/null
+++ b/svl/source/misc/mediatyp.src
@@ -0,0 +1,607 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..9fd767c2253f
--- /dev/null
+++ b/svl/source/misc/ownlist.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..8c6f136f3eee
--- /dev/null
+++ b/svl/source/misc/restrictedpaths.cxx
@@ -0,0 +1,214 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..b7b4f24141dd
--- /dev/null
+++ b/svl/source/misc/sharecontrolfile.cxx
@@ -0,0 +1,373 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..9811618eb571
--- /dev/null
+++ b/svl/source/misc/strmadpt.cxx
@@ -0,0 +1,1045 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..35c9fca3aef2
--- /dev/null
+++ b/svl/source/misc/svldata.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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..a3a3f63367c1
--- /dev/null
+++ b/svl/source/misc/urihelper.cxx
@@ -0,0 +1,949 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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];
+}