~ubuntu-branches/ubuntu/raring/notecase/raring

« back to all changes in this revision

Viewing changes to src/lib/TextSearch.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Handler
  • Date: 2008-12-21 13:09:58 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20081221130958-0ri77h0x7j1dclkq
Tags: 1.9.8-0ubuntu1
New upstream release (LP: #307752)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
////////////////////////////////////////////////////////////////////////////
2
 
// NoteCase notes manager project <http://notecase.sf.net>
3
 
//
4
 
// This code is licensed under BSD license.See "license.txt" for more details.
5
 
//
6
 
// File: Class implements fast text buffer search method
7
 
////////////////////////////////////////////////////////////////////////////
8
 
 
9
 
#include "TextSearch.h"
10
 
#include <string.h>
11
 
#include <stdlib.h>
12
 
#include <ctype.h>
13
 
#include "debug.h"
14
 
 
15
 
static gchar *utf8_strcasestr(const gchar *haystack, const gchar *needle);
16
 
 
17
 
TextSearch::TextSearch()
18
 
{
19
 
        m_dwStyle               = 0;
20
 
        m_pszPattern    = NULL;
21
 
        m_nPtrnSize             = 0;
22
 
}
23
 
 
24
 
TextSearch::~TextSearch()
25
 
{
26
 
}
27
 
 
28
 
void TextSearch::SetScanStyle(unsigned long dwStyle)
29
 
{
30
 
        //NOTE: you should NOT change style once the pattern is set
31
 
        //              (since that functions used current style setting)
32
 
        //ASSERT(NULL == m_pszPattern && 0 == m_nPtrnSize);
33
 
 
34
 
        m_dwStyle |= dwStyle;
35
 
}
36
 
 
37
 
void TextSearch::SetSearchPattern(const char *szText)
38
 
{
39
 
        m_pszPattern = (const gchar *)szText;
40
 
        m_nPtrnSize      = g_utf8_strlen(szText, -1);   //TOFIX if NULL
41
 
}
42
 
 
43
 
void TextSearch::SetSearchPattern(const char *szBinary, unsigned int nSize)
44
 
{
45
 
        m_pszPattern = szBinary;
46
 
        m_nPtrnSize      = nSize;
47
 
}
48
 
 
49
 
bool TextSearch::SetScanBuffer(const char *szBuffer, unsigned int nSize)
50
 
{
51
 
        m_pszBlock      = szBuffer;
52
 
        m_nBlkSize      = nSize;
53
 
        return (m_pszBlock != NULL && m_nBlkSize > 0);
54
 
}
55
 
 
56
 
//TOFIX use int64 for large memory
57
 
long TextSearch::Search(unsigned long nStartPos)
58
 
{
59
 
    const gchar
60
 
        *block   = m_pszBlock,          //  Concrete pointer to block data
61
 
        *pattern = m_pszPattern;        //  Concrete pointer to search value
62
 
 
63
 
    ASSERT (NULL != block);                 //  Expect non-NULL pointers, but
64
 
    ASSERT (NULL != pattern);               //  fail gracefully if not debugging
65
 
 
66
 
        if(nStartPos < 0 || nStartPos >= m_nBlkSize)
67
 
                return -1; //invalid position
68
 
    if (block == NULL || pattern == NULL)
69
 
        return -1;
70
 
 
71
 
        //move position by the required amount of characters
72
 
        block = g_utf8_offset_to_pointer(block, nStartPos);
73
 
 
74
 
    //  Pattern must be smaller or equal in size to string
75
 
    if (m_nBlkSize-nStartPos < m_nPtrnSize)
76
 
        return -1;                  //  Otherwise it's not found
77
 
    if (m_nPtrnSize == 0)           //  Empty patterns match at start
78
 
        return 0;
79
 
 
80
 
        //NOTE: case sensitive and case insensitive version
81
 
        gchar *szPos = NULL;
82
 
        if(m_dwStyle & FS_CASE_INSENSITIVE)
83
 
                szPos = utf8_strcasestr(block, pattern);
84
 
        else
85
 
                szPos = g_strstr_len(block, m_nBlkSize - nStartPos, pattern);
86
 
 
87
 
        if (szPos){
88
 
                long nPos = g_utf8_pointer_to_offset(block, szPos);
89
 
                return nPos + nStartPos;
90
 
        }
91
 
        return -1;      // Found nothing
92
 
}
93
 
 
94
 
void TextSearch::Clear()
95
 
{
96
 
        m_pszPattern = NULL;
97
 
        m_nPtrnSize  = 0;
98
 
        m_pszBlock       = NULL;
99
 
        m_nBlkSize   = 0;
100
 
}
101
 
 
102
 
 
103
 
int utf8_strnicmp(const gchar *szStr1, const gchar *szStr2, int nLen)
104
 
{
105
 
        while(nLen --)
106
 
        {
107
 
                if(NULL == szStr1)
108
 
                        return -1;
109
 
                if(NULL == szStr2)
110
 
                        return 1;
111
 
 
112
 
                gunichar nC1 = g_unichar_toupper(g_utf8_get_char(szStr1));
113
 
                gunichar nC2 = g_unichar_toupper(g_utf8_get_char(szStr2));
114
 
                if(nC1 != nC2)
115
 
                        return nC1-nC2;
116
 
 
117
 
                szStr1 = g_utf8_next_char(szStr1);
118
 
                szStr2 = g_utf8_next_char(szStr2);
119
 
        }
120
 
 
121
 
        return 0; // match
122
 
}
123
 
 
124
 
gchar *utf8_strcasestr(const gchar *haystack, const gchar *needle)
125
 
{
126
 
        size_t haystack_len = g_utf8_strlen(haystack, -1);
127
 
        size_t needle_len   = g_utf8_strlen(needle, -1);
128
 
 
129
 
        if (haystack_len < needle_len || needle_len == 0)
130
 
                return NULL;
131
 
 
132
 
        while (haystack_len >= needle_len) {
133
 
                if (0 == utf8_strnicmp(haystack, needle, needle_len))
134
 
                        return (gchar *)haystack;
135
 
                else {
136
 
                        haystack = g_utf8_next_char(haystack);
137
 
                        haystack_len--;
138
 
                }
139
 
        }
140
 
 
141
 
        return NULL;
142
 
}
 
1
////////////////////////////////////////////////////////////////////////////
 
2
// NoteCase notes manager project <http://notecase.sf.net>
 
3
//
 
4
// This code is licensed under BSD license.See "license.txt" for more details.
 
5
//
 
6
// File: Class implements fast text buffer search method
 
7
////////////////////////////////////////////////////////////////////////////
 
8
 
 
9
#include "TextSearch.h"
 
10
#include <string.h>
 
11
#include <stdlib.h>
 
12
#include <ctype.h>
 
13
#include "debug.h"
 
14
 
 
15
static gchar *utf8_strcasestr(const gchar *haystack, const gchar *needle);
 
16
 
 
17
TextSearch::TextSearch()
 
18
{
 
19
        m_dwStyle               = 0;
 
20
        m_pszPattern    = NULL;
 
21
        m_nPtrnSize             = 0;
 
22
}
 
23
 
 
24
TextSearch::~TextSearch()
 
25
{
 
26
}
 
27
 
 
28
void TextSearch::SetScanStyle(unsigned long dwStyle)
 
29
{
 
30
        //NOTE: you should NOT change style once the pattern is set
 
31
        //              (since that functions used current style setting)
 
32
        //ASSERT(NULL == m_pszPattern && 0 == m_nPtrnSize);
 
33
 
 
34
        m_dwStyle |= dwStyle;
 
35
}
 
36
 
 
37
void TextSearch::SetSearchPattern(const char *szText)
 
38
{
 
39
        m_pszPattern = (const gchar *)szText;
 
40
        m_nPtrnSize      = g_utf8_strlen(szText, -1);   //TOFIX if NULL
 
41
}
 
42
 
 
43
void TextSearch::SetSearchPattern(const char *szBinary, unsigned int nSize)
 
44
{
 
45
        m_pszPattern = szBinary;
 
46
        m_nPtrnSize      = nSize;
 
47
}
 
48
 
 
49
bool TextSearch::SetScanBuffer(const char *szBuffer, unsigned int nSize)
 
50
{
 
51
        m_pszBlock      = szBuffer;
 
52
        m_nBlkSize      = nSize;
 
53
        return (m_pszBlock != NULL && m_nBlkSize > 0);
 
54
}
 
55
 
 
56
//TOFIX use int64 for large memory
 
57
long TextSearch::Search(unsigned long nStartPos)
 
58
{
 
59
    const gchar
 
60
        *block   = m_pszBlock,          //  Concrete pointer to block data
 
61
        *pattern = m_pszPattern;        //  Concrete pointer to search value
 
62
 
 
63
    ASSERT (NULL != block);                 //  Expect non-NULL pointers, but
 
64
    ASSERT (NULL != pattern);               //  fail gracefully if not debugging
 
65
 
 
66
        if(nStartPos < 0 || nStartPos >= m_nBlkSize)
 
67
                return -1; //invalid position
 
68
    if (block == NULL || pattern == NULL)
 
69
        return -1;
 
70
 
 
71
        //move position by the required amount of characters
 
72
        block = g_utf8_offset_to_pointer(block, nStartPos);
 
73
 
 
74
    //  Pattern must be smaller or equal in size to string
 
75
    if (m_nBlkSize-nStartPos < m_nPtrnSize)
 
76
        return -1;                  //  Otherwise it's not found
 
77
    if (m_nPtrnSize == 0)           //  Empty patterns match at start
 
78
        return 0;
 
79
 
 
80
        //NOTE: case sensitive and case insensitive version
 
81
        gchar *szPos = NULL;
 
82
        if(m_dwStyle & FS_CASE_INSENSITIVE)
 
83
                szPos = utf8_strcasestr(block, pattern);
 
84
        else
 
85
                szPos = g_strstr_len(block, m_nBlkSize - nStartPos, pattern);
 
86
 
 
87
        if (szPos){
 
88
                long nPos = g_utf8_pointer_to_offset(block, szPos);
 
89
                return nPos + nStartPos;
 
90
        }
 
91
        return -1;      // Found nothing
 
92
}
 
93
 
 
94
void TextSearch::Clear()
 
95
{
 
96
        m_pszPattern = NULL;
 
97
        m_nPtrnSize  = 0;
 
98
        m_pszBlock       = NULL;
 
99
        m_nBlkSize   = 0;
 
100
}
 
101
 
 
102
 
 
103
int utf8_strnicmp(const gchar *szStr1, const gchar *szStr2, int nLen)
 
104
{
 
105
        while(nLen --)
 
106
        {
 
107
                if(NULL == szStr1)
 
108
                        return -1;
 
109
                if(NULL == szStr2)
 
110
                        return 1;
 
111
 
 
112
                gunichar nC1 = g_unichar_toupper(g_utf8_get_char(szStr1));
 
113
                gunichar nC2 = g_unichar_toupper(g_utf8_get_char(szStr2));
 
114
                if(nC1 != nC2)
 
115
                        return nC1-nC2;
 
116
 
 
117
                szStr1 = g_utf8_next_char(szStr1);
 
118
                szStr2 = g_utf8_next_char(szStr2);
 
119
        }
 
120
 
 
121
        return 0; // match
 
122
}
 
123
 
 
124
gchar *utf8_strcasestr(const gchar *haystack, const gchar *needle)
 
125
{
 
126
        size_t haystack_len = g_utf8_strlen(haystack, -1);
 
127
        size_t needle_len   = g_utf8_strlen(needle, -1);
 
128
 
 
129
        if (haystack_len < needle_len || needle_len == 0)
 
130
                return NULL;
 
131
 
 
132
        while (haystack_len >= needle_len) {
 
133
                if (0 == utf8_strnicmp(haystack, needle, needle_len))
 
134
                        return (gchar *)haystack;
 
135
                else {
 
136
                        haystack = g_utf8_next_char(haystack);
 
137
                        haystack_len--;
 
138
                }
 
139
        }
 
140
 
 
141
        return NULL;
 
142
}