ObjFW  Diff

Differences From Artifact [88fdb05c43]:

To Artifact [b53cd466b1]:


26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







 *
 * We already have a clue about how big the resulting string will get, so we
 * can prealloc and only resize when really necessary - OFString would always
 * resize when we append, which would be slow here.
 */

static inline void
xf_resize_chars(char **str, size_t *len, size_t add, Class class)
resize(char **str, size_t *len, size_t add, Class class)
{
	char *str2;
	size_t len2;

	if (add > SIZE_MAX - *len)
		@throw [OFOutOfRangeException newWithClass: class];
	len2 = *len + add;
48
49
50
51
52
53
54
55

56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71

72
73

74
75
76
77

78

79
80

81
82
83


84
85

86
87
88

89
90
91

92
93
94

95
96
97

98
99
100

101
102
103
104
105

106
107
108
109
110
111
112
48
49
50
51
52
53
54

55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70

71
72

73
74
75

76
77

78
79

80
81


82
83
84

85
86
87

88
89
90

91
92
93

94
95
96

97
98
99

100
101
102
103
104

105
106
107
108
109
110
111
112







-
+





-
+









-
+

-
+


-

+
-
+

-
+

-
-
+
+

-
+


-
+


-
+


-
+


-
+


-
+




-
+







	}

	*str = str2;
	*len = len2;
}

static inline void
xf_add2chars(char **str, size_t *len, size_t *pos, const char *add, Class class)
append(char **str, size_t *len, size_t *pos, const char *add, Class class)
{
	size_t add_len;

	add_len = strlen(add);

	xf_resize_chars(str, len, add_len, class);
	resize(str, len, add_len, class);

	memcpy(*str + *pos, add, add_len);
	*pos += add_len;
}

@implementation OFXMLFactory
+ (char*)escapeCString: (const char*)s
{
	char *ret;
	size_t i, j, len, nlen;
	size_t i, len;

	len = nlen = strlen(s);
	len = strlen(s);
	if (SIZE_MAX - len < 1)
		@throw [OFOutOfRangeException newWithClass: self];
	nlen++;

	len++;
	if ((ret = malloc(nlen)) == NULL)
	if ((ret = malloc(len)) == NULL)
		@throw [OFNoMemException newWithClass: self
					      andSize: nlen];
					      andSize: len];

	for (i = j = 0; i < len; i++) {
		switch (s[i]) {
	for (i = 0; *s; s++) {
		switch (*s) {
		case '<':
			xf_add2chars(&ret, &nlen, &j, "&lt;", self);
			append(&ret, &len, &i, "&lt;", self);
			break;
		case '>':
			xf_add2chars(&ret, &nlen, &j, "&gt;", self);
			append(&ret, &len, &i, "&gt;", self);
			break;
		case '"':
			xf_add2chars(&ret, &nlen, &j, "&quot;", self);
			append(&ret, &len, &i, "&quot;", self);
			break;
		case '\'':
			xf_add2chars(&ret, &nlen, &j, "&apos;", self);
			append(&ret, &len, &i, "&apos;", self);
			break;
		case '&':
			xf_add2chars(&ret, &nlen, &j, "&amp;", self);
			append(&ret, &len, &i, "&amp;", self);
			break;
		default:
			ret[j++] = s[i];
			ret[i++] = *s;
			break;
		}
	}

	ret[j] = 0;
	ret[i] = 0;
	return ret;
}

+ (char*)createStanza: (const char*)name
	 withCloseTag: (BOOL)close
	      andData: (const char*)data, ...
{
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153







-
+







		va_start(args, data);

		while ((arg = va_arg(args, char*)) != NULL &&
		    (val = va_arg(args, char*)) != NULL) {
			esc_val = NULL;	/* Needed for our @catch */
			esc_val = [self escapeCString: val];

			xf_resize_chars(&xml, &len, 1 + strlen(arg) + 2 +
			resize(&xml, &len, 1 + strlen(arg) + 2 +
			    strlen(esc_val) + 1, self);

			xml[i++] = ' ';
			memcpy(xml + i, arg, strlen(arg));
			i += strlen(arg);
			xml[i++] = '=';
			xml[i++] = '\'';
167
168
169
170
171
172
173
174

175
176
177
178
179
180


181
182
183
184
185
186
187
167
168
169
170
171
172
173

174
175
176
177
178


179
180
181
182
183
184
185
186
187







-
+




-
-
+
+








		@throw e;
	}

	/* End of tag */
	if (close) {
		if (data == NULL) {
			xf_resize_chars(&xml, &len, 2 - 1, self);
			resize(&xml, &len, 2 - 1, self);

			xml[i++] = '/';
			xml[i++] = '>';
		} else {
			xf_resize_chars(&xml, &len, 1 + strlen(data) + 2 +
			    strlen(name) + 1 - 1, self);
			resize(&xml, &len, 1 + strlen(data) + 2 + strlen(name) +
			    1 - 1, self);

			xml[i++] = '>';
			memcpy(xml + i, data, strlen(data));
			i += strlen(data);
			xml[i++] = '<';
			xml[i++] = '/';
			memcpy(xml + i, name, strlen(name));
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227







-
+








		@throw [OFNoMemException newWithClass: self
					      andSize: len];

	memcpy(ret, strs[0], len - 1);
	pos = len - 1;

	for (i = 1; strs[i] != NULL; i++)
		xf_add2chars(&ret, &len, &pos, strs[i], self);
		append(&ret, &len, &pos, strs[i], self);

	for (i = 0; strs[i] != NULL; i++)
		free(strs[i]);

	ret[pos] = 0;
	return ret;
}
@end