tdf#124384 sw DOCX: fix crash during bibliography loading
[LibreOffice.git] / unoidl / source / sourcefileprovider.cxx
blobc538f8553b90a8d8b30214e5276bf8350f6c7961
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
12 #include <map>
13 #include <utility>
14 #include <vector>
16 #include "sourcefileprovider.hxx"
17 #include "sourceprovider-scanner.hxx"
19 namespace unoidl { namespace detail {
21 namespace {
23 class Cursor: public MapCursor {
24 public:
25 explicit Cursor(std::map< OUString, rtl::Reference<Entity> > const & map):
26 map_(map), iterator_(map_.begin())
29 private:
30 virtual ~Cursor() throw () override {}
32 virtual rtl::Reference< Entity > getNext(OUString * name) override;
34 std::map< OUString, rtl::Reference<Entity> > const & map_; //TODO: extent
35 std::map< OUString, rtl::Reference<Entity> >::const_iterator iterator_;
38 rtl::Reference< Entity > Cursor::getNext(OUString * name) {
39 assert(name != nullptr);
40 rtl::Reference< Entity > ent;
41 if (iterator_ != map_.end()) {
42 *name = iterator_->first;
43 ent = iterator_->second;
44 ++iterator_;
46 return ent;
49 class Module: public ModuleEntity {
50 public:
51 Module() {}
53 std::map< OUString, rtl::Reference<Entity> > map;
55 private:
56 virtual ~Module() throw () override {}
58 virtual std::vector<OUString> getMemberNames() const override;
60 virtual rtl::Reference<MapCursor> createCursor() const override
61 { return new Cursor(map); }
64 std::vector<OUString> Module::getMemberNames() const {
65 std::vector<OUString> names;
66 for (auto & i: map) {
67 names.push_back(i.first);
69 return names;
74 SourceFileProvider::SourceFileProvider(
75 rtl::Reference<Manager> const & manager, OUString const & uri)
77 SourceProviderScannerData data(manager);
78 if (!parse(uri, &data)) {
79 throw NoSuchFileException(uri);
81 for (auto & i: data.entities) {
82 if (i.second.kind == SourceProviderEntity::KIND_LOCAL) {
83 assert(i.second.entity.is());
84 assert(i.second.entity->getSort() != Entity::SORT_MODULE);
85 std::map< OUString, rtl::Reference<Entity> > * map = &rootMap_;
86 for (sal_Int32 j = 0;;) {
87 OUString id(i.first.getToken(0, '.', j));
88 if (j == -1) {
89 map->insert(std::make_pair(id, i.second.entity));
90 break;
92 std::map< OUString, rtl::Reference<Entity> >::const_iterator k(
93 map->find(id));
94 if (k == map->end()) {
95 k = map->insert(std::make_pair(id, new Module)).first;
97 Module& mod = dynamic_cast<Module&>(*k->second);
98 map = &mod.map;
104 rtl::Reference<MapCursor> SourceFileProvider::createRootCursor() const {
105 return new Cursor(rootMap_);
108 rtl::Reference<Entity> SourceFileProvider::findEntity(OUString const & name)
109 const
111 std::map< OUString, rtl::Reference<Entity> > const * map = &rootMap_;
112 for (sal_Int32 i = 0;;) {
113 OUString id(name.getToken(0, '.', i));
114 std::map< OUString, rtl::Reference<Entity> >::const_iterator j(
115 map->find(id));
116 if (j == map->end()) {
117 return rtl::Reference<Entity>();
119 if (i == -1) {
120 return j->second;
122 if (j->second->getSort() != Entity::SORT_MODULE) {
123 return rtl::Reference<Entity>();
125 Module * mod = dynamic_cast< Module * >(j->second.get());
126 assert(mod != nullptr);
127 map = &mod->map;
131 SourceFileProvider::~SourceFileProvider() throw () {}
135 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */