Coverage Report

Created: 2025-08-11 08:01

/src/jasper/src/libjasper/base/jas_tvp.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2001-2002 Michael David Adams.
3
 * All rights reserved.
4
 */
5
6
/* __START_OF_JASPER_LICENSE__
7
 * 
8
 * JasPer License Version 2.0
9
 * 
10
 * Copyright (c) 2001-2006 Michael David Adams
11
 * Copyright (c) 1999-2000 Image Power, Inc.
12
 * Copyright (c) 1999-2000 The University of British Columbia
13
 * 
14
 * All rights reserved.
15
 * 
16
 * Permission is hereby granted, free of charge, to any person (the
17
 * "User") obtaining a copy of this software and associated documentation
18
 * files (the "Software"), to deal in the Software without restriction,
19
 * including without limitation the rights to use, copy, modify, merge,
20
 * publish, distribute, and/or sell copies of the Software, and to permit
21
 * persons to whom the Software is furnished to do so, subject to the
22
 * following conditions:
23
 * 
24
 * 1.  The above copyright notices and this permission notice (which
25
 * includes the disclaimer below) shall be included in all copies or
26
 * substantial portions of the Software.
27
 * 
28
 * 2.  The name of a copyright holder shall not be used to endorse or
29
 * promote products derived from the Software without specific prior
30
 * written permission.
31
 * 
32
 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
33
 * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
34
 * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
35
 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37
 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
38
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
39
 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
40
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
41
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
42
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
43
 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
44
 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
45
 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
46
 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
47
 * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
48
 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
49
 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
50
 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
51
 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
52
 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
53
 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
54
 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
55
 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
56
 * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
57
 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
58
 * 
59
 * __END_OF_JASPER_LICENSE__
60
 */
61
62
/*
63
 * Tag-Value Parser Library
64
 *
65
 * $Id$
66
 */
67
68
/******************************************************************************\
69
* Includes.
70
\******************************************************************************/
71
72
#define JAS_FOR_INTERNAL_USE_ONLY
73
74
#include "jasper/jas_tvp.h"
75
#include "jasper/jas_malloc.h"
76
#include "jasper/jas_string.h"
77
78
#include <ctype.h>
79
#include <string.h>
80
81
/******************************************************************************\
82
* Macros.
83
\******************************************************************************/
84
85
/* Is the specified character valid for a tag name? */
86
#define JAS_TVP_ISTAG(x) \
87
74.0k
  (isalpha(x) || (x) == '_' || isdigit(x))
88
89
/******************************************************************************\
90
* Code for creating and destroying a tag-value parser.
91
\******************************************************************************/
92
93
jas_tvparser_t *jas_tvparser_create(const char *s)
94
5.69k
{
95
5.69k
  jas_tvparser_t *tvp;
96
5.69k
  if (!(tvp = jas_malloc(sizeof(jas_tvparser_t)))) {
97
0
    return 0;
98
0
  }
99
5.69k
  if (!(tvp->buf = jas_strdup(s))) {
100
0
    jas_tvparser_destroy(tvp);
101
0
    return 0;
102
0
  }
103
5.69k
  tvp->pos = tvp->buf;
104
5.69k
  tvp->tag = 0;
105
5.69k
  tvp->val = 0;
106
5.69k
  return tvp;
107
5.69k
}
108
109
void jas_tvparser_destroy(jas_tvparser_t *tvp)
110
5.69k
{
111
5.69k
  if (tvp->buf) {
112
5.69k
    jas_free(tvp->buf);
113
5.69k
  }
114
5.69k
  jas_free(tvp);
115
5.69k
}
116
117
/******************************************************************************\
118
* Main parsing code.
119
\******************************************************************************/
120
121
/* Get the next tag-value pair. */
122
int jas_tvparser_next(jas_tvparser_t *tvp)
123
11.3k
{
124
11.3k
  char *p;
125
11.3k
  char *tag;
126
11.3k
  char *val;
127
128
  /* Skip any leading whitespace. */
129
11.3k
  p = tvp->pos;
130
11.3k
  while (*p != '\0' && isspace(JAS_CAST(unsigned char, *p))) {
131
0
    ++p;
132
0
  }
133
134
  /* Has the end of the input data been reached? */
135
11.3k
  if (*p == '\0') {
136
    /* No more tags are present. */
137
5.69k
    tvp->pos = p;
138
5.69k
    return 1;
139
5.69k
  }
140
141
  /* Does the tag name begin with a valid character? */
142
5.69k
  if (!JAS_TVP_ISTAG(JAS_CAST(unsigned char, *p))) {
143
0
    return -1;
144
0
  }
145
146
  /* Remember where the tag name begins. */
147
5.69k
  tag = p;
148
149
  /* Find the end of the tag name. */
150
68.3k
  while (*p != '\0' && JAS_TVP_ISTAG(JAS_CAST(unsigned char, *p))) {
151
62.6k
    ++p;
152
62.6k
  }
153
154
  /* Has the end of the input data been reached? */
155
5.69k
  if (*p == '\0') {
156
    /* The value field is empty. */
157
0
    tvp->tag = tag;
158
0
    tvp->val = "";
159
0
    tvp->pos = p;
160
0
    return 0;
161
0
  }
162
163
  /* Is a value field not present? */
164
5.69k
  if (*p != '=') {
165
0
    if (*p != '\0' && !isspace(JAS_CAST(unsigned char, *p))) {
166
0
      return -1;
167
0
    }
168
0
    *p++ = '\0';
169
0
    tvp->tag = tag;
170
0
    tvp->val = "";
171
0
    tvp->pos = p;
172
0
    return 0;
173
0
  }
174
175
5.69k
  *p++ = '\0';
176
177
5.69k
  val = p;
178
56.9k
  while (*p != '\0' && !isspace(JAS_CAST(unsigned char, *p))) {
179
51.2k
    ++p;
180
51.2k
  }
181
182
5.69k
  if (*p != '\0') {
183
5.69k
    *p++ = '\0';
184
5.69k
  }
185
186
5.69k
  tvp->pos = p;
187
5.69k
  tvp->tag = tag;
188
5.69k
  tvp->val = val;
189
190
5.69k
  return 0;
191
5.69k
}
192
193
/******************************************************************************\
194
* Code for querying the current tag/value.
195
\******************************************************************************/
196
197
/* Get the current tag. */
198
const char *jas_tvparser_gettag(const jas_tvparser_t *tvp)
199
5.69k
{
200
5.69k
  return tvp->tag;
201
5.69k
}
202
203
/* Get the current value. */
204
const char *jas_tvparser_getval(const jas_tvparser_t *tvp)
205
5.69k
{
206
5.69k
  return tvp->val;
207
5.69k
}
208
209
/******************************************************************************\
210
* Miscellaneous code.
211
\******************************************************************************/
212
213
/* Lookup a tag by name. */
214
const jas_taginfo_t *jas_taginfos_lookup(const jas_taginfo_t *taginfos, const char *name)
215
5.69k
{
216
5.69k
  const jas_taginfo_t *taginfo;
217
5.69k
  taginfo = taginfos;
218
10.2k
  while (taginfo->id >= 0) {
219
10.2k
    if (!strcmp(taginfo->name, name)) {
220
5.69k
      return taginfo;
221
5.69k
    }
222
4.54k
    ++taginfo;
223
4.54k
  }
224
0
  return 0;
225
5.69k
}
226
227
/* This function is simply for convenience. */
228
/* One can avoid testing for the special case of a null pointer, by
229
  using this function.   This function never returns a null pointer.  */
230
const jas_taginfo_t *jas_taginfo_nonull(const jas_taginfo_t *taginfo)
231
5.69k
{
232
5.69k
  static const jas_taginfo_t invalidtaginfo = {
233
5.69k
    -1, 0
234
5.69k
  };
235
  
236
5.69k
  return taginfo ? taginfo : &invalidtaginfo;
237
5.69k
}