LCOV - code coverage report
Current view: top level - queryparser - cjk-tokenizer.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 7028d852e609 Lines: 39 39 100.0 %
Date: 2019-02-17 14:59:59 Functions: 5 5 100.0 %
Branches: 42 68 61.8 %

           Branch data     Line data    Source code
       1                 :            : /** @file cjk-tokenizer.cc
       2                 :            :  * @brief Tokenise CJK text as n-grams
       3                 :            :  */
       4                 :            : /* Copyright (c) 2007, 2008 Yung-chung Lin (henearkrxern@gmail.com)
       5                 :            :  * Copyright (c) 2011 Richard Boulton (richard@tartarus.org)
       6                 :            :  * Copyright (c) 2011 Brandon Schaefer (brandontschaefer@gmail.com)
       7                 :            :  * Copyright (c) 2011,2018 Olly Betts
       8                 :            :  *
       9                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a copy
      10                 :            :  * of this software and associated documentation files (the "Software"), to deal
      11                 :            :  * deal in the Software without restriction, including without limitation the
      12                 :            :  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      13                 :            :  * sell copies of the Software, and to permit persons to whom the Software is
      14                 :            :  * furnished to do so, subject to the following conditions:
      15                 :            :  *
      16                 :            :  * The above copyright notice and this permission notice shall be included in
      17                 :            :  * all copies or substantial portions of the Software.
      18                 :            :  *
      19                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      20                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      22                 :            :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24                 :            :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      25                 :            :  * IN THE SOFTWARE.
      26                 :            :  */
      27                 :            : 
      28                 :            : #include <config.h>
      29                 :            : 
      30                 :            : #include "cjk-tokenizer.h"
      31                 :            : 
      32                 :            : #include "omassert.h"
      33                 :            : #include "xapian/unicode.h"
      34                 :            : 
      35                 :            : #include <cstdlib>
      36                 :            : #include <string>
      37                 :            : 
      38                 :            : using namespace std;
      39                 :            : 
      40                 :            : static unsigned NGRAM_SIZE = 2;
      41                 :            : 
      42                 :            : bool
      43                 :      64925 : CJK::is_cjk_enabled()
      44                 :            : {
      45                 :            :     const char * p;
      46 [ +  + ][ +  - ]:      64925 :     static bool result = ((p = getenv("XAPIAN_CJK_NGRAM")) != NULL && *p);
         [ -  + ][ #  # ]
      47                 :      64925 :     return result;
      48                 :            : }
      49                 :            : 
      50                 :            : // 2E80..2EFF; CJK Radicals Supplement
      51                 :            : // 3000..303F; CJK Symbols and Punctuation
      52                 :            : // 3040..309F; Hiragana
      53                 :            : // 30A0..30FF; Katakana
      54                 :            : // 3100..312F; Bopomofo
      55                 :            : // 3130..318F; Hangul Compatibility Jamo
      56                 :            : // 3190..319F; Kanbun
      57                 :            : // 31A0..31BF; Bopomofo Extended
      58                 :            : // 31C0..31EF; CJK Strokes
      59                 :            : // 31F0..31FF; Katakana Phonetic Extensions
      60                 :            : // 3200..32FF; Enclosed CJK Letters and Months
      61                 :            : // 3300..33FF; CJK Compatibility
      62                 :            : // 3400..4DBF; CJK Unified Ideographs Extension A
      63                 :            : // 4DC0..4DFF; Yijing Hexagram Symbols
      64                 :            : // 4E00..9FFF; CJK Unified Ideographs
      65                 :            : // A700..A71F; Modifier Tone Letters
      66                 :            : // AC00..D7AF; Hangul Syllables
      67                 :            : // F900..FAFF; CJK Compatibility Ideographs
      68                 :            : // FE30..FE4F; CJK Compatibility Forms
      69                 :            : // FF00..FFEF; Halfwidth and Fullwidth Forms
      70                 :            : // 20000..2A6DF; CJK Unified Ideographs Extension B
      71                 :            : // 2F800..2FA1F; CJK Compatibility Ideographs Supplement
      72                 :            : bool
      73                 :        275 : CJK::codepoint_is_cjk(unsigned p)
      74                 :            : {
      75         [ +  + ]:        275 :     if (p < 0x2E80) return false;
      76 [ +  - ][ +  - ]:        141 :     return ((p >= 0x2E80 && p <= 0x2EFF) ||
      77 [ +  + ][ +  - ]:        141 :             (p >= 0x3000 && p <= 0x9FFF) ||
      78 [ +  - ][ +  - ]:         22 :             (p >= 0xA700 && p <= 0xA71F) ||
      79 [ +  + ][ +  - ]:         22 :             (p >= 0xAC00 && p <= 0xD7AF) ||
      80 [ +  - ][ +  - ]:          2 :             (p >= 0xF900 && p <= 0xFAFF) ||
      81 [ +  - ][ +  - ]:          2 :             (p >= 0xFE30 && p <= 0xFE4F) ||
      82 [ -  + ][ #  # ]:          2 :             (p >= 0xFF00 && p <= 0xFFEF) ||
      83 [ +  - ][ #  # ]:        282 :             (p >= 0x20000 && p <= 0x2A6DF) ||
                 [ #  # ]
      84         [ #  # ]:        141 :             (p >= 0x2F800 && p <= 0x2FA1F));
      85                 :            : }
      86                 :            : 
      87                 :            : string
      88                 :         41 : CJK::get_cjk(Xapian::Utf8Iterator &it, size_t& char_count)
      89                 :            : {
      90                 :         41 :     string str;
      91                 :         41 :     char_count = 0;
      92 [ +  + ][ +  - ]:        379 :     while (it != Xapian::Utf8Iterator() &&
                 [ +  + ]
      93 [ +  + ][ +  + ]:        248 :            codepoint_is_cjk(*it) &&
      94                 :         92 :            Xapian::Unicode::is_wordchar(*it)) {
      95         [ +  - ]:         90 :         Xapian::Unicode::append_utf8(str, *it);
      96                 :         90 :         ++char_count;
      97                 :         90 :         ++it;
      98                 :            :     }
      99                 :         41 :     return str;
     100                 :            : }
     101                 :            : 
     102                 :            : const string &
     103                 :        133 : CJKTokenIterator::operator*() const
     104                 :            : {
     105         [ +  + ]:        133 :     if (current_token.empty()) {
     106                 :            :         Assert(it != Xapian::Utf8Iterator());
     107                 :         86 :         p = it;
     108                 :         86 :         Xapian::Unicode::append_utf8(current_token, *p);
     109                 :         86 :         ++p;
     110                 :         86 :         len = 1;
     111                 :            :     }
     112                 :        133 :     return current_token;
     113                 :            : }
     114                 :            : 
     115                 :            : CJKTokenIterator &
     116                 :        133 : CJKTokenIterator::operator++()
     117                 :            : {
     118 [ +  + ][ +  + ]:        133 :     if (len < NGRAM_SIZE && p != Xapian::Utf8Iterator()) {
         [ +  + ][ +  + ]
     119                 :         47 :         Xapian::Unicode::append_utf8(current_token, *p);
     120                 :         47 :         ++p;
     121                 :         47 :         ++len;
     122                 :            :     } else {
     123                 :            :         Assert(it != Xapian::Utf8Iterator());
     124                 :         86 :         ++it;
     125                 :         86 :         current_token.resize(0);
     126                 :            :     }
     127                 :        133 :     return *this;
     128                 :            : }

Generated by: LCOV version 1.11