1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include <precomp.h> 29*cdf0e10cSrcweir #include <toolkit/out_position.hxx> 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir // NOT FULLY DEFINED SERVICES 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir namespace output 37*cdf0e10cSrcweir { 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir namespace 42*cdf0e10cSrcweir { 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir const int C_nAssumedMaxLinkLength = 500; 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir void move_ToParent( 47*cdf0e10cSrcweir Node * & io_node, 48*cdf0e10cSrcweir intt i_levels = 1 ); 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir void 51*cdf0e10cSrcweir move_ToParent( Node * & io_node, 52*cdf0e10cSrcweir intt i_levels ) 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir for ( intt n = 0; n < i_levels; ++n ) 55*cdf0e10cSrcweir { 56*cdf0e10cSrcweir csv_assert(io_node != 0); 57*cdf0e10cSrcweir io_node = io_node->Parent(); 58*cdf0e10cSrcweir } 59*cdf0e10cSrcweir } 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir } // namepace anonymous 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir Position::Position() 68*cdf0e10cSrcweir : sFile(), 69*cdf0e10cSrcweir pDirectory(&Node::Null_()) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir } 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir Position::Position( Node & i_directory, 75*cdf0e10cSrcweir const String & i_file ) 76*cdf0e10cSrcweir : sFile(i_file), 77*cdf0e10cSrcweir pDirectory(&i_directory) 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir Position::Position( const Position & i_directory, 82*cdf0e10cSrcweir const String & i_sDifferentFile ) 83*cdf0e10cSrcweir : sFile(i_sDifferentFile), 84*cdf0e10cSrcweir pDirectory(i_directory.pDirectory) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir Position::~Position() 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir Position & 95*cdf0e10cSrcweir Position::operator=( Node & i_node ) 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir pDirectory = &i_node; 98*cdf0e10cSrcweir sFile.clear(); 99*cdf0e10cSrcweir return *this; 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir Position & 103*cdf0e10cSrcweir Position::operator+=( const String & i_nodeName ) 104*cdf0e10cSrcweir { 105*cdf0e10cSrcweir csv_assert(pDirectory != 0); 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir pDirectory = &pDirectory->Provide_Child(i_nodeName); 108*cdf0e10cSrcweir sFile.clear(); 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir return *this; 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir Position & 114*cdf0e10cSrcweir Position::operator-=( intt i_levels ) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir csv_assert(pDirectory != 0); 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir for ( intt i = i_levels; i > 0; --i ) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir pDirectory = pDirectory->Parent(); 121*cdf0e10cSrcweir if (pDirectory == 0) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir pDirectory = &Node::Null_(); 124*cdf0e10cSrcweir i = 0; 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir sFile.clear(); 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir return *this; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir String 133*cdf0e10cSrcweir Position::LinkToRoot( const String & ) const 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir StreamLock sl(C_nAssumedMaxLinkLength); 136*cdf0e10cSrcweir return sl() << get_UpLink(Depth()) << c_str; 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir void 140*cdf0e10cSrcweir Position::Get_LinkTo( StreamStr & o_result, 141*cdf0e10cSrcweir const Position & i_destination, 142*cdf0e10cSrcweir const String & i_localLabel ) const 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir Node * p1 = pDirectory; 145*cdf0e10cSrcweir Node * p2 = i_destination.pDirectory; 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir intt diff = Depth() - i_destination.Depth(); 148*cdf0e10cSrcweir intt pathLength1 = 0; 149*cdf0e10cSrcweir intt pathLength2 = 0; 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir if ( diff > 0 ) 152*cdf0e10cSrcweir { 153*cdf0e10cSrcweir pathLength1 = diff; 154*cdf0e10cSrcweir move_ToParent(p1,pathLength1); 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir else if ( diff < 0 ) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir pathLength2 = -diff; 159*cdf0e10cSrcweir move_ToParent(p2,pathLength2); 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir while ( p1 != p2 ) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir move_ToParent(p1); 165*cdf0e10cSrcweir move_ToParent(p2); 166*cdf0e10cSrcweir ++pathLength1; 167*cdf0e10cSrcweir ++pathLength2; 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir o_result << get_UpLink(pathLength1); 171*cdf0e10cSrcweir i_destination.pDirectory->Get_Path(o_result, pathLength2); 172*cdf0e10cSrcweir o_result << i_destination.sFile; 173*cdf0e10cSrcweir if (i_localLabel.length()) 174*cdf0e10cSrcweir o_result << "#" << i_localLabel; 175*cdf0e10cSrcweir } 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir void 178*cdf0e10cSrcweir Position::Get_LinkToRoot( StreamStr & o_result, 179*cdf0e10cSrcweir const String & ) const 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir o_result << get_UpLink(Depth()); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir void 185*cdf0e10cSrcweir Position::Set( Node & i_node, 186*cdf0e10cSrcweir const String & i_file ) 187*cdf0e10cSrcweir { 188*cdf0e10cSrcweir sFile = i_file; 189*cdf0e10cSrcweir pDirectory = &i_node; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir const char * 196*cdf0e10cSrcweir get_UpLink(uintt i_depth) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir static const uintt 199*cdf0e10cSrcweir C_nMaxDepth = 30; 200*cdf0e10cSrcweir static const char 201*cdf0e10cSrcweir C_sUpLinkArray[3*C_nMaxDepth+1] = 202*cdf0e10cSrcweir "../../../../../../../../../../" 203*cdf0e10cSrcweir "../../../../../../../../../../" 204*cdf0e10cSrcweir "../../../../../../../../../../"; 205*cdf0e10cSrcweir static const char * 206*cdf0e10cSrcweir C_sUpLink = &C_sUpLinkArray[0]; 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir if ( i_depth <= C_nMaxDepth ) 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir return C_sUpLink + 3*(C_nMaxDepth - i_depth); 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir else 213*cdf0e10cSrcweir { // not THREAD fast 214*cdf0e10cSrcweir static std::vector<char> 215*cdf0e10cSrcweir aRet; 216*cdf0e10cSrcweir uintt nNeededSize = i_depth * 3 + 1; 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir if (aRet.size() < nNeededSize) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir aRet.resize(nNeededSize); 221*cdf0e10cSrcweir char * pEnd = &aRet[nNeededSize-1]; 222*cdf0e10cSrcweir *pEnd = '\0'; 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir for ( char * pFill = &(*aRet.begin()); 225*cdf0e10cSrcweir pFill != pEnd; 226*cdf0e10cSrcweir pFill += 3 ) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir memcpy(pFill, C_sUpLink, 3); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir } // end if 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir return &aRet[aRet.size() - 1 - 3*i_depth]; 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir } // namespace output 240