LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
EnhancedAnalysisDictionary.cpp
Go to the documentation of this file.
1// Copyright 2002-2015 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
14
15#include <iostream>
16#include <QReadWriteLock>
17#include <QWriteLocker>
18#include <QReadLocker>
19#include <QFileInfo>
20
21using namespace Lima;
22using namespace Lima::Common;
24using namespace Lima::Common::MediaticData;
25using namespace std;
26
27namespace Lima
28{
29
30namespace LinguisticProcessing
31{
32
33namespace AnalysisDict
34{
35
37
38
40{
42
44
47 std::shared_ptr<Lima::Common::AbstractAccessByString> access,
48 const std::string& dataFile);
49
51
52 std::shared_ptr<Lima::Common::AbstractAccessByString> m_access;
53 DictionaryData* m_dicoData;
55 bool m_isMainKeys;
56 // A read/write locker to prevent accessing m_dicoData during its loading
57 QReadWriteLock m_lock;
58};
59
60EnhancedAnalysisDictionaryPrivate::EnhancedAnalysisDictionaryPrivate() :
61 m_access(0),
62 m_dicoData(new DictionaryData()),
63 m_sp(0)
64{
65}
66
67EnhancedAnalysisDictionaryPrivate::EnhancedAnalysisDictionaryPrivate(
69 std::shared_ptr<Lima::Common::AbstractAccessByString> access,
70 const std::string& dataFile) :
71 m_access(access),
72 m_dicoData(new DictionaryData()),
73 m_sp(sp)
74{
75 QWriteLocker locker(&m_lock);
76 m_dicoData->loadBinaryFile(dataFile);
77}
78
79
80EnhancedAnalysisDictionaryPrivate::~EnhancedAnalysisDictionaryPrivate()
81{
82 delete m_dicoData;
83}
84
85
89{
91// LDEBUG << "EnhancedAnalysisDictionary::EnhancedAnalysisDictionary";
92 if (!connect(this,SIGNAL(resourceFileChanged(QString)),this,SLOT(dictionaryFileChanged(QString))))
93 {
94 LIMA_EXCEPTION("Unable to connect resourceFileChanged");
95 }
96
97 if (!dataFilePath.isEmpty())
98 {
99 resourceFileWatcher().addPath(dataFilePath);
100 QWriteLocker locker(&m_d->m_lock);
101 m_d->m_dicoData->loadBinaryFile(dataFilePath.toUtf8().constData());
102 }
103}
104
106 FsaStringsPool* sp,
107 std::shared_ptr<Lima::Common::AbstractAccessByString> access,
108 const std::string& dataFile) :
109 m_d(new EnhancedAnalysisDictionaryPrivate(sp, access, dataFile))
110{
112// LDEBUG << "EnhancedAnalysisDictionary::EnhancedAnalysisDictionary" << dataFile.c_str();
113 if (!connect(this,SIGNAL(resourceFileChanged(QString)),this,SLOT(dictionaryFileChanged(QString))))
114 {
115 LIMA_EXCEPTION("Unable to connect resourceFileChanged");
116 }
117 resourceFileWatcher().addPath(QString::fromUtf8(dataFile.c_str()));
118 QWriteLocker locker(&m_d->m_lock);
119 m_d->m_dicoData->loadBinaryFile(dataFile);
120}
121
122
127
130 Manager* manager)
131{
133 LDEBUG << "EnhancedAnalysisDictionary::init";
134 MediaId language=manager->getInitializationParameters().language;
136 try
137 {
138 string accessId=unitConfiguration.getParamsValueAtKey("accessKeys");
139 auto res = LinguisticResources::single().getResource(language,accessId);
140 auto aar = std::dynamic_pointer_cast<AbstractAccessResource>(res);
141 if (!connect(aar.get(), SIGNAL(accessFileReloaded(std::shared_ptr<Common::AbstractAccessByString>)),
142 this, SLOT(slotAccessFileReloaded(std::shared_ptr<Common::AbstractAccessByString>))))
143 {
144 LIMA_EXCEPTION("Unable to connect accessFileReloaded");
145 }
146 m_d->m_isMainKeys=aar->isMainKeys();
147 m_d->m_access=aar->getAccessByString();
148 }
149 catch (NoSuchParam& )
150 {
151 LERROR << "no param 'accessKeys' in EnhancedAnalysisDictionary group for language " << (int) language;
152 throw InvalidConfiguration();
153 }
154 try
155 {
156 QString binaryFilePath = Misc::findFileInPaths(Common::MediaticData::MediaticData::single().getResourcesPath().c_str(),
157 unitConfiguration.getParamsValueAtKey("dictionaryValuesFile").c_str());
158 resourceFileWatcher().addPath(binaryFilePath);
159 QWriteLocker locker(&m_d->m_lock);
160 m_d->m_dicoData->loadBinaryFile(binaryFilePath.toUtf8().constData());
161 }
162 catch (NoSuchList& )
163 {
164 LERROR << "no list 'dictionaryValues' in EnhancedAnalysisDictionary group for language " << (int) language;
165 throw InvalidConfiguration();
166 }
167
168
169}
170
171void EnhancedAnalysisDictionary::slotAccessFileReloaded(std::shared_ptr<Common::AbstractAccessByString> access)
172{
174 LDEBUG << "EnhancedAnalysisDictionary::slotAccessFileReloaded";
175 m_d->m_access = access;
176 }
177
178void EnhancedAnalysisDictionary::dictionaryFileChanged ( const QString & path )
179{
181 // Check if the file exists as, when a file is replaced, dictionaryFileChanged can be triggered
182 // two times, when it is first suppressed and when the new version is available. One should not
183 // try to load the missing file
184 if (QFileInfo::exists(path))
185 {
186 LINFO << "EnhancedAnalysisDictionary::dictionaryFileChanged reload" << path;
187 QWriteLocker locker(&m_d->m_lock);
188 if (m_d->m_dicoData != 0)
189 delete m_d->m_dicoData;
190 m_d->m_dicoData = new DictionaryData();
191 m_d->m_dicoData->loadBinaryFile(path.toUtf8().constData());
192 }
193 else
194 {
195 LINFO << "EnhancedAnalysisDictionary::dictionaryFileChanged deleted, ignoring" << path;
196 }
197}
198
200{
201// QReadLocker locker(&m_d->m_lock);
202 return m_d->m_dicoData->getSize();
203}
204
205DictionaryEntry EnhancedAnalysisDictionary::getEntry(const StringsPoolIndex wordId, const Lima::LimaString& word) const
206{
207 if (m_d->m_isMainKeys) return getEntryData(wordId);
208 return getEntryData(static_cast<StringsPoolIndex>(m_d->m_access->getIndex(word)));
209}
210
212{
213 return getEntryData( static_cast<StringsPoolIndex>(m_d->m_access->getIndex(word)) );
214}
215
216DictionaryEntry EnhancedAnalysisDictionary::getEntry(const StringsPoolIndex wordId) const
217{
218 if (m_d->m_isMainKeys) return getEntryData(wordId);
219 return getEntryData( static_cast<StringsPoolIndex>(m_d->m_access->getIndex((*m_d->m_sp)[wordId])) );
220}
221
222
224{
225// ANALYSISDICTLOGINIT;
226// LDEBUG << "getEntry " << wordId;
227// QReadLocker locker(&m_d->m_lock);
228 if (wordId >= m_d->m_dicoData->getSize())
229 {
230// LDEBUG << "return empty : index out of range";
231 return DictionaryEntry(
232 std::make_shared<EnhancedAnalysisDictionaryEntry>(
233 static_cast<StringsPoolIndex>(0), false, true, false, false, false, nullptr, nullptr, m_d->m_dicoData,
234 m_d->m_isMainKeys, m_d->m_access, m_d->m_sp));
235 }
236
237 StringsPoolIndex strId=wordId;
238 if (!m_d->m_isMainKeys) {
239 strId = (*m_d->m_sp)[m_d->m_access->getSpelling(wordId)];
240 }
241
242 unsigned char* p=m_d->m_dicoData->getEntryAddr(wordId);
243 uint64_t read=DictionaryData::readCodedInt(p);
244 bool final=false;
245 if (read == 1)
246 {
247 final=true;
249 }
250 if (read == 0)
251 {
252// LDEBUG << "return empty entry";
253 return DictionaryEntry(std::make_shared<EnhancedAnalysisDictionaryEntry>(strId,final,true,false,false,false,p,p,m_d->m_dicoData,m_d->m_isMainKeys,m_d->m_access,m_d->m_sp));
254 }
255 unsigned char* start=p;
256 unsigned char* end=p+read;
257 bool hasLing=false;
258 bool hasAccented=false;
259 bool hasConcat=false;
261 hasLing=(read != 0);
262// LDEBUG << "info length = " << read;
263 p+=read;
264 if (p!=end)
265 {
267// LDEBUG << "accented length = " << read;
268 hasAccented=(read != 0);
269 p+=read;
270 if (p!=end)
271 {
273// LDEBUG << "concat length = " << read;
274 hasConcat=(read != 0);
275 p+=read;
276 }
277 }
278 Q_ASSERT(p==end);
279// LDEBUG << "return entry " << (uint64_t)start << " , " << (uint64_t)end;
280 return DictionaryEntry(std::make_shared<EnhancedAnalysisDictionaryEntry>(strId,final,false,hasLing,hasConcat,hasAccented,start,end,m_d->m_dicoData,m_d->m_isMainKeys,m_d->m_access,m_d->m_sp));
281}
282
283std::pair< DictionarySubWordIterator, DictionarySubWordIterator > EnhancedAnalysisDictionary::getSubWordEntries(const int offset, const LimaString& key) const
284{
285 std::pair<AccessSubWordIterator,AccessSubWordIterator> accessItrs=
286 m_d->m_access->getSubWords(offset,key);
287 return std::pair< DictionarySubWordIterator, DictionarySubWordIterator >(
290
291}
292
293std::pair< DictionarySuperWordIterator, DictionarySuperWordIterator > EnhancedAnalysisDictionary::getSuperWordEntries(const LimaString& key) const
294{
295 std::pair<AccessSuperWordIterator,AccessSuperWordIterator> accessItrs=
296 m_d->m_access->getSuperWords(key);
297 return std::pair< DictionarySuperWordIterator, DictionarySuperWordIterator >(
300}
301
302} // namespace
303} // namespace
304} // namespace
#define ENHANCEDANALYSISDICTIONARY_CLASSID
#define LIMA_EXCEPTION(X)
This macro writes the message X to a previously configured error stream before throwing a LimaExcepti...
Definition LimaCommon.h:293
#define LDEBUG
Definition LimaCommon.h:157
#define LINFO
Definition LimaCommon.h:158
#define LERROR
Definition LimaCommon.h:161
#define ANALYSISDICTLOGINIT
Defines a Factory to create Object of type Base.
const FsaStringsPool & stringsPool(MediaId med) const
return a message when a 'param' was not found
Use this exception to signal an error in one of the configuration files.
Definition LimaCommon.h:345
void addPath(const QString &path)
LimaFileSystemWatcher & resourceFileWatcher()
Accessor to the file watcher used to register resource files to be watched for changes.
void resourceFileChanged(const QString &path)
Signal triggered whenever one of the registered files changes on disk.
unsigned char * getEntryAddr(uint64_t index) const
virtual DictionaryEntry getEntry(const Lima::LimaString &word) const override
get dictionary entry for a word
virtual std::pair< DictionarySubWordIterator, DictionarySubWordIterator > getSubWordEntries(const int offset, const LimaString &key) const override
Returns subwords entries.
virtual std::pair< DictionarySuperWordIterator, DictionarySuperWordIterator > getSuperWordEntries(const LimaString &key) const override
return superword entries A superword entry is an entry that begins with the given key
virtual uint64_t getSize() const override
return number of keys in dictionary
virtual void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
static const LinguisticResources & single()
const singleton accessor
Definition Singleton.h:51
static MediaticData & changeable()
singleton accessor
Definition Singleton.h:71
QString findFileInPaths(const QString &paths, const QString &fileName, const QChar &separator)
Find the given file in the given paths.
SimpleFactory< AbstractResource, EnhancedAnalysisDictionary > enhancedAnalysisDictionaryFactory(ENHANCEDANALYSISDICTIONARY_CLASSID)
NAUTITIA.
QString LimaString
Definition LimaString.h:33
STL namespace.
launch exception related to the configuration file parsing