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