Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f1366a3

Browse files
authored
Merge pull request #13332 from QuLogic/std-string
MNT: Rewrite convert_to_string using std::string
2 parents 8219a14 + 8b0e15c commit f1366a3

File tree

2 files changed

+51
-102
lines changed

2 files changed

+51
-102
lines changed

src/_path.h

Lines changed: 44 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <vector>
99
#include <cmath>
1010
#include <algorithm>
11+
#include <string>
1112

1213
#include "agg_conv_contour.h"
1314
#include "agg_conv_curve.h"
@@ -1044,40 +1045,11 @@ void quad2cubic(double x0, double y0,
10441045
outy[2] = y2;
10451046
}
10461047

1047-
char *__append_to_string(char *p, char **buffer, size_t *buffersize,
1048-
const char *content)
1049-
{
1050-
for (const char *i = content; *i; ++i) {
1051-
if (p < *buffer) {
1052-
/* This is just an internal error */
1053-
return NULL;
1054-
}
1055-
if ((size_t)(p - *buffer) >= *buffersize) {
1056-
char *newbuffer;
1057-
ptrdiff_t diff = p - *buffer;
1058-
*buffersize *= 2;
1059-
newbuffer = (char *)realloc(*buffer, *buffersize);
1060-
if (newbuffer == NULL) {
1061-
return NULL;
1062-
}
1063-
*buffer = newbuffer;
1064-
p = *buffer + diff;
1065-
}
1066-
1067-
*p++ = *i;
1068-
}
1069-
1070-
return p;
1071-
}
1072-
10731048

1074-
char *__add_number(double val, const char *format, int precision,
1075-
char **buffer, char *p, size_t *buffersize)
1049+
void __add_number(double val, char format_code, int precision,
1050+
std::string& buffer)
10761051
{
1077-
char *result;
1078-
1079-
char *str;
1080-
str = PyOS_double_to_string(val, format[0], precision, 0, NULL);
1052+
char *str = PyOS_double_to_string(val, format_code, precision, 0, NULL);
10811053

10821054
// Delete trailing zeros and decimal point
10831055
char *q = str;
@@ -1090,7 +1062,7 @@ char *__add_number(double val, const char *format, int precision,
10901062
// Rewind through all the zeros
10911063
}
10921064

1093-
// If the end is a decimal qoint, delete that too
1065+
// If the end is a decimal point, delete that too
10941066
if (q >= str && *q == '.') {
10951067
--q;
10961068
}
@@ -1099,27 +1071,25 @@ char *__add_number(double val, const char *format, int precision,
10991071
++q;
11001072
*q = 0;
11011073

1102-
if ((result = __append_to_string(p, buffer, buffersize, str)) == NULL) {
1074+
try {
1075+
buffer += str;
1076+
} catch (std::bad_alloc& e) {
11031077
PyMem_Free(str);
1104-
return NULL;
1078+
throw e;
11051079
}
11061080
PyMem_Free(str);
1107-
1108-
return result;
11091081
}
11101082

11111083

11121084
template <class PathIterator>
1113-
int __convert_to_string(PathIterator &path,
1114-
int precision,
1115-
char **codes,
1116-
bool postfix,
1117-
char **buffer,
1118-
size_t *buffersize)
1085+
bool __convert_to_string(PathIterator &path,
1086+
int precision,
1087+
char **codes,
1088+
bool postfix,
1089+
std::string& buffer)
11191090
{
1120-
const char *format = "f";
1091+
const char format_code = 'f';
11211092

1122-
char *p = *buffer;
11231093
double x[3];
11241094
double y[3];
11251095
double last_x = 0.0;
@@ -1131,14 +1101,14 @@ int __convert_to_string(PathIterator &path,
11311101

11321102
while ((code = path.vertex(&x[0], &y[0])) != agg::path_cmd_stop) {
11331103
if (code == 0x4f) {
1134-
if ((p = __append_to_string(p, buffer, buffersize, codes[4])) == NULL) return 1;
1104+
buffer += codes[4];
11351105
} else if (code < 5) {
11361106
size = sizes[code - 1];
11371107

11381108
for (int i = 1; i < size; ++i) {
11391109
unsigned subcode = path.vertex(&x[i], &y[i]);
11401110
if (subcode != code) {
1141-
return 2;
1111+
return false;
11421112
}
11431113
}
11441114

@@ -1151,48 +1121,46 @@ int __convert_to_string(PathIterator &path,
11511121
}
11521122

11531123
if (!postfix) {
1154-
if ((p = __append_to_string(p, buffer, buffersize, codes[code - 1])) == NULL) return 1;
1155-
if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
1124+
buffer += codes[code - 1];
1125+
buffer += ' ';
11561126
}
11571127

11581128
for (int i = 0; i < size; ++i) {
1159-
if ((p = __add_number(x[i], format, precision, buffer, p, buffersize)) == NULL) return 1;
1160-
if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
1161-
if ((p = __add_number(y[i], format, precision, buffer, p, buffersize)) == NULL) return 1;
1162-
if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
1129+
__add_number(x[i], format_code, precision, buffer);
1130+
buffer += ' ';
1131+
__add_number(y[i], format_code, precision, buffer);
1132+
buffer += ' ';
11631133
}
11641134

11651135
if (postfix) {
1166-
if ((p = __append_to_string(p, buffer, buffersize, codes[code - 1])) == NULL) return 1;
1136+
buffer += codes[code - 1];
11671137
}
11681138

11691139
last_x = x[size - 1];
11701140
last_y = y[size - 1];
11711141
} else {
11721142
// Unknown code value
1173-
return 2;
1143+
return false;
11741144
}
11751145

1176-
if ((p = __append_to_string(p, buffer, buffersize, "\n")) == NULL) return 1;
1146+
buffer += '\n';
11771147
}
11781148

1179-
*buffersize = p - *buffer;
1180-
1181-
return 0;
1149+
return true;
11821150
}
11831151

11841152
template <class PathIterator>
1185-
int convert_to_string(PathIterator &path,
1186-
agg::trans_affine &trans,
1187-
agg::rect_d &clip_rect,
1188-
bool simplify,
1189-
SketchParams sketch_params,
1190-
int precision,
1191-
char **codes,
1192-
bool postfix,
1193-
char **buffer,
1194-
size_t *buffersize)
1153+
bool convert_to_string(PathIterator &path,
1154+
agg::trans_affine &trans,
1155+
agg::rect_d &clip_rect,
1156+
bool simplify,
1157+
SketchParams sketch_params,
1158+
int precision,
1159+
char **codes,
1160+
bool postfix,
1161+
std::string& buffer)
11951162
{
1163+
size_t buffersize;
11961164
typedef agg::conv_transform<py::PathIterator> transformed_path_t;
11971165
typedef PathNanRemover<transformed_path_t> nan_removal_t;
11981166
typedef PathClipper<nan_removal_t> clipped_t;
@@ -1207,26 +1175,23 @@ int convert_to_string(PathIterator &path,
12071175
clipped_t clipped(nan_removed, do_clip && !path.has_curves(), clip_rect);
12081176
simplify_t simplified(clipped, simplify, path.simplify_threshold());
12091177

1210-
*buffersize = path.total_vertices() * (precision + 5) * 4;
1211-
if (*buffersize == 0) {
1212-
return 0;
1178+
buffersize = path.total_vertices() * (precision + 5) * 4;
1179+
if (buffersize == 0) {
1180+
return true;
12131181
}
12141182

12151183
if (sketch_params.scale != 0.0) {
1216-
*buffersize *= 10;
1184+
buffersize *= 10;
12171185
}
12181186

1219-
*buffer = (char *)malloc(*buffersize);
1220-
if (*buffer == NULL) {
1221-
return 1;
1222-
}
1187+
buffer.reserve(buffersize);
12231188

12241189
if (sketch_params.scale == 0.0) {
1225-
return __convert_to_string(simplified, precision, codes, postfix, buffer, buffersize);
1190+
return __convert_to_string(simplified, precision, codes, postfix, buffer);
12261191
} else {
12271192
curve_t curve(simplified);
12281193
sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
1229-
return __convert_to_string(sketch, precision, codes, postfix, buffer, buffersize);
1194+
return __convert_to_string(sketch, precision, codes, postfix, buffer);
12301195
}
12311196

12321197
}

src/_path_wrapper.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -683,10 +683,8 @@ static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *
683683
PyObject *codesobj;
684684
char *codes[5];
685685
bool postfix;
686-
char *buffer = NULL;
687-
size_t buffersize;
688-
PyObject *result;
689-
int status;
686+
std::string buffer;
687+
bool status;
690688

691689
if (!PyArg_ParseTuple(args,
692690
"O&O&O&OO&iOO&:convert_to_string",
@@ -735,28 +733,14 @@ static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *
735733
CALL_CPP("convert_to_string",
736734
(status = convert_to_string(
737735
path, trans, cliprect, simplify, sketch,
738-
precision, codes, postfix, &buffer,
739-
&buffersize)));
740-
741-
if (status) {
742-
free(buffer);
743-
if (status == 1) {
744-
PyErr_SetString(PyExc_MemoryError, "Memory error");
745-
} else if (status == 2) {
746-
PyErr_SetString(PyExc_ValueError, "Malformed path codes");
747-
}
748-
return NULL;
749-
}
736+
precision, codes, postfix, buffer)));
750737

751-
if (buffersize == 0) {
752-
result = PyBytes_FromString("");
753-
} else {
754-
result = PyBytes_FromStringAndSize(buffer, buffersize);
738+
if (!status) {
739+
PyErr_SetString(PyExc_ValueError, "Malformed path codes");
740+
return NULL;
755741
}
756742

757-
free(buffer);
758-
759-
return result;
743+
return PyBytes_FromStringAndSize(buffer.c_str(), buffer.size());
760744
}
761745

762746

0 commit comments

Comments
 (0)