/ src / filter_helper_functions.cpp
filter_helper_functions.cpp
  1  /**
  2   * @file filter_helper_functions.cpp
  3   * @author Rene Ceska xceska06 (xceska06@stud.fit.vutbr.cz)
  4   * @date 2023-11-19
  5   */
  6  #include "inc/filter_helper_functions.h"
  7  
  8  bool substrFilterHandler(SubstringFilter *sf, int *err,
  9                           std::vector<unsigned char> attribute) {
 10    std::vector<unsigned char> attributeInital = {};
 11    std::vector<unsigned char> attributeMiddle = {};
 12    std::vector<unsigned char> attributeFinal = {};
 13  
 14    // extract initial
 15    if (!sf->getSubInitial().empty()) {
 16      if (attribute.size() >= sf->getSubInitial().size()) {
 17        attributeInital = std::vector<unsigned char>(
 18            attribute.begin(), attribute.begin() + sf->getSubInitial().size());
 19        attributeMiddle = std::vector<unsigned char>(
 20            attribute.begin() + sf->getSubInitial().size(), attribute.end());
 21      } else {
 22        return false;
 23      }
 24    } else {
 25      attributeMiddle =
 26          std::vector<unsigned char>(attribute.begin(), attribute.end());
 27    }
 28  
 29    // extract final
 30    if (!sf->getSubFinal().empty()) {
 31      if (attribute.size() >= sf->getSubFinal().size()) {
 32        attributeFinal = std::vector<unsigned char>(
 33            attribute.end() - sf->getSubFinal().size(), attribute.end());
 34        if (attributeMiddle.size() > sf->getSubFinal().size()) {
 35          attributeMiddle = std::vector<unsigned char>(
 36              attributeMiddle.begin(),
 37              attributeMiddle.end() - sf->getSubFinal().size());
 38        }
 39      } else {
 40        return false;
 41      }
 42    }
 43  
 44    // check subInitial
 45    if (!sf->getSubInitial().empty() &&
 46        ToLowerCase(attributeInital) != ToLowerCase(sf->getSubInitial())) {
 47      return false;
 48    }
 49    // check subFinal
 50    if (!sf->getSubFinal().empty() &&
 51        ToLowerCase(attributeFinal) != ToLowerCase(sf->getSubFinal())) {
 52      return false;
 53    }
 54    unsigned long int x = 0;
 55  
 56    // convert to lower case
 57    attributeMiddle = ToLowerCase(attributeMiddle);
 58  
 59    for (unsigned long int y = 0; y < sf->getSubAny().size(); y++) {
 60      bool match = false;
 61      for (; x < attributeMiddle.size(); x++) {
 62  
 63        if (attributeMiddle[x] == std::tolower(sf->getSubAny()[y][0])) {
 64          match = true;
 65          for (unsigned long int z = 0; z < sf->getSubAny()[y].size(); z++) {
 66            if (attributeMiddle[x + z] != std::tolower(sf->getSubAny()[y][z])) {
 67              match = false;
 68              break;
 69            }
 70          }
 71          if (match) {
 72            break;
 73          }
 74        }
 75      }
 76      if (!match) {
 77        return false;
 78      }
 79    }
 80    return true;
 81  }
 82  
 83  bool equalityMatchHandler(EqualityMatchFilter *emf, int *err,
 84                            std::vector<unsigned char> attribute) {
 85    if (ToLowerCase(emf->getAssertionValue()) == ToLowerCase(attribute)) {
 86      return true;
 87    }
 88    return false;
 89  }
 90  
 91  bool filterLine(FilterObject *f, int *err, DatabaseObject &databaseEntry) {
 92  
 93    // cn
 94    std::vector<unsigned char> cn = {'c', 'n'};
 95    // CommonName
 96    std::vector<unsigned char> CommonName = {'c', 'o', 'm', 'm', 'o',
 97                                             'n', 'n', 'a', 'm', 'e'};
 98    // email
 99    std::vector<unsigned char> email = {'e', 'm', 'a', 'i', 'l'};
100    // email
101    std::vector<unsigned char> mail = {'m', 'a', 'i', 'l'};
102    // uid
103    std::vector<unsigned char> uid = {'u', 'i', 'd'};
104    // UserID
105    std::vector<unsigned char> UserID = {'u', 's', 'e', 'r', 'i', 'd'};
106  
107    switch (f->getFilterType()) {
108    case equalityMatch: {
109      std::vector<unsigned char> attributeDescription =
110          ToLowerCase(((EqualityMatchFilter *)f)->getAttributeDescription());
111      if (attributeDescription == cn || attributeDescription == CommonName) {
112        return equalityMatchHandler((EqualityMatchFilter *)f, err,
113                                    databaseEntry.get_name());
114      } else if (attributeDescription == email || attributeDescription == mail) {
115        return equalityMatchHandler((EqualityMatchFilter *)f, err,
116                                    databaseEntry.get_email());
117      } else if (attributeDescription == uid || attributeDescription == UserID) {
118        return equalityMatchHandler((EqualityMatchFilter *)f, err,
119                                    databaseEntry.get_uid());
120      } else {
121        *err = 2;
122        return false;
123      }
124  
125    } break;
126    case substrings: {
127      std::vector<unsigned char> attributeDescription =
128             ToLowerCase(((SubstringFilter *)f)->getAttributeDescription());
129      if (attributeDescription == cn || attributeDescription == CommonName) {
130        return substrFilterHandler((SubstringFilter *)f, err,
131                                   databaseEntry.get_name());
132      } else if (attributeDescription == email || attributeDescription == mail) {
133        return substrFilterHandler((SubstringFilter *)f, err,
134                                   databaseEntry.get_email());
135      } else if (attributeDescription == uid || attributeDescription == UserID) {
136        return substrFilterHandler((SubstringFilter *)f, err,
137                                   databaseEntry.get_uid());
138      } else {
139        *err = 2;
140        return false;
141      }
142    } break;
143    case AND: {
144      AndFilter *af = (AndFilter *)f;
145      for (unsigned long int i = 0; i < af->filters.size(); i++) {
146        if (!filterLine(af->filters[i], err, databaseEntry)) {
147          return false;
148        }
149      }
150      return true;
151  
152    } break;
153    case OR: {
154      OrFilter *of = (OrFilter *)f;
155      for (unsigned long int i = 0; i < of->filters.size(); i++) {
156        if (filterLine(of->filters[i], err, databaseEntry)) {
157          return true;
158        }
159      }
160      return false;
161    } break;
162    case NOT: {
163      NotFilter *nf = (NotFilter *)f;
164      bool result = !filterLine((nf->filter), err, databaseEntry);
165      if (*err == 2)
166        return false;
167      return result;
168    } break;
169    default:
170      return false;
171    }
172    return false;
173  }
174  
175  std::vector<DatabaseObject> filterHandler(FilterObject *f, int *err,
176                                            const char *dbLocation,
177                                            int sizeLimit) {
178    std::vector<DatabaseObject> resultDB;
179    int dbErr = 0;
180    DatabaseController db(dbLocation);
181    int lineCounter = 0;
182    while (true) {
183  
184      DatabaseObject obj = db.loadNextRow(&dbErr);
185  
186      if (dbErr != 0)
187        break;
188  
189      if (filterLine(f, err, obj)) {
190        resultDB.push_back(obj);
191        lineCounter++;
192      }
193  
194      if (lineCounter >= sizeLimit && sizeLimit != 0) {
195        *err = 1;
196        break;
197      }
198    }
199  
200    return resultDB;
201  }
202  
203  FilterObject *
204  convertToFilterObject(std::vector<unsigned char>::iterator BERfilter,
205                        std::vector<unsigned char>::iterator end) {
206  
207    FilterObject *f;
208    int err;
209    int lenght = 0;
210    int ll = 0;
211    std::vector<unsigned char> attributeDescription;
212    std::vector<unsigned char> assertionValue;
213  
214    switch (getFilterType(BERfilter)) {
215    case equalityMatch:
216  
217      GoIntoTag(BERfilter, &err, end);
218      if (err != 0)
219        return new FilterObject();
220      lenght = GetLength(BERfilter + 1, &err, end);
221  
222      ll = GetLengthOfLength(BERfilter + 1, &err, end);
223  
224      for (int i = 0; i < lenght; i++) {
225        attributeDescription.push_back(BERfilter[1 + ll + i]);
226      }
227  
228      SkipTags(BERfilter, 1, &err, end);
229      if (err != 0)
230        return new FilterObject();
231  
232      lenght = GetLength(BERfilter + 1, &err, end);
233      ll = GetLengthOfLength(BERfilter + 1, &err, end);
234  
235      for (int i = 0; i < lenght; i++) {
236        assertionValue.push_back(BERfilter[1 + ll + i]);
237      }
238  
239      f = new EqualityMatchFilter(attributeDescription, assertionValue);
240  
241      break;
242    case substrings: {
243      std::vector<unsigned char> attributeDescription;
244      std::vector<unsigned char> initial;
245      std::vector<std::vector<unsigned char>> any;
246      std::vector<unsigned char> final;
247      GoIntoTag(BERfilter, &err, end);
248      if (err != 0)
249        return new FilterObject();
250      lenght = GetLength(BERfilter + 1, &err, end);
251      ll = GetLengthOfLength(BERfilter + 1, &err, end);
252  
253      for (int i = 0; i < lenght; i++) {
254        attributeDescription.push_back(BERfilter[1 + ll + i]);
255      }
256  
257      SkipTags(BERfilter, 1, &err, end);
258      if (err != 0)
259        return new FilterObject();
260      int lenghtOfSequence = GetLength(BERfilter + 1, &err, end);
261      int lenghtOflenOfSequence = GetLengthOfLength(BERfilter + 1, &err, end);
262      GoIntoTag(BERfilter, &err, end);
263      if (err != 0)
264        return new FilterObject();
265  
266      int currentBitPointer = 0;
267      while (currentBitPointer < lenghtOfSequence + lenghtOflenOfSequence) {
268        switch (BERfilter[0]) {
269        case 0x80: {
270          int dataLenght = GetLength(BERfilter + 1, &err, end);
271          int LenghtLenght = GetLengthOfLength(BERfilter + 1, &err, end);
272          initial = std::vector<unsigned char>(BERfilter + 1 + LenghtLenght,
273                                               BERfilter + 1 + LenghtLenght +
274                                                   dataLenght);
275        } break;
276        case 0x81: {
277          int dataLenght = GetLength(BERfilter + 1, &err, end);
278          int LenghtLenght = GetLengthOfLength(BERfilter + 1, &err, end);
279          std::vector<unsigned char> tmp = std::vector<unsigned char>(
280              BERfilter + 1 + LenghtLenght,
281              BERfilter + 1 + LenghtLenght + dataLenght);
282          any.push_back(tmp);
283        } break;
284        case 0x82: {
285          int dataLenght = GetLength(BERfilter + 1, &err, end);
286          int LenghtLenght = GetLengthOfLength(BERfilter + 1, &err, end);
287          final = std::vector<unsigned char>(BERfilter + 1 + LenghtLenght,
288                                             BERfilter + 1 + LenghtLenght +
289                                                 dataLenght);
290        } break;
291        }
292        currentBitPointer += 1 + GetLengthOfLength(BERfilter + 1, &err, end) +
293                             GetLength(BERfilter + 1, &err, end);
294        SkipTags(BERfilter, 1, &err, end);
295      }
296      f = new SubstringFilter(attributeDescription, initial, any, final);
297  
298    } break;
299    case AND:
300      f = new AndFilter();
301  
302      lenght = GetLength(BERfilter + 1, &err, end);
303      GoIntoTag(BERfilter, &err, end);
304      if (err != 0)
305        return new FilterObject();
306      for (int i = 0; i < lenght;) {
307  
308        if (err != 0)
309          return new FilterObject();
310        FilterObject *tmpF = convertToFilterObject(BERfilter, end);
311        printf("filter type: %d\n", tmpF->getFilterType());
312        fflush(stdout);
313        ((AndFilter *)f)->filters.push_back(tmpF);
314        i += 1 + GetLengthOfLength(BERfilter + 1, &err, end) +
315             GetLength(BERfilter + 1, &err, end);
316        SkipTags(BERfilter, 1, &err, end);
317      }
318  
319      break;
320    case OR:
321      f = new OrFilter();
322      lenght = GetLength(BERfilter + 1, &err, end);
323      GoIntoTag(BERfilter, &err, end);
324      if (err != 0)
325        return new FilterObject();
326  
327      for (int i = 0; i < lenght;) {
328        if (err != 0)
329          return new FilterObject();
330        FilterObject *tmpF = convertToFilterObject(BERfilter, end);
331        ((OrFilter *)f)->filters.push_back(tmpF);
332        i += 1 + GetLengthOfLength(BERfilter + 1, &err, end) +
333             GetLength(BERfilter + 1, &err, end);
334        SkipTags(BERfilter, 1, &err, end);
335      }
336  
337      break;
338    case NOT: {
339      f = new NotFilter();
340      lenght = GetLength(BERfilter + 1, &err, end);
341      GoIntoTag(BERfilter, &err, end);
342      if (err != 0)
343        return new FilterObject();
344      FilterObject *tmpF = convertToFilterObject(BERfilter, end);
345      ((NotFilter *)f)->filter = tmpF;
346      break;
347    }
348    default:
349      f = new FilterObject();
350      break;
351    }
352    return f;
353  }