BRL-CAD
encode.c
Go to the documentation of this file.
1 /* E N C O D E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2010-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <string.h>
24 
25 #include "bu/vls.h"
26 #include "bu/log.h"
27 
28 
29 static const char DQUOTE = '"';
30 static const char ESCAPE = '\\';
31 
32 
33 const char *
34 bu_vls_encode(struct bu_vls *vp, const char *str)
35 {
36  static const char *empty = "";
37  int skip = 0;
38  const char *escape_chars = "\" {}\\$[]\0";
39  const char *ec = NULL;
40  int needs_escaping = 0;
41 
42  if (UNLIKELY(!str))
43  return empty;
44 
45  BU_CK_VLS(vp);
46 
47  skip = bu_vls_strlen(vp);
48 
49  ec = escape_chars;
50  while (*ec != '\0') {
51  if (strchr(str, *ec) != NULL) needs_escaping = 1;
52  ec++;
53  }
54 
55  if (needs_escaping) {
56  bu_vls_putc(vp, DQUOTE);
57  for (; *str != '\0'; str++) {
58  int needs_escape = 0;
59  ec = escape_chars;
60  while (*ec != '\0') {
61  if (*str == *ec) needs_escape = 1;
62  ec++;
63  }
64  if (needs_escape) {
65  bu_vls_putc(vp, ESCAPE);
66  }
67  bu_vls_putc(vp, *str);
68  }
69  bu_vls_putc(vp, DQUOTE);
70  } else {
71  bu_vls_strcat(vp, str);
72  }
73 
74  return bu_vls_addr(vp) + skip;
75 }
76 
77 
78 const char *
79 bu_vls_decode(struct bu_vls *vp, const char *str)
80 {
81  static const char *empty = "";
82 
83  int skip = 0;
84  int dquote = 0;
85  int escape = 0;
86 
87  struct bu_vls quotebuf = BU_VLS_INIT_ZERO;
88 
89  if (UNLIKELY(!str))
90  return empty;
91 
92  BU_CK_VLS(vp);
93 
94  skip = bu_vls_strlen(vp);
95 
96  for (; *str != '\0'; str++) {
97  if (escape) {
98  /* previous character was escaped */
99  if (dquote) {
100  bu_vls_putc(&quotebuf, *str);
101  } else {
102  bu_vls_putc(vp, *str);
103  }
104  escape = 0;
105  continue;
106  }
107 
108  if (*str == ESCAPE) {
109  /* encountered new escape */
110  escape = 1;
111  continue;
112  }
113 
114  if (*str == DQUOTE) {
115  if (!dquote) {
116  /* entering double quote pairing */
117  dquote = 1;
118  } else {
119  /* end of double quote */
120  dquote = 0;
121  bu_vls_vlscatzap(vp, &quotebuf);
122  }
123  continue;
124  }
125 
126  /* if we're inside a quote, buffer up the string until we find
127  * a matching double quote character.
128  */
129  if (dquote) {
130  bu_vls_putc(&quotebuf, *str);
131  } else {
132  bu_vls_putc(vp, *str);
133  }
134  }
135 
136  if (dquote) {
137  /* we got to the end of the input string while still inside a
138  * double-quote. have to assume the quote is regular content.
139  */
140  bu_vls_putc(vp, DQUOTE);
141  bu_vls_vlscatzap(vp, &quotebuf);
142  }
143 
144  bu_vls_free(&quotebuf);
145 
146  return bu_vls_addr(vp) + skip;
147 }
148 
149 
150 /*
151  * Local Variables:
152  * tab-width: 8
153  * mode: C
154  * indent-tabs-mode: t
155  * c-file-style: "stroustrup"
156  * End:
157  * ex: shiftwidth=4 tabstop=8
158  */
const char * bu_vls_encode(struct bu_vls *vp, const char *str)
Definition: encode.c:34
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
Header file for the BRL-CAD common definitions.
char * strchr(const char *sp, int c)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define BU_CK_VLS(_vp)
Definition: vls.h:69
const char * bu_vls_decode(struct bu_vls *vp, const char *str)
Definition: encode.c:79
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
void bu_vls_putc(struct bu_vls *vp, int c)
Definition: vls.c:666
void bu_vls_vlscatzap(struct bu_vls *dest, struct bu_vls *src)
Definition: vls.c:433
#define UNLIKELY(expression)
Definition: common.h:282