~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/poppler/poppler/CharCodeToUnicode.cc

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//========================================================================
 
2
//
 
3
// CharCodeToUnicode.cc
 
4
//
 
5
// Copyright 2001-2003 Glyph & Cog, LLC
 
6
//
 
7
//========================================================================
 
8
 
 
9
//========================================================================
 
10
//
 
11
// Modified under the Poppler project - http://poppler.freedesktop.org
 
12
//
 
13
// All changes made under the Poppler project to this file are licensed
 
14
// under GPL version 2 or later
 
15
//
 
16
// Copyright (C) 2006, 2008-2010 Albert Astals Cid <aacid@kde.org>
 
17
// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
 
18
// Copyright (C) 2007 Koji Otani <sho@bbr.jp>
 
19
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
 
20
// Copyright (C) 2008 Vasile Gaburici <gaburici@cs.umd.edu>
 
21
// Copyright (C) 2010 William Bader <williambader@hotmail.com>
 
22
// Copyright (C) 2010 Jakub Wilk <ubanus@users.sf.net>
 
23
//
 
24
// To see a description of the changes please see the Changelog file that
 
25
// came with your tarball or type make ChangeLog if you are building from git
 
26
//
 
27
//========================================================================
 
28
 
 
29
#include <config.h>
 
30
 
 
31
#ifdef USE_GCC_PRAGMAS
 
32
#pragma implementation
 
33
#endif
 
34
 
 
35
#include <stdio.h>
 
36
#include <string.h>
 
37
#include "goo/gmem.h"
 
38
#include "goo/gfile.h"
 
39
#include "goo/GooLikely.h"
 
40
#include "goo/GooString.h"
 
41
#include "Error.h"
 
42
#include "GlobalParams.h"
 
43
#include "PSTokenizer.h"
 
44
#include "CharCodeToUnicode.h"
 
45
 
 
46
//------------------------------------------------------------------------
 
47
 
 
48
struct CharCodeToUnicodeString {
 
49
  CharCode c;
 
50
  Unicode *u;
 
51
  int len;
 
52
};
 
53
 
 
54
//------------------------------------------------------------------------
 
55
 
 
56
static int getCharFromString(void *data) {
 
57
  char *p;
 
58
  int c;
 
59
 
 
60
  p = *(char **)data;
 
61
  if (*p) {
 
62
    c = *p++;
 
63
    *(char **)data = p;
 
64
  } else {
 
65
    c = EOF;
 
66
  }
 
67
  return c;
 
68
}
 
69
 
 
70
static int getCharFromFile(void *data) {
 
71
  return fgetc((FILE *)data);
 
72
}
 
73
 
 
74
//------------------------------------------------------------------------
 
75
 
 
76
CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName,
 
77
                                                        GooString *collection) {
 
78
  FILE *f;
 
79
  Unicode *mapA;
 
80
  CharCode size, mapLenA;
 
81
  char buf[64];
 
82
  Unicode u;
 
83
  CharCodeToUnicode *ctu;
 
84
 
 
85
  if (!(f = fopen(fileName->getCString(), "r"))) {
 
86
    error(-1, "Couldn't open cidToUnicode file '%s'",
 
87
          fileName->getCString());
 
88
    return NULL;
 
89
  }
 
90
 
 
91
  size = 32768;
 
92
  mapA = (Unicode *)gmallocn(size, sizeof(Unicode));
 
93
  mapLenA = 0;
 
94
 
 
95
  while (getLine(buf, sizeof(buf), f)) {
 
96
    if (mapLenA == size) {
 
97
      size *= 2;
 
98
      mapA = (Unicode *)greallocn(mapA, size, sizeof(Unicode));
 
99
    }
 
100
    if (sscanf(buf, "%x", &u) == 1) {
 
101
      mapA[mapLenA] = u;
 
102
    } else {
 
103
      error(-1, "Bad line (%d) in cidToUnicode file '%s'",
 
104
            (int)(mapLenA + 1), fileName->getCString());
 
105
      mapA[mapLenA] = 0;
 
106
    }
 
107
    ++mapLenA;
 
108
  }
 
109
  fclose(f);
 
110
 
 
111
  ctu = new CharCodeToUnicode(collection->copy(), mapA, mapLenA, gTrue,
 
112
                              NULL, 0, 0);
 
113
  gfree(mapA);
 
114
  return ctu;
 
115
}
 
116
 
 
117
CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(
 
118
                                                    GooString *fileName) {
 
119
  FILE *f;
 
120
  Unicode *mapA;
 
121
  CharCodeToUnicodeString *sMapA;
 
122
  CharCode size, oldSize, len, sMapSizeA, sMapLenA;
 
123
  char buf[256];
 
124
  char *tok;
 
125
  Unicode u0;
 
126
  int uBufSize = 8;
 
127
  Unicode *uBuf = (Unicode *)gmallocn(uBufSize, sizeof(Unicode));
 
128
  CharCodeToUnicode *ctu;
 
129
  int line, n, i;
 
130
  char *tokptr;
 
131
 
 
132
  if (!(f = fopen(fileName->getCString(), "r"))) {
 
133
    gfree(uBuf);
 
134
    error(-1, "Couldn't open unicodeToUnicode file '%s'",
 
135
          fileName->getCString());
 
136
    return NULL;
 
137
  }
 
138
 
 
139
  size = 4096;
 
140
  mapA = (Unicode *)gmallocn(size, sizeof(Unicode));
 
141
  memset(mapA, 0, size * sizeof(Unicode));
 
142
  len = 0;
 
143
  sMapA = NULL;
 
144
  sMapSizeA = sMapLenA = 0;
 
145
 
 
146
  line = 0;
 
147
  while (getLine(buf, sizeof(buf), f)) {
 
148
    ++line;
 
149
    if (!(tok = strtok_r(buf, " \t\r\n", &tokptr)) ||
 
150
        sscanf(tok, "%x", &u0) != 1) {
 
151
      error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
 
152
            line, fileName->getCString());
 
153
      continue;
 
154
    }
 
155
    n = 0;
 
156
    while ((tok = strtok_r(NULL, " \t\r\n", &tokptr))) {
 
157
      if (n >= uBufSize)
 
158
      {
 
159
        uBufSize += 8;
 
160
        uBuf = (Unicode *)greallocn(uBuf, uBufSize, sizeof(Unicode));
 
161
      }
 
162
      if (sscanf(tok, "%x", &uBuf[n]) != 1) {
 
163
        error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
 
164
              line, fileName->getCString());
 
165
        break;
 
166
      }
 
167
      ++n;
 
168
    }
 
169
    if (n < 1) {
 
170
      error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
 
171
            line, fileName->getCString());
 
172
      continue;
 
173
    }
 
174
    if (u0 >= size) {
 
175
      oldSize = size;
 
176
      while (u0 >= size) {
 
177
        size *= 2;
 
178
      }
 
179
      mapA = (Unicode *)greallocn(mapA, size, sizeof(Unicode));
 
180
      memset(mapA + oldSize, 0, (size - oldSize) * sizeof(Unicode));
 
181
    }
 
182
    if (n == 1) {
 
183
      mapA[u0] = uBuf[0];
 
184
    } else {
 
185
      mapA[u0] = 0;
 
186
      if (sMapLenA == sMapSizeA) {
 
187
        sMapSizeA += 16;
 
188
        sMapA = (CharCodeToUnicodeString *)
 
189
                  greallocn(sMapA, sMapSizeA, sizeof(CharCodeToUnicodeString));
 
190
      }
 
191
      sMapA[sMapLenA].c = u0;
 
192
      sMapA[sMapLenA].u = (Unicode*)gmallocn(n, sizeof(Unicode));
 
193
      for (i = 0; i < n; ++i) {
 
194
        sMapA[sMapLenA].u[i] = uBuf[i];
 
195
      }
 
196
      sMapA[sMapLenA].len = n;
 
197
      ++sMapLenA;
 
198
    }
 
199
    if (u0 >= len) {
 
200
      len = u0 + 1;
 
201
    }
 
202
  }
 
203
  fclose(f);
 
204
 
 
205
  ctu = new CharCodeToUnicode(fileName->copy(), mapA, len, gTrue,
 
206
                              sMapA, sMapLenA, sMapSizeA);
 
207
  gfree(mapA);
 
208
  gfree(uBuf);
 
209
  return ctu;
 
210
}
 
211
 
 
212
CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
 
213
  return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0, 0);
 
214
}
 
215
 
 
216
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GooString *buf, int nBits) {
 
217
  CharCodeToUnicode *ctu;
 
218
  char *p;
 
219
 
 
220
  ctu = new CharCodeToUnicode(NULL);
 
221
  p = buf->getCString();
 
222
  ctu->parseCMap1(&getCharFromString, &p, nBits);
 
223
  return ctu;
 
224
}
 
225
 
 
226
CharCodeToUnicode *CharCodeToUnicode::parseCMapFromFile(GooString *fileName,
 
227
  int nBits) {
 
228
  CharCodeToUnicode *ctu;
 
229
  FILE *f;
 
230
 
 
231
  ctu = new CharCodeToUnicode(NULL);
 
232
  if ((f = globalParams->findToUnicodeFile(fileName))) {
 
233
    ctu->parseCMap1(&getCharFromFile, f, nBits);
 
234
    fclose(f);
 
235
  } else {
 
236
    error(-1, "Couldn't find ToUnicode CMap file for '%s'",
 
237
          fileName->getCString());
 
238
  }
 
239
  return ctu;
 
240
}
 
241
 
 
242
void CharCodeToUnicode::mergeCMap(GooString *buf, int nBits) {
 
243
  char *p;
 
244
 
 
245
  p = buf->getCString();
 
246
  parseCMap1(&getCharFromString, &p, nBits);
 
247
}
 
248
 
 
249
void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
 
250
                                   int nBits) {
 
251
  PSTokenizer *pst;
 
252
  char tok1[256], tok2[256], tok3[256];
 
253
  int nDigits, n1, n2, n3;
 
254
  CharCode i;
 
255
  CharCode code1, code2;
 
256
  GooString *name;
 
257
  FILE *f;
 
258
 
 
259
  nDigits = nBits / 4;
 
260
  pst = new PSTokenizer(getCharFunc, data);
 
261
  pst->getToken(tok1, sizeof(tok1), &n1);
 
262
  while (pst->getToken(tok2, sizeof(tok2), &n2)) {
 
263
    if (!strcmp(tok2, "usecmap")) {
 
264
      if (tok1[0] == '/') {
 
265
        name = new GooString(tok1 + 1);
 
266
        if ((f = globalParams->findToUnicodeFile(name))) {
 
267
          parseCMap1(&getCharFromFile, f, nBits);
 
268
          fclose(f);
 
269
        } else {
 
270
          error(-1, "Couldn't find ToUnicode CMap file for '%s'",
 
271
                name->getCString());
 
272
        }
 
273
        delete name;
 
274
      }
 
275
      pst->getToken(tok1, sizeof(tok1), &n1);
 
276
    } else if (!strcmp(tok2, "beginbfchar")) {
 
277
      while (pst->getToken(tok1, sizeof(tok1), &n1)) {
 
278
        if (!strcmp(tok1, "endbfchar")) {
 
279
          break;
 
280
        }
 
281
        if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
 
282
            !strcmp(tok2, "endbfchar")) {
 
283
          error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
 
284
          break;
 
285
        }
 
286
        if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
 
287
              tok2[0] == '<' && tok2[n2 - 1] == '>')) {
 
288
          if (!(n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0' &&
 
289
                tok2[0] == '<' && tok2[n2 - 1] == '>')) {
 
290
            error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
 
291
            continue;
 
292
          }
 
293
        }
 
294
        tok1[n1 - 1] = tok2[n2 - 1] = '\0';
 
295
        if (sscanf(tok1 + 1, "%x", &code1) != 1) {
 
296
          error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
 
297
          continue;
 
298
        }
 
299
        addMapping(code1, tok2 + 1, n2 - 2, 0);
 
300
      }
 
301
      pst->getToken(tok1, sizeof(tok1), &n1);
 
302
    } else if (!strcmp(tok2, "beginbfrange")) {
 
303
      while (pst->getToken(tok1, sizeof(tok1), &n1)) {
 
304
        if (!strcmp(tok1, "endbfrange")) {
 
305
          break;
 
306
        }
 
307
        if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
 
308
            !strcmp(tok2, "endbfrange") ||
 
309
            !pst->getToken(tok3, sizeof(tok3), &n3) ||
 
310
            !strcmp(tok3, "endbfrange")) {
 
311
          error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
 
312
          break;
 
313
        }
 
314
        if (!(((n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>') ||
 
315
               (n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')) &&
 
316
              ((n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>') ||
 
317
               (n2 == 4 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')))) {
 
318
          error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
 
319
          continue;
 
320
        }
 
321
        tok1[n1 - 1] = tok2[n2 - 1] = '\0';
 
322
        if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
 
323
            sscanf(tok2 + 1, "%x", &code2) != 1) {
 
324
          error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
 
325
          continue;
 
326
        }
 
327
        if (!strcmp(tok3, "[")) {
 
328
          i = 0;
 
329
          while (pst->getToken(tok1, sizeof(tok1), &n1) &&
 
330
                 code1 + i <= code2) {
 
331
            if (!strcmp(tok1, "]")) {
 
332
              break;
 
333
            }
 
334
            if (tok1[0] == '<' && tok1[n1 - 1] == '>') {
 
335
              tok1[n1 - 1] = '\0';
 
336
              addMapping(code1 + i, tok1 + 1, n1 - 2, 0);
 
337
            } else {
 
338
              error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
 
339
            }
 
340
            ++i;
 
341
          }
 
342
        } else if (tok3[0] == '<' && tok3[n3 - 1] == '>') {
 
343
          tok3[n3 - 1] = '\0';
 
344
          for (i = 0; code1 <= code2; ++code1, ++i) {
 
345
            addMapping(code1, tok3 + 1, n3 - 2, i);
 
346
          }
 
347
 
 
348
        } else {
 
349
          error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
 
350
        }
 
351
      }
 
352
      pst->getToken(tok1, sizeof(tok1), &n1);
 
353
    } else {
 
354
      strcpy(tok1, tok2);
 
355
    }
 
356
  }
 
357
  delete pst;
 
358
}
 
359
 
 
360
void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
 
361
                                   int offset) {
 
362
  CharCode oldLen, i;
 
363
  Unicode u;
 
364
  char uHex[5];
 
365
  int j;
 
366
 
 
367
  if (code >= mapLen) {
 
368
    oldLen = mapLen;
 
369
    mapLen = (code + 256) & ~255;
 
370
    if (unlikely(code >= mapLen)) {
 
371
      error(-1, "Illegal code value in CharCodeToUnicode::addMapping");
 
372
      return;
 
373
    } else {
 
374
      map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
 
375
      for (i = oldLen; i < mapLen; ++i) {
 
376
        map[i] = 0;
 
377
      }
 
378
        }
 
379
  }
 
380
  if (n <= 4) {
 
381
    if (sscanf(uStr, "%x", &u) != 1) {
 
382
      error(-1, "Illegal entry in ToUnicode CMap");
 
383
      return;
 
384
    }
 
385
    map[code] = u + offset;
 
386
  } else {
 
387
    if (sMapLen >= sMapSize) {
 
388
      sMapSize = sMapSize + 16;
 
389
      sMap = (CharCodeToUnicodeString *)
 
390
               greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString));
 
391
    }
 
392
    map[code] = 0;
 
393
    sMap[sMapLen].c = code;
 
394
    sMap[sMapLen].len = n / 4;
 
395
    sMap[sMapLen].u = (Unicode*)gmallocn(sMap[sMapLen].len, sizeof(Unicode));
 
396
    for (j = 0; j < sMap[sMapLen].len; ++j) {
 
397
      strncpy(uHex, uStr + j*4, 4);
 
398
      uHex[4] = '\0';
 
399
      if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
 
400
        error(-1, "Illegal entry in ToUnicode CMap");
 
401
      }
 
402
    }
 
403
    sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset;
 
404
    ++sMapLen;
 
405
  }
 
406
}
 
407
 
 
408
CharCodeToUnicode::CharCodeToUnicode(GooString *tagA) {
 
409
  CharCode i;
 
410
 
 
411
  tag = tagA;
 
412
  mapLen = 256;
 
413
  map = (Unicode *)gmallocn(mapLen, sizeof(Unicode));
 
414
  for (i = 0; i < mapLen; ++i) {
 
415
    map[i] = 0;
 
416
  }
 
417
  sMap = NULL;
 
418
  sMapLen = sMapSize = 0;
 
419
  refCnt = 1;
 
420
#if MULTITHREADED
 
421
  gInitMutex(&mutex);
 
422
#endif
 
423
}
 
424
 
 
425
CharCodeToUnicode::CharCodeToUnicode(GooString *tagA, Unicode *mapA,
 
426
                                     CharCode mapLenA, GBool copyMap,
 
427
                                     CharCodeToUnicodeString *sMapA,
 
428
                                     int sMapLenA, int sMapSizeA) {
 
429
  tag = tagA;
 
430
  mapLen = mapLenA;
 
431
  if (copyMap) {
 
432
    map = (Unicode *)gmallocn(mapLen, sizeof(Unicode));
 
433
    memcpy(map, mapA, mapLen * sizeof(Unicode));
 
434
  } else {
 
435
    map = mapA;
 
436
  }
 
437
  sMap = sMapA;
 
438
  sMapLen = sMapLenA;
 
439
  sMapSize = sMapSizeA;
 
440
  refCnt = 1;
 
441
#if MULTITHREADED
 
442
  gInitMutex(&mutex);
 
443
#endif
 
444
}
 
445
 
 
446
CharCodeToUnicode::~CharCodeToUnicode() {
 
447
  if (tag) {
 
448
    delete tag;
 
449
  }
 
450
  gfree(map);
 
451
  if (sMap) {
 
452
    for (int i = 0; i < sMapLen; ++i) gfree(sMap[i].u);
 
453
    gfree(sMap);
 
454
  }
 
455
#if MULTITHREADED
 
456
  gDestroyMutex(&mutex);
 
457
#endif
 
458
}
 
459
 
 
460
void CharCodeToUnicode::incRefCnt() {
 
461
#if MULTITHREADED
 
462
  gLockMutex(&mutex);
 
463
#endif
 
464
  ++refCnt;
 
465
#if MULTITHREADED
 
466
  gUnlockMutex(&mutex);
 
467
#endif
 
468
}
 
469
 
 
470
void CharCodeToUnicode::decRefCnt() {
 
471
  GBool done;
 
472
 
 
473
#if MULTITHREADED
 
474
  gLockMutex(&mutex);
 
475
#endif
 
476
  done = --refCnt == 0;
 
477
#if MULTITHREADED
 
478
  gUnlockMutex(&mutex);
 
479
#endif
 
480
  if (done) {
 
481
    delete this;
 
482
  }
 
483
}
 
484
 
 
485
GBool CharCodeToUnicode::match(GooString *tagA) {
 
486
  return tag && !tag->cmp(tagA);
 
487
}
 
488
 
 
489
void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) {
 
490
  int i, j;
 
491
 
 
492
  if (len == 1) {
 
493
    map[c] = u[0];
 
494
  } else {
 
495
    for (i = 0; i < sMapLen; ++i) {
 
496
      if (sMap[i].c == c) {
 
497
        gfree(sMap[i].u);
 
498
        break;
 
499
      }
 
500
    }
 
501
    if (i == sMapLen) {
 
502
      if (sMapLen == sMapSize) {
 
503
        sMapSize += 8;
 
504
        sMap = (CharCodeToUnicodeString *)
 
505
                 greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString));
 
506
      }
 
507
      ++sMapLen;
 
508
    }
 
509
    map[c] = 0;
 
510
    sMap[i].c = c;
 
511
    sMap[i].len = len;
 
512
    sMap[i].u = (Unicode*)gmallocn(len, sizeof(Unicode));
 
513
    for (j = 0; j < len; ++j) {
 
514
      sMap[i].u[j] = u[j];
 
515
    }
 
516
  }
 
517
}
 
518
 
 
519
int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode **u) {
 
520
  int i;
 
521
 
 
522
  if (c >= mapLen) {
 
523
    return 0;
 
524
  }
 
525
  if (map[c]) {
 
526
    *u = &map[c];
 
527
    return 1;
 
528
  }
 
529
  for (i = sMapLen - 1; i >= 0; --i) { // in reverse so CMap takes precedence
 
530
    if (sMap[i].c == c) {
 
531
      *u = sMap[i].u;
 
532
      return sMap[i].len;
 
533
    }
 
534
  }
 
535
  return 0;
 
536
}
 
537
 
 
538
int CharCodeToUnicode::mapToCharCode(Unicode* u, CharCode *c, int usize) {
 
539
  //look for charcode in map
 
540
  if (usize == 1) {
 
541
    for (CharCode i=0; i<mapLen; i++) {
 
542
      if (map[i] == *u) {
 
543
        *c = i;
 
544
        return 1;
 
545
      }
 
546
    }
 
547
    *c = 'x';
 
548
  } else {
 
549
    int i, j;
 
550
    //for each entry in the sMap
 
551
    for (i=0; i<sMapLen; i++) {
 
552
      //if the entry's unicode length isn't the same are usize, the strings 
 
553
      // are obviously differents
 
554
      if (sMap[i].len != usize) continue;
 
555
      //compare the string char by char
 
556
      for (j=0; j<sMap[i].len; j++) {
 
557
        if (sMap[i].u[j] != u[j]) {
 
558
          continue;
 
559
        }
 
560
      }
 
561
 
 
562
      //we have the same strings
 
563
      if (j==sMap[i].len) { 
 
564
        *c = sMap[i].c;
 
565
        return 1;
 
566
      }
 
567
    }
 
568
  }
 
569
  return 0;
 
570
}
 
571
 
 
572
//------------------------------------------------------------------------
 
573
 
 
574
CharCodeToUnicodeCache::CharCodeToUnicodeCache(int sizeA) {
 
575
  int i;
 
576
 
 
577
  size = sizeA;
 
578
  cache = (CharCodeToUnicode **)gmallocn(size, sizeof(CharCodeToUnicode *));
 
579
  for (i = 0; i < size; ++i) {
 
580
    cache[i] = NULL;
 
581
  }
 
582
}
 
583
 
 
584
CharCodeToUnicodeCache::~CharCodeToUnicodeCache() {
 
585
  int i;
 
586
 
 
587
  for (i = 0; i < size; ++i) {
 
588
    if (cache[i]) {
 
589
      cache[i]->decRefCnt();
 
590
    }
 
591
  }
 
592
  gfree(cache);
 
593
}
 
594
 
 
595
CharCodeToUnicode *CharCodeToUnicodeCache::getCharCodeToUnicode(GooString *tag) {
 
596
  CharCodeToUnicode *ctu;
 
597
  int i, j;
 
598
 
 
599
  if (cache[0] && cache[0]->match(tag)) {
 
600
    cache[0]->incRefCnt();
 
601
    return cache[0];
 
602
  }
 
603
  for (i = 1; i < size; ++i) {
 
604
    if (cache[i] && cache[i]->match(tag)) {
 
605
      ctu = cache[i];
 
606
      for (j = i; j >= 1; --j) {
 
607
        cache[j] = cache[j - 1];
 
608
      }
 
609
      cache[0] = ctu;
 
610
      ctu->incRefCnt();
 
611
      return ctu;
 
612
    }
 
613
  }
 
614
  return NULL;
 
615
}
 
616
 
 
617
void CharCodeToUnicodeCache::add(CharCodeToUnicode *ctu) {
 
618
  int i;
 
619
 
 
620
  if (cache[size - 1]) {
 
621
    cache[size - 1]->decRefCnt();
 
622
  }
 
623
  for (i = size - 1; i >= 1; --i) {
 
624
    cache[i] = cache[i - 1];
 
625
  }
 
626
  cache[0] = ctu;
 
627
  ctu->incRefCnt();
 
628
}