Гарантированно ли чтение свойства X11 типа UTF8_STRING заканчивается NULL?
У меня есть следующий код:
static Atom _NET_WM_NAME = XInternAtom( display, "_NET_WM_NAME", false );
unsigned char* wm_data = NULL;
Atom wm_type;
int wm_format;
unsigned long wm_nitems, wm_bytes;
std::string title;
int ret = XGetWindowProperty( display, window, _NET_WM_NAME, 0, 512,
false, utf8_string, &wm_type, &wm_format, &wm_nitems, &wm_bytes, &wm_data);
if( ret == Success && wm_nitems != 0 && wm_data != NULL ) {
title = (const char*)wm_data; // [1]
}
Недвижимость соответствует спецификации
Итак, в моем коде выше[1]
предполагает, что полученные данные всегда будут завершаться NULL. Код как есть работает, но возвращаемая сумма байтов () не включает терминатор NULL, она всегда совпадает с фактической длиной строки. Это то, что делает меня неуверенным.
Итак, мои вопросы:
- Гарантируется, что чтение
UTF8_STRING
Свойство всегда будет возвращать строку, ВКЛЮЧАЯ разделитель NULL? - Если да, то почему терминатор NULL не включен как часть
wm_nitems
считать? - Может кто-нибудь указать, где это указано в спецификации?
- И, в частности, является ли приведенный выше фрагмент правильным для чтения
_NET_WM_NAME
свойство?
1 ответ
«XGetWindowProperty() всегда выделяет один дополнительный байт в prop_return (даже если свойство имеет нулевую длину) и устанавливает его равным нулю, чтобы простые свойства, состоящие из символов, не нужно было копировать в еще одну строку перед использованием».
wm_nitems
nitems_return
: возвращает фактическое количество 8-битных, 16-битных или 32-битных элементов, хранящихся в данных prop_return.
Почему нулевой терминатор должен считаться данными. Это любезностьXGetWindowProperty
автоматически возвращать строку с завершающим нулем (см. выше), но символ не является частью фактических данных (например, абсолютно возможно установить имя окна без окончанияnul
символ).
Если выразиться иначе:strlen
завершающий нулевой символ также не считается, верно?
Другое дело, что строки C представляют собой массивы символов с нулевым завершением. Символ является нулевым указателем и имеет особое значение в среде C (см.: https://en.cppreference.com/w/c/types/NULL).
-
'\0'
имеет типchar
-
NULL
имеет типvoid*
(определяется реализацией, также может быть0
)