LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
OffsetMapping.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 by CEA - LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
6#include "OffsetMapping.h"
8
9using namespace std;
10
11namespace Lima {
12namespace LinguisticProcessing {
13namespace AnalysisDumpers {
14
15//***********************************************************************
17m_mappingNewToOld(),
18m_mappingOldToNew()
19{
20}
24
26{
27 m_mappingNewToOld.clear();
28 m_mappingOldToNew.clear();
29
30}
31
32void OffsetMapping::addMapping(unsigned int offset, unsigned int newOffset)
33{
34 m_mappingNewToOld[newOffset]=offset;
35}
36
38{
39 // add n to all key values (new offsets)
40 OffsetMapping newMap;
41 for (const auto& m: m_mappingNewToOld) {
42 //cout << "OffsetMapping::operator+" << n << " " << m.first << "," << m.second+n << endl;
43 // m.first is the new offset, m.second the old
44 newMap.addMapping(m.second,m.first+n);
45 }
46 return newMap;
47}
48
49void OffsetMapping::add(const OffsetMapping& otherMapping)
50{
51 for (const auto& m: otherMapping.m_mappingNewToOld) {
52 //cout << "OffsetMapping::add " << m.first << "-" << m.second << endl;
53 m_mappingNewToOld[m.first]=m.second;
54 }
55}
56
57
59{
60 //LOGINIT("LP::TextPreprocessing");
61 for (const auto& m: m_mappingNewToOld) {
62 m_mappingOldToNew.insert(make_pair(m.second,m.first));
63 }
64 //LDEBUG << "OffsetMapping::createInverseMapping: map size=" << m_mappingOldToNew.size();
65}
66
67unsigned int OffsetMapping::getOriginalOffset(unsigned int newOffset) const
68{
69 // mapping is incomplete: not all offset are stored, only the ones where a change occurs
70 // find closest change
71 auto it=m_mappingNewToOld.lower_bound(newOffset);
72 // lower_bound is the first iterator that is greater or equal to the newOffset:
73 // need to take previous one (if it exists) to have highest smaller value
74
75 unsigned int prevOffset(0);
76 unsigned int prevOffsetMapping(0);
77 if (it!=m_mappingNewToOld.begin()) {
78 if (it==m_mappingNewToOld.end()) {
79 prevOffset=m_mappingNewToOld.rbegin()->first;
80 prevOffsetMapping=m_mappingNewToOld.rbegin()->second;
81 }
82 else {
83 if ((*it).first != newOffset) {
84 // take previous one only if strictly superior: if equal, keep this iterator
85 it--;
86 }
87 prevOffset=(*it).first;
88 prevOffsetMapping=(*it).second;
89 }
90 }
91 // otherwise, before first offset mapping: keep zeros
92
93 // return old value translated by the difference between the target offset and the closest smaller one that was found in the map
95 LDEBUG << "OffsetMapping::getOriginalOffset" << newOffset << "->" << prevOffsetMapping << "+" << newOffset << "-" << prevOffset;
96 return (prevOffsetMapping + newOffset-prevOffset);
97}
98
99void OffsetMapping::getNewOffsets(unsigned int prevOffset, std::vector<unsigned int>& newOffsets) const
100{
101 newOffsets.clear();
102 //LOGINIT("LP::TextPreprocessing");
103 if (m_mappingOldToNew.size()==0) {
104 //LERROR << "OffsetMapping::getNewOffsets: missing offset mapping";
105 // no mapping: keep offset
106 newOffsets.push_back(prevOffset);
107 return;
108 }
109 auto it=m_mappingOldToNew.upper_bound(prevOffset);
110 // uppper_bound is the first iterator that is greater to the newOffset:
111 // need to take previous ones (if they exists) to have highest smaller value
112 // oldToNew is a multimap : several entries can have same key value
113 if (it!=m_mappingNewToOld.begin()) {
114 it--;
115 unsigned int newOffset=(*it).first;
116 while (it!=m_mappingOldToNew.begin() && (*it).first==newOffset) {
117 // to keep the same order, push in front
118 newOffsets.insert(newOffsets.begin(),(*it).second+prevOffset-newOffset);
119 it--;
120 }
121 }
122 else {
123 // otherwise, before first offset mapping: keep same value
124 newOffsets.push_back(prevOffset);
125 }
126}
127
128
129//***********************************************************************
131{
132 ostringstream oss;
133 //os << "mapping (new->old)=" << endl;
134 for (const auto& m: m_mappingNewToOld) {
135 oss << m.first << "->" << m.second << endl;
136 }
137 return oss.str();
138}
139std::ostream& operator<<(std::ostream& os, const OffsetMapping& offsetMapping)
140{
141 os << offsetMapping.toString();
142 return os;
143}
144
145
146} // end namespace
147} // end namespace
148} // end namespace
#define LDEBUG
Definition LimaCommon.h:157
#define DUMPERLOGINIT
void addMapping(unsigned int offset, unsigned int newOffset)
add new mapping between old and new offsets.
unsigned int getOriginalOffset(unsigned int newOffset) const
void getNewOffsets(unsigned int prevOffset, std::vector< unsigned int > &newOffsets) const
std::ostream & operator<<(std::ostream &os, const OffsetMapping &offsetMapping)
NAUTITIA.
STL namespace.