.TH MPU_FMEMOPEN 3 "Август 2026" "libmpuio" "Руководство программиста LIBMPUIO" .SH ИМЯ mpu_fmemopen, mpu_open_memstream \- потоки памяти UCS-2 .SH ОБЗОР .nf #include mpu_FILE *mpu_fmemopen( __mpu_char16_t *buffer, size_t size, const char *mode ); mpu_FILE *mpu_open_memstream( __mpu_char16_t **buffer, size_t *size ); .fi .SH ОПИСАНИЕ Эти интерфейсы предоставляют текстовые потоки на основе памяти, использующие нативное 16-битное представление LIBMPUIO .BR __mpu_char16_t . Они намеренно не являются побайтовыми копиями libc fmemopen/open_memstream: размеры измеряются в кодовых единицах UCS-2, а не в байтах. .PP .B mpu_fmemopen использует хранилище, принадлежащее вызывающей стороне. Аргумент .I size задаёт число доступных кодовых единиц .BR __mpu_char16_t , включая место для завершающего NUL при записи. Строгая грамматика режима r/w/a с необязательными + и b общая с .BR mpu_fopen (3). .PP Для r/r+ начальная логическая длина равна ограниченной длине строки UCS-2, уже находящейся в буфере. Для w/w+ логическая длина становится равной нулю, а первая кодовая единица устанавливается в NUL. Для a/a+ начальная позиция находится на завершающем NUL, а каждая последующая операция вывода добавляет данные в текущий логический конец, даже если успешный seek изменил текущую позицию. Успешные текстовые записи поддерживают NUL-терминацию, если это позволяет ёмкость. Если следующая кодовая единица вместе с завершающим NUL уже не помещается, вывод завершается с ENOSPC и устанавливает индикатор ошибки потока, не разрушая существующий завершающий NUL. .PP .B mpu_open_memstream создаёт динамически растущий выходной поток UCS-2, предназначенный только для записи. Библиотека выделяет и расширяет буфер данных. После .BR mpu_fflush (3) (включая форму для всех потоков mpu_fflush(NULL)) либо .BR mpu_fclose (3), .I *buffer указывает на текущий NUL-терминированный выделенный буфер, а .I *size содержит логическое число символов UCS-2 без завершающего NUL. После закрытия опубликованный буфер принадлежит вызывающей стороне и в конечном итоге должен быть освобождён через .BR free (3). .SH МОДЕЛЬ СИМВОЛОВ Обе функции создают текстовые потоки памяти UCS-2. Преобразование UTF-8 не выполняется, поскольку внешний байтовый файл отсутствует. Суррогатные кодовые единицы U+D800..U+DFFF остаются недопустимыми и отвергаются текстовыми операциями вывода с EILSEQ. .PP Сырые байтовые операции .B mpu_fread/mpu_fwrite для этих текстовых потоков памяти не определены. Используйте вместо них символьные, строковые, форматированные или сканирующие интерфейсы. .SH ПОЗИЦИОНИРОВАНИЕ Позиции потоков памяти измеряются в кодовых единицах .BR __mpu_char16_t . Фиксированный поток .B mpu_fmemopen может быть позиционирован в диапазоне от нуля до size-1; последующая запись за старым логическим концом заполняет промежуточные кодовые единицы NUL и увеличивает логическую длину. Позиционирование на size или дальше завершается с EINVAL, поскольку одна кодовая единица должна оставаться доступной для завершающего NUL. .PP Динамический .B mpu_open_memstream может быть позиционирован за текущий логический конец. Сам по себе seek не увеличивает опубликованный размер. Если затем по новой позиции выполняется запись, промежуток материализуется как кодовые единицы UCS-2 NUL, а логическая длина увеличивается до вновь записанного символа включительно. Позиционирование назад с перезаписью существующего содержимого не уменьшает логическую длину. .PP Нативные потоки памяти UCS-2 поддерживают то же активное состояние READING/WRITING, что и потоки на основе дескрипторов и cookie. Успешный seek сбрасывает EOF и отбрасывает pushback/состояние направления чтения-записи, согласованно с другими потоками LIBMPUIO. .BR mpu_fileno (3) для потоков памяти завершается с EBADF, поскольку у них нет POSIX-дескриптора. .SH ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ Обе функции при успехе возвращают указатель на поток, при ошибке \- NULL. .SH ОШИБКИ .B EINVAL используется для недопустимых указателей, хранилища вызывающей стороны нулевого размера, недопустимых режимов или операций, несовместимых с текстовым потоком памяти. .B ENOSPC означает, что фиксированный выходной буфер .B mpu_fmemopen не способен принять ещё один символ вместе с требуемым NUL. Ошибки выделения памяти из .B mpu_open_memstream сообщаются через обычное поведение errno аллокатора. .SH ПОТОКОБЕЗОПАСНОСТЬ Обычные операции над возвращённым потоком используют ту же рекурсивную блокировку потока, что и остальные потоки LIBMPUIO. Вызывающая сторона не должна напрямую изменять живой буфер mpu_fmemopen одновременно с потоковыми операциями. Для mpu_open_memstream опубликованные указатель/размер следует проверять только после явного flush или после закрытия. Пока поток жив, realloc может переместить буфер; актуальным является только указатель, опубликованный последним flush (или окончательным close). После закрытия этот последний выделенный буфер принадлежит вызывающей стороне и может быть освобождён через free(3). .SH ПРИМЕРЫ Фиксированный поток в памяти вызывающей стороны: .nf __mpu_char16_t storage[128]; mpu_FILE *fp = mpu_fmemopen( storage, 128, "w+" ); mpu_fprintf( fp, MPU_UCS2("value=%d"), 42 ); mpu_fflush( fp ); /* теперь storage содержит UCS-2 "value=42". */ .fi .PP Растущий поток: .nf __mpu_char16_t *text = NULL; size_t length = 0; mpu_FILE *fp = mpu_open_memstream( &text, &length ); mpu_fprintf( fp, MPU_UCS2("name=%s"), MPU_UCS2("mpu") ); mpu_fflush( fp ); /* text NUL-терминирован; length измеряется в элементах __mpu_char16_t. */ mpu_fclose( fp ); free( text ); .fi .SH СМ. ТАКЖЕ .BR libmpuio (3), .BR mpu_fopen (3), .BR mpu_fgetc (3), .BR mpu_printf (3), .BR mpu_scanf (3), .BR mpu_fseek (3)