if (nxt_fast_path(p != NULL)) {
memcpy(p, start, size);
-
- if (size != length && length >= NJS_STRING_MAP_STRIDE) {
- njs_string_offset_map_init(p, size);
- }
-
return NXT_OK;
}
njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size,
uint32_t length)
{
- uint32_t total;
+ uint32_t total, map_offset, *map;
njs_string_t *string;
value->type = NJS_STRING;
value->data.string_size = size;
if (size != length && length > NJS_STRING_MAP_STRIDE) {
- total = njs_string_map_offset(size) + njs_string_map_size(length);
+ map_offset = njs_string_map_offset(size);
+ total = map_offset + njs_string_map_size(length);
} else {
+ map_offset = 0;
total = size;
}
string->length = length;
string->retain = 1;
+ if (map_offset != 0) {
+ map = (uint32_t *) (string->start + map_offset);
+ map[0] = 0;
+ }
+
return string->start;
}
/*
* njs_string_validate() validates an UTF-8 string, evaluates its length,
- * sets njs_string_prop_t struct, and initializes offset map if it is required.
+ * sets njs_string_prop_t struct.
*/
nxt_noinline njs_ret_t
njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value)
{
- u_char *start;
- size_t new_size;
- ssize_t size, length;
+ u_char *start;
+ size_t new_size, map_offset;
+ ssize_t size, length;
+ uint32_t *map;
size = value->short_string.size;
* Reallocate the long string with offset map
* after the string.
*/
- new_size = njs_string_map_offset(size)
- + njs_string_map_size(length);
+ map_offset = njs_string_map_offset(size);
+ new_size = map_offset + njs_string_map_size(length);
start = nxt_mem_cache_alloc(vm->mem_cache_pool, new_size);
if (nxt_slow_path(start == NULL)) {
string->start = start;
value->data.u.string->start = start;
- njs_string_offset_map_init(start, size);
+ map = (uint32_t *) (start + map_offset);
+ map[0] = 0;
}
}
p += string.size;
}
- if (length >= NJS_STRING_MAP_STRIDE && size != length) {
- njs_string_offset_map_init(start, size);
- }
-
return NXT_OK;
}
for (p = string.start; p < end; p++) {
s = nxt_utf8_encode(s, *p);
}
-
- if (slice.length >= NJS_STRING_MAP_STRIDE || size != slice.length) {
- njs_string_offset_map_init(start, size);
- }
}
return NXT_OK;
/*
- * njs_string_offset() assumes that index is correct
- * and the optional offset map has been initialized.
+ * njs_string_offset() assumes that index is correct.
*/
nxt_noinline const u_char *
if (index >= NJS_STRING_MAP_STRIDE) {
map = njs_string_map_start(end);
+ if (map[0] == 0) {
+ njs_string_offset_map_init(start, end - start);
+ }
+
start += map[index / NJS_STRING_MAP_STRIDE - 1];
}
/*
- * njs_string_index() assumes that offset is correct
- * and the optional offset map has been initialized.
+ * njs_string_index() assumes that offset is correct.
*/
nxt_noinline uint32_t
end = string->start + string->size;
map = njs_string_map_start(end);
+ if (map[0] == 0) {
+ njs_string_offset_map_init(string->start, string->size);
+ }
+
while (index + NJS_STRING_MAP_STRIDE < string->length
&& *map <= offset)
{
p = nxt_utf8_encode(p, nxt_utf8_lower_case(&s, end));
size--;
}
-
- if (string.length >= NJS_STRING_MAP_STRIDE) {
- njs_string_offset_map_init(start, string.size);
- }
}
return NXT_OK;
p = nxt_utf8_encode(p, nxt_utf8_upper_case(&s, end));
size--;
}
-
- if (string.length >= NJS_STRING_MAP_STRIDE) {
- njs_string_offset_map_init(start, string.size);
- }
}
return NXT_OK;
n--;
}
- if (length >= NJS_STRING_MAP_STRIDE && size != length) {
- njs_string_offset_map_init(start, size);
- }
-
return NXT_OK;
}
/* GC: release valid values. */
}
- if (length >= NJS_STRING_MAP_STRIDE && size != length) {
- njs_string_offset_map_init(string, size);
- }
-
nxt_array_destroy(&r->parts, &njs_array_mem_proto, vm->mem_cache_pool);
return NXT_OK;