~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/extensions/universalchardet/src/nsSBCSGroupProber.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#include <stdio.h>
 
40
#include "prmem.h"
 
41
 
 
42
#include "nsSBCharSetProber.h"
 
43
#include "nsSBCSGroupProber.h"
 
44
 
 
45
 
 
46
nsSBCSGroupProber::nsSBCSGroupProber()
 
47
{
 
48
  mProbers[0] = new nsSingleByteCharSetProber(&Win1251Model);
 
49
  mProbers[1] = new nsSingleByteCharSetProber(&Koi8rModel);
 
50
  mProbers[2] = new nsSingleByteCharSetProber(&Latin5Model);
 
51
  mProbers[3] = new nsSingleByteCharSetProber(&MacCyrillicModel);
 
52
  mProbers[4] = new nsSingleByteCharSetProber(&Ibm866Model);
 
53
  mProbers[5] = new nsSingleByteCharSetProber(&Ibm855Model);
 
54
  mProbers[6] = new nsSingleByteCharSetProber(&Latin7Model);
 
55
  mProbers[7] = new nsSingleByteCharSetProber(&Win1253Model);
 
56
  mProbers[8] = new nsSingleByteCharSetProber(&Latin5BulgarianModel);
 
57
  mProbers[9] = new nsSingleByteCharSetProber(&Win1251BulgarianModel);
 
58
 
 
59
  // disable latin2 before latin1 is available, otherwise all latin1 
 
60
  // will be detected as latin2 because of their similarity.
 
61
  //mProbers[10] = new nsSingleByteCharSetProber(&Latin2HungarianModel);
 
62
  //mProbers[11] = new nsSingleByteCharSetProber(&Win1250HungarianModel);
 
63
 
 
64
  Reset();
 
65
}
 
66
 
 
67
nsSBCSGroupProber::~nsSBCSGroupProber()
 
68
{
 
69
  for (PRUint32 i = 0; i < NUM_OF_SBCS_PROBERS; i++)
 
70
  {
 
71
    delete mProbers[i];
 
72
  }
 
73
}
 
74
 
 
75
 
 
76
const char* nsSBCSGroupProber::GetCharSetName()
 
77
{
 
78
  //if we have no answer yet
 
79
  if (mBestGuess == -1)
 
80
  {
 
81
    GetConfidence();
 
82
    //no charset seems positive
 
83
    if (mBestGuess == -1)
 
84
      //we will use default.
 
85
      mBestGuess = 0;
 
86
  }
 
87
  return mProbers[mBestGuess]->GetCharSetName();
 
88
}
 
89
 
 
90
void  nsSBCSGroupProber::Reset(void)
 
91
{
 
92
  for (PRUint32 i = 0; i < NUM_OF_SBCS_PROBERS; i++)
 
93
  {
 
94
    mProbers[i]->Reset();
 
95
    mIsActive[i] = PR_TRUE;
 
96
  }
 
97
  mActiveNum = NUM_OF_SBCS_PROBERS;
 
98
  mBestGuess = -1;
 
99
  mState = eDetecting;
 
100
}
 
101
 
 
102
//This filter apply to all scripts that does not use latin letters (english letter)
 
103
PRBool nsSBCSGroupProber::FilterWithoutEnglishLetters(const char* aBuf, PRUint32 aLen, char** newBuf, PRUint32& newLen)
 
104
{
 
105
  //do filtering to reduce load to probers
 
106
  char *newptr;
 
107
  char *prevPtr, *curPtr;
 
108
  
 
109
  PRBool meetMSB = PR_FALSE;   
 
110
  newptr = *newBuf = (char*)PR_MALLOC(aLen);
 
111
  if (!newptr)
 
112
    return PR_FALSE;
 
113
 
 
114
  for (curPtr = prevPtr = (char*)aBuf; curPtr < aBuf+aLen; curPtr++)
 
115
  {
 
116
    if (*curPtr & 0x80)
 
117
    {
 
118
      meetMSB = PR_TRUE;
 
119
    }
 
120
    else if (*curPtr < 'A' || (*curPtr > 'Z' && *curPtr < 'a') || *curPtr > 'z') 
 
121
    {
 
122
      //current char is a symbol, most likely a punctuation. we treat it as segment delimiter
 
123
      if (meetMSB && curPtr > prevPtr) 
 
124
      //this segment contains more than single symbol, and it has upper ascii, we need to keep it
 
125
      {
 
126
        while (prevPtr < curPtr) *newptr++ = *prevPtr++;  
 
127
        prevPtr++;
 
128
        *newptr++ = ' ';
 
129
        meetMSB = PR_FALSE;
 
130
      }
 
131
      else //ignore current segment. (either because it is just a symbol or just a english word
 
132
        prevPtr = curPtr+1;
 
133
    }
 
134
  }
 
135
  if (meetMSB && curPtr > prevPtr) 
 
136
    while (prevPtr < curPtr) *newptr++ = *prevPtr++;  
 
137
 
 
138
  newLen = newptr - *newBuf;
 
139
 
 
140
  return PR_TRUE;
 
141
}
 
142
 
 
143
#ifdef  NO_ENGLISH_CONTAMINATION 
 
144
//This filter apply to all scripts that does use latin letters (english letter)
 
145
PRBool nsSBCSGroupProber::FilterWithEnglishLetters(const char* aBuf, PRUint32 aLen, char** newBuf, PRUint32& newLen)
 
146
{
 
147
  //do filtering to reduce load to probers
 
148
  char *newptr;
 
149
  char *prevPtr, *curPtr;
 
150
  PRBool isInTag = PR_FALSE;
 
151
 
 
152
  newptr = *newBuf = (char*)PR_MALLOC(aLen);
 
153
  if (!newptr)
 
154
    return PR_FALSE;
 
155
 
 
156
  for (curPtr = prevPtr = (char*)aBuf; curPtr < aBuf+aLen; curPtr++)
 
157
  {
 
158
                if (*curPtr == '>')
 
159
                        isInTag = PR_FALSE;
 
160
    else if (*curPtr == '<')
 
161
      isInTag = PR_TRUE;
 
162
 
 
163
    if (!(*curPtr & 0x80) &&
 
164
        (*curPtr < 'A' || (*curPtr > 'Z' && *curPtr < 'a') || *curPtr > 'z') )
 
165
    {
 
166
      if (curPtr > prevPtr && !isInTag) //current segment contains more than just a symbol 
 
167
                                        // and it is not inside a tag, keep it
 
168
      {
 
169
        while (prevPtr < curPtr) *newptr++ = *prevPtr++;  
 
170
        prevPtr++;
 
171
        *newptr++ = ' ';
 
172
      }
 
173
      else
 
174
        prevPtr = curPtr+1;
 
175
    }
 
176
  }
 
177
 
 
178
  // If the current segment contains more than just a symbol 
 
179
  // and it is not inside a tag then keep it.
 
180
  if (curPtr > prevPtr && !isInTag)
 
181
    while (prevPtr < curPtr)
 
182
      *newptr++ = *prevPtr++;  
 
183
 
 
184
  newLen = newptr - *newBuf;
 
185
 
 
186
  return PR_TRUE;
 
187
}
 
188
#endif //NO_ENGLISH_CONTAMINATION
 
189
 
 
190
nsProbingState nsSBCSGroupProber::HandleData(const char* aBuf, PRUint32 aLen)
 
191
{
 
192
  nsProbingState st;
 
193
  PRUint32 i;
 
194
  char *newBuf1;
 
195
  PRUint32 newLen1;
 
196
 
 
197
  //apply filter to original buffer, and we got new buffer back
 
198
  //depend on what script it is, we will feed them the new buffer 
 
199
  //we got after applying proper filter
 
200
  FilterWithoutEnglishLetters(aBuf, aLen, &newBuf1, newLen1);
 
201
 
 
202
  for (i = 0; i < NUM_OF_SBCS_PROBERS; i++)
 
203
  {
 
204
     if (!mIsActive[i])
 
205
       continue;
 
206
     st = mProbers[i]->HandleData(newBuf1, newLen1);
 
207
     if (st == eFoundIt)
 
208
     {
 
209
       mBestGuess = i;
 
210
       mState = eFoundIt;
 
211
       break;
 
212
     }
 
213
     else if (st == eNotMe)
 
214
     {
 
215
       mIsActive[i] = PR_FALSE;
 
216
       mActiveNum--;
 
217
       if (mActiveNum <= 0)
 
218
       {
 
219
         mState = eNotMe;
 
220
         break;
 
221
       }
 
222
     }
 
223
  }
 
224
 
 
225
  PR_FREEIF(newBuf1);
 
226
 
 
227
  return mState;
 
228
}
 
229
 
 
230
float nsSBCSGroupProber::GetConfidence(void)
 
231
{
 
232
  PRUint32 i;
 
233
  float bestConf = 0.0, cf;
 
234
 
 
235
  switch (mState)
 
236
  {
 
237
  case eFoundIt:
 
238
    return (float)0.99; //sure yes
 
239
  case eNotMe:
 
240
    return (float)0.01;  //sure no
 
241
  default:
 
242
    for (i = 0; i < NUM_OF_SBCS_PROBERS; i++)
 
243
    {
 
244
      if (!mIsActive[i])
 
245
        continue;
 
246
      cf = mProbers[i]->GetConfidence();
 
247
      if (bestConf < cf)
 
248
      {
 
249
        bestConf = cf;
 
250
        mBestGuess = i;
 
251
      }
 
252
    }
 
253
  }
 
254
  return bestConf;
 
255
}
 
256
 
 
257
#ifdef DEBUG_chardet
 
258
void 
 
259
nsSBCSGroupProber::DumpStatus()
 
260
{
 
261
  PRUint32 i;
 
262
  float cf;
 
263
  
 
264
  cf = GetConfidence();
 
265
  printf("SBCS Group Prober --------begin status \r\n");
 
266
  for (i = 0; i < NUM_OF_SBCS_PROBERS; i++)
 
267
  {
 
268
    if (!mIsActive[i])
 
269
      printf("[%s] is inactive(ie. cofidence is too low).\r\n", mProbers[i]->GetCharSetName(), i);
 
270
    else
 
271
      mProbers[i]->DumpStatus();
 
272
  }
 
273
  printf("SBCS Group found best match [%s] confidence %f.\r\n", 
 
274
        mProbers[mBestGuess]->GetCharSetName(), cf);
 
275
}
 
276
#endif