72b29ec5c00716baa05d0635911b08486be9861f
[pazpar2-moved-to-github.git] / src / charsets.c
1 /* $Id: charsets.c,v 1.3 2007-05-24 11:09:27 adam Exp $
2    Copyright (c) 2006-2007, Index Data.
3
4 This file is part of Pazpar2.
5
6 Pazpar2 is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Pazpar2; see the file LICENSE.  If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.
20  */
21
22 /** \file charsets.c
23     \brief Pazpar2 Character set facilities
24 */
25
26 #if HAVE_CONFIG_H
27 #include "cconfig.h"
28 #endif
29
30 #include <yaz/xmalloc.h>
31 #include <yaz/wrbuf.h>
32 #include <yaz/log.h>
33 #include <ctype.h>
34 #include <assert.h>
35
36 #include "charsets.h"
37 //#include "config.h"
38 //#include "parameters.h"
39
40 #ifdef HAVE_ICU
41 #include "icu_I18N.h"
42 #endif // HAVE_ICU
43
44 /* charset handle */
45 struct pp2_charset_s {
46     const char *(*token_next_handler)(pp2_relevance_token_t prt);
47     /* other handlers will come as we see fit */
48 #ifdef HAVE_ICU
49     struct icu_chain * icu_chn;
50     UErrorCode icu_sts;
51 #endif // HAVE_ICU
52 };
53
54 static const char *pp2_relevance_token_a_to_z(pp2_relevance_token_t prt);
55
56 #ifdef HAVE_ICU
57 static const char *pp2_relevance_token_icu(pp2_relevance_token_t prt);
58 #endif // HAVE_ICU
59
60 /* tokenzier handle */
61 struct pp2_relevance_token_s {
62     const char *cp;     /* unnormalized buffer we're tokenizing */
63     pp2_charset_t pct;  /* our main charset handle (type+config) */
64     WRBUF norm_str;     /* normized string we return (temporarily) */
65 };
66
67 pp2_charset_t pp2_charset_create(struct icu_chain * icu_chn)
68 {
69     pp2_charset_t pct = xmalloc(sizeof(*pct));
70
71     pct->icu_chn = 0;
72     pct->token_next_handler = pp2_relevance_token_a_to_z;
73 #ifdef HAVE_ICU
74     if (icu_chn){
75         pct->icu_chn = icu_chn;
76         pct->icu_sts = U_ZERO_ERROR;
77         pct->token_next_handler = pp2_relevance_token_icu;
78     }
79  #endif // HAVE_ICU
80     return pct;
81 }
82
83 void pp2_charset_destroy(pp2_charset_t pct)
84 {
85     xfree(pct);
86 }
87
88 pp2_relevance_token_t pp2_relevance_tokenize(pp2_charset_t pct,
89                                              const char *buf)
90 {
91     pp2_relevance_token_t prt = xmalloc(sizeof(*prt));
92
93     assert(pct);
94
95     prt->norm_str = wrbuf_alloc();
96     prt->cp = buf;
97     prt->pct = pct;
98
99 #ifdef HAVE_ICU
100     if (pct->icu_chn)
101     {
102         pct->icu_sts = U_ZERO_ERROR;
103         int ok = 0;
104         ok = icu_chain_assign_cstr(pct->icu_chn, buf, &pct->icu_sts);
105         printf("\nfield ok: %d '%s'\n", ok, buf);
106         //prt->cp = buf;
107         prt->pct = pct;
108         prt->norm_str = 0;
109     }
110 #endif // HAVE_ICU
111     return prt;
112 }
113
114
115 void pp2_relevance_token_destroy(pp2_relevance_token_t prt)
116 {
117     assert(prt);
118     if(prt->norm_str) 
119         wrbuf_destroy(prt->norm_str);
120     xfree(prt);
121 }
122
123 const char *pp2_relevance_token_next(pp2_relevance_token_t prt)
124 {
125     assert(prt);
126     return (prt->pct->token_next_handler)(prt);
127 }
128
129 #define raw_char(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 1 : -1)
130 /* original tokenizer with our tokenize interface, but we
131    add +1 to ensure no '\0' are in our string (except for EOF)
132 */
133 static const char *pp2_relevance_token_a_to_z(pp2_relevance_token_t prt)
134 {
135     const char *cp = prt->cp;
136     int c;
137
138     /* skip white space */
139     while (*cp && (c = raw_char(tolower(*cp))) < 0)
140         cp++;
141     if (*cp == '\0')
142     {
143         prt->cp = cp;
144         return 0;
145     }
146     /* now read the term itself */
147     wrbuf_rewind(prt->norm_str);
148     while (*cp && (c = raw_char(tolower(*cp))) >= 0)
149     {
150         wrbuf_putc(prt->norm_str, c);
151         cp++;
152     }
153     prt->cp = cp;
154     return wrbuf_cstr(prt->norm_str);
155 }
156
157
158 #ifdef HAVE_ICU
159 static const char *pp2_relevance_token_icu(pp2_relevance_token_t prt)
160 {
161     //&& U_SUCCESS(pct->icu_sts))
162     if (icu_chain_next_token(prt->pct->icu_chn, &prt->pct->icu_sts)){
163         printf("'%s' ",  icu_chain_get_norm(prt->pct->icu_chn)); 
164         if (U_FAILURE(prt->pct->icu_sts))
165         {
166             printf("ICU status failure\n "); 
167             return 0;
168         }
169             
170         return icu_chain_get_norm(prt->pct->icu_chn);
171     }
172     printf ("EOF\n");
173     return 0;
174 };
175 #endif // HAVE_ICU
176
177
178
179 /*
180  * Local variables:
181  * c-basic-offset: 4
182  * indent-tabs-mode: nil
183  * End:
184  * vim: shiftwidth=4 tabstop=8 expandtab
185  */