1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/core/relations.hxx"
22 #include <rtl/ustrbuf.hxx>
23 #include "oox/helper/helper.hxx"
28 // ============================================================================
31 // ============================================================================
35 OUString
lclRemoveFileName( const OUString
& rPath
)
37 return rPath
.copy( 0, ::std::max
< sal_Int32
>( rPath
.lastIndexOf( '/' ), 0 ) );
40 OUString
lclAppendFileName( const OUString
& rPath
, const OUString
& rFileName
)
42 return rPath
.isEmpty() ? rFileName
:
43 OUStringBuffer( rPath
).append( '/' ).append( rFileName
).makeStringAndClear();
48 // ============================================================================
50 Relations::Relations( const OUString
& rFragmentPath
) :
51 maFragmentPath( rFragmentPath
)
55 const Relation
* Relations::getRelationFromRelId( const OUString
& rId
) const
57 const_iterator aIt
= find( rId
);
58 return (aIt
== end()) ? 0 : &aIt
->second
;
61 const Relation
* Relations::getRelationFromFirstType( const OUString
& rType
) const
63 for( const_iterator aIt
= begin(), aEnd
= end(); aIt
!= aEnd
; ++aIt
)
64 if( aIt
->second
.maType
.equalsIgnoreAsciiCase( rType
) )
69 RelationsRef
Relations::getRelationsFromType( const OUString
& rType
) const
71 RelationsRef
xRelations( new Relations( maFragmentPath
) );
72 for( const_iterator aIt
= begin(), aEnd
= end(); aIt
!= aEnd
; ++aIt
)
73 if( aIt
->second
.maType
.equalsIgnoreAsciiCase( rType
) )
74 (*xRelations
)[ aIt
->first
] = aIt
->second
;
78 OUString
Relations::getExternalTargetFromRelId( const OUString
& rRelId
) const
80 const Relation
* pRelation
= getRelationFromRelId( rRelId
);
81 return (pRelation
&& pRelation
->mbExternal
) ? pRelation
->maTarget
: OUString();
84 OUString
Relations::getInternalTargetFromRelId( const OUString
& rRelId
) const
86 const Relation
* pRelation
= getRelationFromRelId( rRelId
);
87 return (pRelation
&& !pRelation
->mbExternal
) ? pRelation
->maTarget
: OUString();
90 OUString
Relations::getFragmentPathFromRelation( const Relation
& rRelation
) const
92 // no target, no fragment path
93 if( rRelation
.mbExternal
|| rRelation
.maTarget
.isEmpty() )
96 // absolute target: return it without leading slash (#i100978)
97 if( rRelation
.maTarget
[ 0 ] == '/' )
98 return rRelation
.maTarget
.copy( 1 );
100 // empty fragment path: return target
101 if( maFragmentPath
.isEmpty() )
102 return rRelation
.maTarget
;
104 // resolve relative target path according to base path
105 OUString aPath
= lclRemoveFileName( maFragmentPath
);
106 sal_Int32 nStartPos
= 0;
107 while( nStartPos
< rRelation
.maTarget
.getLength() )
109 sal_Int32 nSepPos
= rRelation
.maTarget
.indexOf( '/', nStartPos
);
110 if( nSepPos
< 0 ) nSepPos
= rRelation
.maTarget
.getLength();
111 // append next directory name from aTarget to aPath, or remove last directory on '../'
112 if( (nStartPos
+ 2 == nSepPos
) && (rRelation
.maTarget
[ nStartPos
] == '.') && (rRelation
.maTarget
[ nStartPos
+ 1 ] == '.') )
113 aPath
= lclRemoveFileName( aPath
);
115 aPath
= lclAppendFileName( aPath
, rRelation
.maTarget
.copy( nStartPos
, nSepPos
- nStartPos
) );
116 // move nStartPos to next directory name
117 nStartPos
= nSepPos
+ 1;
123 OUString
Relations::getFragmentPathFromRelId( const OUString
& rRelId
) const
125 const Relation
* pRelation
= getRelationFromRelId( rRelId
);
126 return pRelation
? getFragmentPathFromRelation( *pRelation
) : OUString();
129 OUString
Relations::getFragmentPathFromFirstType( const OUString
& rType
) const
131 const Relation
* pRelation
= getRelationFromFirstType( rType
);
132 return pRelation
? getFragmentPathFromRelation( *pRelation
) : OUString();
135 // ============================================================================
140 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */