22#include "GlobalParams.h"
23#include "UnicodeMap.h"
31 char code[maxExtCode];
37UnicodeMap *UnicodeMap::parse(GString *encodingNameA) {
40 UnicodeMapRange *range;
46 char *tok1, *tok2, *tok3;
48 if (!(f = globalParams->getUnicodeMapFile(encodingNameA))) {
49 error(-1,
"Couldn't find unicodeMap file for the '%s' encoding",
50 encodingNameA->getCString());
54 map =
new UnicodeMap(encodingNameA->copy());
57 map->ranges = (UnicodeMapRange *)gmalloc(size *
sizeof(UnicodeMapRange));
61 while (getLine(buf,
sizeof(buf), f)) {
62 if ((tok1 = strtok(buf,
" \t\r\n")) &&
63 (tok2 = strtok(NULL,
" \t\r\n"))) {
64 if (!(tok3 = strtok(NULL,
" \t\r\n"))) {
68 nBytes = strlen(tok3) / 2;
70 if (map->len == size) {
72 map->ranges = (UnicodeMapRange *)
73 grealloc(map->ranges, size *
sizeof(UnicodeMapRange));
75 range = &map->ranges[map->len];
76 sscanf(tok1,
"%x", &range->start);
77 sscanf(tok2,
"%x", &range->end);
78 sscanf(tok3,
"%x", &range->code);
79 range->nBytes = nBytes;
81 }
else if (tok2 == tok1) {
82 if (map->eMapsLen == eMapsSize) {
84 map->eMaps = (UnicodeMapExt *)
85 grealloc(map->eMaps, eMapsSize *
sizeof(UnicodeMapExt));
87 eMap = &map->eMaps[map->eMapsLen];
88 sscanf(tok1,
"%x", &eMap->u);
89 for (i = 0; i < nBytes; ++i) {
90 sscanf(tok3 + i*2,
"%2x", &x);
91 eMap->code[i] = (char)x;
93 eMap->nBytes = nBytes;
96 error(-1,
"Bad line (%d) in unicodeMap file for the '%s' encoding",
97 line, encodingNameA->getCString());
100 error(-1,
"Bad line (%d) in unicodeMap file for the '%s' encoding",
101 line, encodingNameA->getCString());
111UnicodeMap::UnicodeMap(GString *encodingNameA) {
112 encodingName = encodingNameA;
114 kind = unicodeMapUser;
122UnicodeMap::UnicodeMap(
const char *encodingNameA, GBool unicodeOutA,
123 UnicodeMapRange *rangesA,
int lenA) {
124 encodingName =
new GString(encodingNameA);
125 unicodeOut = unicodeOutA;
126 kind = unicodeMapResident;
134UnicodeMap::UnicodeMap(
const char *encodingNameA, GBool unicodeOutA,
135 UnicodeMapFunc funcA) {
136 encodingName =
new GString(encodingNameA);
137 unicodeOut = unicodeOutA;
138 kind = unicodeMapFunc;
145UnicodeMap::~UnicodeMap() {
147 if (kind == unicodeMapUser && ranges) {
155void UnicodeMap::incRefCnt() {
159void UnicodeMap::decRefCnt() {
165GBool UnicodeMap::match(GString *encodingNameA) {
166 return !encodingName->cmp(encodingNameA);
169int UnicodeMap::mapUnicode(Unicode u,
char *buf,
int bufSize) {
170 int a, b, m, n, i, j;
173 if (kind == unicodeMapFunc) {
174 return (*func)(u, buf, bufSize);
179 if (u < ranges[a].start) {
185 if (u >= ranges[m].start) {
187 }
else if (u < ranges[m].start) {
191 if (u <= ranges[a].end) {
192 n = ranges[a].nBytes;
196 code = ranges[a].code + (u - ranges[a].start);
197 for (i = n - 1; i >= 0; --i) {
198 buf[i] = (char)(code & 0xff);
204 for (i = 0; i < eMapsLen; ++i) {
205 if (eMaps[i].u == u) {
207 for (j = 0; j < n; ++j) {
208 buf[j] = eMaps[i].code[j];
219UnicodeMapCache::UnicodeMapCache() {
222 for (i = 0; i < unicodeMapCacheSize; ++i) {
227UnicodeMapCache::~UnicodeMapCache() {
230 for (i = 0; i < unicodeMapCacheSize; ++i) {
232 cache[i]->decRefCnt();
237UnicodeMap *UnicodeMapCache::getUnicodeMap(GString *encodingName) {
241 if (cache[0] && cache[0]->match(encodingName)) {
242 cache[0]->incRefCnt();
245 for (i = 1; i < unicodeMapCacheSize; ++i) {
246 if (cache[i] && cache[i]->match(encodingName)) {
248 for (j = i; j >= 1; --j) {
249 cache[j] = cache[j - 1];
256 if ((map = UnicodeMap::parse(encodingName))) {
257 if (cache[unicodeMapCacheSize - 1]) {
258 cache[unicodeMapCacheSize - 1]->decRefCnt();
260 for (j = unicodeMapCacheSize - 1; j >= 1; --j) {
261 cache[j] = cache[j - 1];