Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include "sal/config.h"
21 : :
22 : : #include <cassert>
23 : : #include <map>
24 : : #include <set>
25 : :
26 : : #include "com/sun/star/uno/Reference.hxx"
27 : : #include "com/sun/star/uno/RuntimeException.hpp"
28 : : #include "com/sun/star/uno/XInterface.hpp"
29 : : #include "rtl/ustring.h"
30 : : #include "rtl/ustring.hxx"
31 : : #include "sal/types.h"
32 : :
33 : : #include "data.hxx"
34 : : #include "partial.hxx"
35 : :
36 : : namespace configmgr {
37 : :
38 : : namespace {
39 : :
40 : : namespace css = com::sun::star;
41 : :
42 : 0 : bool parseSegment(
43 : : rtl::OUString const & path, sal_Int32 * index, rtl::OUString * segment)
44 : : {
45 : : assert(
46 : : index != 0 && *index >= 0 && *index <= path.getLength() &&
47 : : segment != 0);
48 [ # # ]: 0 : if (path[(*index)++] == '/') {
49 : 0 : rtl::OUString name;
50 : : bool setElement;
51 : 0 : rtl::OUString templateName;
52 : : *index = Data::parseSegment(
53 [ # # ]: 0 : path, *index, &name, &setElement, &templateName);
54 [ # # ]: 0 : if (*index != -1) {
55 [ # # ]: 0 : *segment = Data::createSegment(templateName, name);
56 : 0 : return *index == path.getLength();
57 [ # # ][ # # ]: 0 : }
58 : : }
59 : : throw css::uno::RuntimeException(
60 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad path ")) + path,
61 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
62 : : }
63 : :
64 : : }
65 : :
66 : 0 : Partial::Partial(
67 : : std::set< rtl::OUString > const & includedPaths,
68 [ # # ]: 0 : std::set< rtl::OUString > const & excludedPaths)
69 : : {
70 : : // The Partial::Node tree built up here encodes the following information:
71 : : // * Inner node, startInclude: an include starts here that contains excluded
72 : : // sub-trees
73 : : // * Inner node, !startInclude: contains in-/excluded sub-trees
74 : : // * Leaf node, startInclude: an include starts here
75 : : // * Leaf node, !startInclude: an exclude starts here
76 [ # # ]: 0 : for (std::set< rtl::OUString >::const_iterator i(includedPaths.begin());
77 : 0 : i != includedPaths.end(); ++i)
78 : : {
79 : 0 : sal_Int32 n = 0;
80 : 0 : for (Node * p = &root_;;) {
81 : 0 : rtl::OUString seg;
82 [ # # ]: 0 : bool end = parseSegment(*i, &n, &seg);
83 [ # # ]: 0 : p = &p->children[seg];
84 [ # # ]: 0 : if (p->startInclude) {
85 : : break;
86 : : }
87 [ # # ]: 0 : if (end) {
88 : 0 : p->children.clear();
89 : 0 : p->startInclude = true;
90 : : break;
91 : : }
92 [ # # ]: 0 : }
93 : : }
94 [ # # ]: 0 : for (std::set< rtl::OUString >::const_iterator i(excludedPaths.begin());
95 : 0 : i != excludedPaths.end(); ++i)
96 : : {
97 : 0 : sal_Int32 n = 0;
98 : 0 : for (Node * p = &root_;;) {
99 : 0 : rtl::OUString seg;
100 [ # # ]: 0 : bool end = parseSegment(*i, &n, &seg);
101 [ # # ]: 0 : if (end) {
102 [ # # ][ # # ]: 0 : p->children[seg] = Node();
[ # # ]
103 : : break;
104 : : }
105 [ # # ]: 0 : Node::Children::iterator j(p->children.find(seg));
106 [ # # ]: 0 : if (j == p->children.end()) {
107 : : break;
108 : : }
109 [ # # ]: 0 : p = &j->second;
110 : 0 : }
111 : : }
112 : 0 : }
113 : :
114 : 0 : Partial::~Partial() {}
115 : :
116 : 0 : Partial::Containment Partial::contains(Path const & path) const {
117 : : //TODO: For set elements, the segment names recorded in the node tree need
118 : : // not match the corresponding path segments, so this function can fail.
119 : :
120 : : // * If path ends at a leaf node or goes past a leaf node:
121 : : // ** If that leaf node is startInclude: => CONTAINS_NODE
122 : : // ** If that leaf node is !startInclude: => CONTAINS_NOT
123 : : // * If path ends at inner node:
124 : : // ** If there is some startInclude along its trace: => CONTAINS_NODE
125 : : // ** If there is no startInclude along its trace: => CONTAINS_SUBNODES
126 : 0 : Node const * p = &root_;
127 : 0 : bool includes = false;
128 [ # # ][ # # ]: 0 : for (Path::const_iterator i(path.begin()); i != path.end(); ++i) {
129 [ # # ]: 0 : Node::Children::const_iterator j(p->children.find(*i));
130 [ # # ]: 0 : if (j == p->children.end()) {
131 [ # # ]: 0 : return p->startInclude ? CONTAINS_NODE : CONTAINS_NOT;
132 : : }
133 : 0 : p = &j->second;
134 : 0 : includes |= p->startInclude;
135 : : }
136 : 0 : return p->children.empty() && !p->startInclude
137 : : ? CONTAINS_NOT
138 [ # # ][ # # ]: 0 : : includes ? CONTAINS_NODE : CONTAINS_SUBNODES;
[ # # ]
139 : : }
140 : :
141 : : }
142 : :
143 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|