Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gscencs.c
Line
Count
Source
1
/* Copyright (C) 2001-2021 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* Compact C representation of built-in encodings */
18
19
#include "memory_.h"
20
#include "gscedata.h"
21
#include "gscencs.h"
22
#include "gserrors.h"
23
24
/*
25
 * The actual encoding data tables in gscedata.c, and the internal
26
 * interface definitions in gscedata.h, are generated by toolbin/encs2c.ps,
27
 * q.v.
28
 *
29
 * In the encoding tables in gscedata.c, each glyph is represented by a
30
 * ushort (16-bit) value.  A bias of gs_c_min_std_encoding_glyph is added
31
 * or subtracted to form a gs_glyph value.
32
 */
33
34
/*
35
 * gscedata.[hc] defines the following tables:
36
 *  const char gs_c_known_encoding_chars[NUM_CHARS] --
37
 *    the character table.
38
 *  const int gs_c_known_encoding_offsets[NUM_INDIRECT_LEN] --
39
 *    the starting offsets of the names of a given length in the
40
 *    character table.
41
 *  const ushort *const gs_c_known_encodings[] --
42
 *    pointers to the encodings per se.
43
 *  const ushort gs_c_known_encoding_lengths[] --
44
 *    lengths of the encodings.
45
 */
46
47
const gs_glyph gs_c_min_std_encoding_glyph = GS_MIN_CID_GLYPH - 0x10000;
48
49
/*
50
 * Encode a character in a known encoding.  The only use for glyph numbers
51
 * returned by this procedure is to pass them to gs_c_glyph_name or gs_c_decode.
52
 */
53
gs_glyph
54
gs_c_known_encode(gs_char ch, int ei)
55
54.1M
{
56
54.1M
    if (ei < 0 || ei >= gs_c_known_encoding_count ||
57
54.1M
        ch >= gs_c_known_encoding_lengths[ei]
58
54.1M
        )
59
7.91k
        return GS_NO_GLYPH;
60
54.1M
    return gs_c_min_std_encoding_glyph + gs_c_known_encodings[ei][ch];
61
54.1M
}
62
63
/*
64
 * Decode a gs_c_glyph_name glyph with a known encoding.
65
 */
66
gs_char
67
gs_c_decode(gs_glyph glyph, int ei)
68
656k
{
69
    /* Do a binary search for glyph, using gx_c_known_encodings_reverse */
70
656k
    const ushort *const encoding = gs_c_known_encodings[ei];
71
656k
    const ushort *const reverse = gs_c_known_encodings_reverse[ei];
72
656k
    int first_index = 0;
73
656k
    int last_index = gs_c_known_encoding_reverse_lengths[ei];
74
4.35M
    while (first_index < last_index) {
75
4.34M
        const int test_index = (first_index + last_index) / 2;
76
4.34M
        const gs_glyph test_glyph =
77
4.34M
         gs_c_min_std_encoding_glyph + encoding[reverse[test_index]];
78
4.34M
        if (glyph < test_glyph)
79
2.18M
            last_index = test_index;
80
2.16M
        else if (glyph > test_glyph)
81
1.51M
            first_index = test_index + 1;
82
654k
        else
83
654k
            return reverse[test_index];
84
4.34M
    }
85
1.80k
    return GS_NO_CHAR;
86
656k
}
87
88
/*
89
 * Convert a glyph number returned by gs_c_known_encode to a string.
90
 */
91
int
92
gs_c_glyph_name(gs_glyph glyph, gs_const_string *pstr)
93
59.2M
{
94
59.2M
    uint n = (uint)(glyph - gs_c_min_std_encoding_glyph);
95
59.2M
    uint len = N_LEN(n);
96
59.2M
    uint off = N_OFFSET(n);
97
98
#ifdef DEBUG
99
    if (len == 0 || len > gs_c_known_encoding_max_length ||
100
        off >= gs_c_known_encoding_offsets[len + 1] -
101
          gs_c_known_encoding_offsets[len] ||
102
        off % len != 0
103
        )
104
        return_error(gs_error_rangecheck);
105
#endif
106
59.2M
    pstr->data = (const byte *)
107
59.2M
        &gs_c_known_encoding_chars[gs_c_known_encoding_offsets[len] + off];
108
59.2M
    pstr->size = len;
109
59.2M
    return 0;
110
59.2M
}
111
112
/*
113
 * Test whether a string is one that was returned by gs_c_glyph_name.
114
 */
115
bool
116
gs_is_c_glyph_name(const byte *str, uint len)
117
26.3M
{
118
26.3M
    return str >= (const byte *)gs_c_known_encoding_chars &&
119
26.3M
           str <  (const byte *)gs_c_known_encoding_chars + gs_c_known_encoding_total_chars;
120
26.3M
}
121
122
/*
123
 * Return the glyph number corresponding to a string (the inverse of
124
 * gs_c_glyph_name), or GS_NO_GLYPH if the glyph name is not known.
125
 */
126
gs_glyph
127
gs_c_name_glyph(const byte *str, uint len)
128
9.83M
{
129
9.83M
    if (len == 0 || len > gs_c_known_encoding_max_length)
130
9.78k
        return GS_NO_GLYPH;
131
    /* Binary search the character table. */
132
9.82M
    {
133
9.82M
        uint base = gs_c_known_encoding_offsets[len];
134
9.82M
        const byte *bot = (const byte *)&gs_c_known_encoding_chars[base];
135
9.82M
        uint count = (gs_c_known_encoding_offsets[len + 1] - base) / len;
136
9.82M
        uint a = 0, b = count;  /* know b > 0 */
137
9.82M
        const byte *probe;
138
139
57.2M
        while (a < b) {   /* know will execute at least once */
140
53.1M
            uint m = (a + b) >> 1;
141
53.1M
            int cmp;
142
143
53.1M
            probe = bot + m * len;
144
53.1M
            cmp = memcmp(str, probe, len);
145
53.1M
            if (cmp == 0)
146
5.77M
                return gs_c_min_std_encoding_glyph + N(len, probe - bot);
147
47.4M
            else if (cmp > 0)
148
22.5M
                a = m + 1;
149
24.8M
            else
150
24.8M
                b = m;
151
53.1M
        }
152
9.82M
    }
153
154
4.05M
    return GS_NO_GLYPH;
155
9.82M
}