1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #include "precompiled_desktop.hxx"
25*b1cdbd2cSJim Jagielski 
26*b1cdbd2cSJim Jagielski #include "sal/config.h"
27*b1cdbd2cSJim Jagielski 
28*b1cdbd2cSJim Jagielski #include <cstddef>
29*b1cdbd2cSJim Jagielski #include <utility>
30*b1cdbd2cSJim Jagielski #include <vector>
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski #include "osl/diagnose.h"
33*b1cdbd2cSJim Jagielski #include "rtl/strbuf.hxx"
34*b1cdbd2cSJim Jagielski #include "rtl/string.hxx"
35*b1cdbd2cSJim Jagielski #include "rtl/textenc.h"
36*b1cdbd2cSJim Jagielski #include "rtl/uri.h"
37*b1cdbd2cSJim Jagielski #include "rtl/uri.hxx"
38*b1cdbd2cSJim Jagielski #include "rtl/ustring.hxx"
39*b1cdbd2cSJim Jagielski #include <hash_map>
40*b1cdbd2cSJim Jagielski 
41*b1cdbd2cSJim Jagielski #include "dp_identifier.hxx"
42*b1cdbd2cSJim Jagielski #include "dp_persmap.h"
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski #include "dp_activepackages.hxx"
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski // Old format of database entry:
47*b1cdbd2cSJim Jagielski //   key: UTF8(filename)
48*b1cdbd2cSJim Jagielski //   value: UTF8(tempname ";" mediatype)
49*b1cdbd2cSJim Jagielski // New format of database entry:
50*b1cdbd2cSJim Jagielski //   key: 0xFF UTF8(identifier)
51*b1cdbd2cSJim Jagielski //   value: UTF8(tempname) 0xFF UTF8(filename) 0xFF UTF8(mediatype)
52*b1cdbd2cSJim Jagielski 
53*b1cdbd2cSJim Jagielski namespace {
54*b1cdbd2cSJim Jagielski 
55*b1cdbd2cSJim Jagielski static char const separator = static_cast< char >(
56*b1cdbd2cSJim Jagielski     static_cast< unsigned char >(0xFF));
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski static char const legacyPrefix[] = "org.openoffice.legacy.";
59*b1cdbd2cSJim Jagielski 
oldKey(::rtl::OUString const & fileName)60*b1cdbd2cSJim Jagielski ::rtl::OString oldKey(::rtl::OUString const & fileName) {
61*b1cdbd2cSJim Jagielski     return ::rtl::OUStringToOString(fileName, RTL_TEXTENCODING_UTF8);
62*b1cdbd2cSJim Jagielski }
63*b1cdbd2cSJim Jagielski 
newKey(::rtl::OUString const & id)64*b1cdbd2cSJim Jagielski ::rtl::OString newKey(::rtl::OUString const & id) {
65*b1cdbd2cSJim Jagielski     ::rtl::OStringBuffer b;
66*b1cdbd2cSJim Jagielski     b.append(separator);
67*b1cdbd2cSJim Jagielski     b.append(::rtl::OUStringToOString(id, RTL_TEXTENCODING_UTF8));
68*b1cdbd2cSJim Jagielski     return b.makeStringAndClear();
69*b1cdbd2cSJim Jagielski }
70*b1cdbd2cSJim Jagielski 
decodeOldData(::rtl::OUString const & fileName,::rtl::OString const & value)71*b1cdbd2cSJim Jagielski ::dp_manager::ActivePackages::Data decodeOldData(
72*b1cdbd2cSJim Jagielski     ::rtl::OUString const & fileName, ::rtl::OString const & value)
73*b1cdbd2cSJim Jagielski {
74*b1cdbd2cSJim Jagielski     ::dp_manager::ActivePackages::Data d;
75*b1cdbd2cSJim Jagielski     sal_Int32 i = value.indexOf(';');
76*b1cdbd2cSJim Jagielski     OSL_ASSERT(i >= 0);
77*b1cdbd2cSJim Jagielski     d.temporaryName = ::rtl::OUString(value.getStr(), i, RTL_TEXTENCODING_UTF8);
78*b1cdbd2cSJim Jagielski     d.fileName = fileName;
79*b1cdbd2cSJim Jagielski     d.mediaType = ::rtl::OUString(
80*b1cdbd2cSJim Jagielski         value.getStr() + i + 1, value.getLength() - i - 1,
81*b1cdbd2cSJim Jagielski         RTL_TEXTENCODING_UTF8);
82*b1cdbd2cSJim Jagielski     return d;
83*b1cdbd2cSJim Jagielski }
84*b1cdbd2cSJim Jagielski 
decodeNewData(::rtl::OString const & value)85*b1cdbd2cSJim Jagielski ::dp_manager::ActivePackages::Data decodeNewData(::rtl::OString const & value) {
86*b1cdbd2cSJim Jagielski     ::dp_manager::ActivePackages::Data d;
87*b1cdbd2cSJim Jagielski     sal_Int32 i1 = value.indexOf(separator);
88*b1cdbd2cSJim Jagielski     OSL_ASSERT(i1 >= 0);
89*b1cdbd2cSJim Jagielski     d.temporaryName = ::rtl::OUString(
90*b1cdbd2cSJim Jagielski         value.getStr(), i1, RTL_TEXTENCODING_UTF8);
91*b1cdbd2cSJim Jagielski     sal_Int32 i2 = value.indexOf(separator, i1 + 1);
92*b1cdbd2cSJim Jagielski     OSL_ASSERT(i2 >= 0);
93*b1cdbd2cSJim Jagielski     d.fileName = ::rtl::OUString(
94*b1cdbd2cSJim Jagielski         value.getStr() + i1 + 1, i2 - i1 - 1, RTL_TEXTENCODING_UTF8);
95*b1cdbd2cSJim Jagielski     sal_Int32 i3 = value.indexOf(separator, i2 + 1);
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski     if (i3 < 0)
98*b1cdbd2cSJim Jagielski     {
99*b1cdbd2cSJim Jagielski         //Before ActivePackages::Data::version was added
100*b1cdbd2cSJim Jagielski         d.mediaType = ::rtl::OUString(
101*b1cdbd2cSJim Jagielski             value.getStr() + i2 + 1, value.getLength() - i2 - 1,
102*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_UTF8);
103*b1cdbd2cSJim Jagielski     }
104*b1cdbd2cSJim Jagielski     else
105*b1cdbd2cSJim Jagielski     {
106*b1cdbd2cSJim Jagielski         sal_Int32 i4 = value.indexOf(separator, i3 + 1);
107*b1cdbd2cSJim Jagielski         d.mediaType = ::rtl::OUString(
108*b1cdbd2cSJim Jagielski             value.getStr() + i2 + 1, i3 - i2 -1, RTL_TEXTENCODING_UTF8);
109*b1cdbd2cSJim Jagielski         d.version = ::rtl::OUString(
110*b1cdbd2cSJim Jagielski             value.getStr() + i3 + 1, i4 - i3 - 1,
111*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_UTF8);
112*b1cdbd2cSJim Jagielski         d.failedPrerequisites = ::rtl::OUString(
113*b1cdbd2cSJim Jagielski             value.getStr() + i4 + 1, value.getLength() - i4 - 1,
114*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_UTF8);
115*b1cdbd2cSJim Jagielski     }
116*b1cdbd2cSJim Jagielski     return d;
117*b1cdbd2cSJim Jagielski }
118*b1cdbd2cSJim Jagielski 
119*b1cdbd2cSJim Jagielski }
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski namespace dp_manager {
122*b1cdbd2cSJim Jagielski 
ActivePackages()123*b1cdbd2cSJim Jagielski ActivePackages::ActivePackages() {}
124*b1cdbd2cSJim Jagielski 
ActivePackages(::rtl::OUString const & url,bool readOnly)125*b1cdbd2cSJim Jagielski ActivePackages::ActivePackages(::rtl::OUString const & url, bool readOnly):
126*b1cdbd2cSJim Jagielski     m_map(url, readOnly) {}
127*b1cdbd2cSJim Jagielski 
~ActivePackages()128*b1cdbd2cSJim Jagielski ActivePackages::~ActivePackages() {}
129*b1cdbd2cSJim Jagielski 
has(::rtl::OUString const & id,::rtl::OUString const & fileName) const130*b1cdbd2cSJim Jagielski bool ActivePackages::has(
131*b1cdbd2cSJim Jagielski     ::rtl::OUString const & id, ::rtl::OUString const & fileName) const
132*b1cdbd2cSJim Jagielski {
133*b1cdbd2cSJim Jagielski     return get(NULL, id, fileName);
134*b1cdbd2cSJim Jagielski }
135*b1cdbd2cSJim Jagielski 
get(Data * data,::rtl::OUString const & id,::rtl::OUString const & fileName) const136*b1cdbd2cSJim Jagielski bool ActivePackages::get(
137*b1cdbd2cSJim Jagielski     Data * data, ::rtl::OUString const & id, ::rtl::OUString const & fileName)
138*b1cdbd2cSJim Jagielski     const
139*b1cdbd2cSJim Jagielski {
140*b1cdbd2cSJim Jagielski     ::rtl::OString v;
141*b1cdbd2cSJim Jagielski     if (m_map.get(&v, newKey(id))) {
142*b1cdbd2cSJim Jagielski         if (data != NULL) {
143*b1cdbd2cSJim Jagielski             *data = decodeNewData(v);
144*b1cdbd2cSJim Jagielski         }
145*b1cdbd2cSJim Jagielski         return true;
146*b1cdbd2cSJim Jagielski     } else if (m_map.get(&v, oldKey(fileName))) {
147*b1cdbd2cSJim Jagielski         if (data != NULL) {
148*b1cdbd2cSJim Jagielski             *data = decodeOldData(fileName, v);
149*b1cdbd2cSJim Jagielski         }
150*b1cdbd2cSJim Jagielski         return true;
151*b1cdbd2cSJim Jagielski     } else {
152*b1cdbd2cSJim Jagielski         return false;
153*b1cdbd2cSJim Jagielski     }
154*b1cdbd2cSJim Jagielski }
155*b1cdbd2cSJim Jagielski 
getEntries() const156*b1cdbd2cSJim Jagielski ActivePackages::Entries ActivePackages::getEntries() const {
157*b1cdbd2cSJim Jagielski     Entries es;
158*b1cdbd2cSJim Jagielski     ::dp_misc::t_string2string_map m(m_map.getEntries());
159*b1cdbd2cSJim Jagielski     for (::dp_misc::t_string2string_map::const_iterator i(m.begin());
160*b1cdbd2cSJim Jagielski          i != m.end(); ++i)
161*b1cdbd2cSJim Jagielski     {
162*b1cdbd2cSJim Jagielski         if (i->first.getLength() > 0 && i->first[0] == separator) {
163*b1cdbd2cSJim Jagielski             es.push_back(
164*b1cdbd2cSJim Jagielski                 ::std::make_pair(
165*b1cdbd2cSJim Jagielski                     ::rtl::OUString(
166*b1cdbd2cSJim Jagielski                         i->first.getStr() + 1, i->first.getLength() - 1,
167*b1cdbd2cSJim Jagielski                         RTL_TEXTENCODING_UTF8),
168*b1cdbd2cSJim Jagielski                     decodeNewData(i->second)));
169*b1cdbd2cSJim Jagielski         } else {
170*b1cdbd2cSJim Jagielski             ::rtl::OUString fn(
171*b1cdbd2cSJim Jagielski                 ::rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
172*b1cdbd2cSJim Jagielski             es.push_back(
173*b1cdbd2cSJim Jagielski                 ::std::make_pair(
174*b1cdbd2cSJim Jagielski                     ::dp_misc::generateLegacyIdentifier(fn),
175*b1cdbd2cSJim Jagielski                     decodeOldData(fn, i->second)));
176*b1cdbd2cSJim Jagielski         }
177*b1cdbd2cSJim Jagielski     }
178*b1cdbd2cSJim Jagielski     return es;
179*b1cdbd2cSJim Jagielski }
180*b1cdbd2cSJim Jagielski 
put(::rtl::OUString const & id,Data const & data)181*b1cdbd2cSJim Jagielski void ActivePackages::put(::rtl::OUString const & id, Data const & data) {
182*b1cdbd2cSJim Jagielski     ::rtl::OStringBuffer b;
183*b1cdbd2cSJim Jagielski     b.append(
184*b1cdbd2cSJim Jagielski         ::rtl::OUStringToOString(data.temporaryName, RTL_TEXTENCODING_UTF8));
185*b1cdbd2cSJim Jagielski     b.append(separator);
186*b1cdbd2cSJim Jagielski     b.append(::rtl::OUStringToOString(data.fileName, RTL_TEXTENCODING_UTF8));
187*b1cdbd2cSJim Jagielski     b.append(separator);
188*b1cdbd2cSJim Jagielski     b.append(::rtl::OUStringToOString(data.mediaType, RTL_TEXTENCODING_UTF8));
189*b1cdbd2cSJim Jagielski     b.append(separator);
190*b1cdbd2cSJim Jagielski     b.append(::rtl::OUStringToOString(data.version, RTL_TEXTENCODING_UTF8));
191*b1cdbd2cSJim Jagielski     b.append(separator);
192*b1cdbd2cSJim Jagielski     b.append(::rtl::OUStringToOString(data.failedPrerequisites, RTL_TEXTENCODING_UTF8));
193*b1cdbd2cSJim Jagielski     m_map.put(newKey(id), b.makeStringAndClear());
194*b1cdbd2cSJim Jagielski }
195*b1cdbd2cSJim Jagielski 
erase(::rtl::OUString const & id,::rtl::OUString const & fileName)196*b1cdbd2cSJim Jagielski void ActivePackages::erase(
197*b1cdbd2cSJim Jagielski     ::rtl::OUString const & id, ::rtl::OUString const & fileName)
198*b1cdbd2cSJim Jagielski {
199*b1cdbd2cSJim Jagielski     m_map.erase(newKey(id), true) || m_map.erase(oldKey(fileName), true);
200*b1cdbd2cSJim Jagielski }
201*b1cdbd2cSJim Jagielski 
202*b1cdbd2cSJim Jagielski }
203