#include <zend.h>
#include "zend_smart_str.h"
+#include "zend_smart_string.h"
#define SMART_STR_OVERHEAD (ZEND_MM_OVERHEAD + _ZSTR_HEADER_SIZE)
va_end(arg);
}
+#define SMART_STRING_START_SIZE 255
+#define SMART_STRING_PREALLOC 128
+#define SMART_STRING_PAGE 4096
+
+ZEND_API void ZEND_FASTCALL _smart_string_alloc_persistent(smart_string *str, size_t len)
+{
+ if (!str->c) {
+ str->len = 0;
+ str->a = len <= SMART_STRING_START_SIZE
+ ? SMART_STRING_START_SIZE
+ : (ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_PREALLOC, SMART_STRING_PAGE) - 1);
+ str->c = malloc(str->a + 1);
+ } else {
+ if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) {
+ zend_error(E_ERROR, "String size overflow");
+ }
+ len += str->len;
+ str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_PREALLOC, SMART_STRING_PAGE) - 1;
+ str->c = realloc(str->c, str->a + 1);
+ }
+}
+
+ZEND_API void ZEND_FASTCALL _smart_string_alloc(smart_string *str, size_t len)
+{
+ if (!str->c) {
+ str->len = 0;
+ str->a = len <= SMART_STRING_START_SIZE
+ ? SMART_STRING_START_SIZE
+ : (ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_PREALLOC, SMART_STRING_PAGE) - 1);
+ str->c = emalloc(str->a + 1);
+ } else {
+ if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) {
+ zend_error(E_ERROR, "String size overflow");
+ }
+ len += str->len;
+ str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_PREALLOC, SMART_STRING_PAGE) - 1;
+ str->c = erealloc(str->c, str->a + 1);
+ }
+}
+
/*
* Local variables:
* tab-width: 4
#include "zend_smart_string_public.h"
#include <stdlib.h>
-#ifndef SMART_STR_USE_REALLOC
#include <zend.h>
-#endif
-
-#ifndef SMART_STRING_PREALLOC
-#define SMART_STRING_PREALLOC 128
-#endif
-
-#ifndef SMART_STRING_START_SIZE
-#define SMART_STRING_START_SIZE 78
-#endif
-
-#ifdef SMART_STRING_USE_REALLOC
-#define SMART_STRING_REALLOC(a,b,c) realloc((a),(b))
-#else
-#define SMART_STRING_REALLOC(a,b,c) perealloc((a),(b),(c))
-#endif
-
-#define SMART_STRING_DO_REALLOC(d, what) \
- (d)->c = (char *) SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what))
/* wrapper */
#define smart_string_append_unsigned(str, val) \
smart_string_append_unsigned_ex((str), (val), 0)
+ZEND_API void ZEND_FASTCALL _smart_string_alloc_persistent(smart_string *str, size_t len);
+ZEND_API void ZEND_FASTCALL _smart_string_alloc(smart_string *str, size_t len);
+
static zend_always_inline size_t smart_string_alloc(smart_string *str, size_t len, zend_bool persistent) {
- if (!str->c) {
- str->len = 0;
- str->a = len < SMART_STRING_START_SIZE
- ? SMART_STRING_START_SIZE
- : len + SMART_STRING_PREALLOC;
- SMART_STRING_DO_REALLOC(str, persistent);
- return len;
- } else {
- if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) {
- zend_error(E_ERROR, "String size overflow");
- }
- len += str->len;
- if (UNEXPECTED(len >= str->a)) {
- str->a = len + SMART_STRING_PREALLOC;
- SMART_STRING_DO_REALLOC(str, persistent);
+ if (UNEXPECTED(!str->c) || UNEXPECTED(len >= str->a - str->len)) {
+ if (persistent) {
+ _smart_string_alloc_persistent(str, len);
+ } else {
+ _smart_string_alloc(str, len);
}
}
- return len;
+ return str->len + len;
}
static zend_always_inline void smart_string_free_ex(smart_string *str, zend_bool persistent) {