Операционная система ЗОСРВ «Нейтрино» > Руководство разработчика > Интерфейсы различных подсистем > Устойчивая служба публикации/подписки (PPS) > API > ppsparse()



ppsparse()

Анализ объекта, считанного из PPS

Прототип:

#include <sys/pps.h>
pps_status_t ppsparse( char **ppsdata,
const char * const *objnames,
const char * const *attrnames,
pps_attrib_t *info,
int parse_flags );

Аргументы:

ppsdata
Указатель на указатель текущей позиции в буфере данных PPS. Функция обновляет этот указатель по мере разбора опций.
objnames
Указатель на NULL-терминированный массив имен объектов. Если значение не равно NULL, ppsparse() выполняет поиск объекта по указанному имени и возвращает его индекс в структуре pps_attrib_t.
attrnames
Указатель на NULL-терминированный массив имен атрибутов. Если значение не равно NULL, ppsparse() выполняет поиск атрибута по указанному имени и возвращает его индекс в структуре pps_attrib_t.
info
Указатель на структуру pps_attrib_t, которая содержит подробную информацию о строке данных.
parse_flags
В настоящий момент не используется.

Библиотека:

libpps

Описание:

Функция ppsparse() выполняет анализ следующей строки из буфера данных PPS. Этот буфер должен быть NUL-терминированным ("\0" в языке C или 0x00 в шестнадцатеричном представлении).

При первом вызове после чтения данных следует установить ppsdata на начало буфера с данными. Поскольку анализируется каждая строка данных, функция ppsparse() выполняет:

При успешном завершении анализа строки, функция ppsparse() также возвращает статус pps_status_t.

Возвращаемое значение:

≥0
Успешное завершение, статус определяется типом pps_status_t.
PPS_ERROR
Возникла ошибка, статус определяется типом pps_status_t.

Примеры:

Следующее приложение демонстрирует использование функции ppsparse():

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* Test data to use if a file name is not provided as a command line argument.
* This data may be read-only in code space, so we copy it. */
char *testdata = "@book\n"
"title::Money money1\n"
"author:c:Money money2\n"
"[n]title::Nopersist option\n"
"[-n]title::Negated option\n"
"[-xnp]time:c:Unknown options\n"
"badattr:Improperly formatted\n"
"[n]@song\n"
"title::Money money4\n"
"Just some garbage\n"
"[n]+newAttr:abc:New attribute\n" /* New attribute (not currently used by pps) */
"+newAttr\n" /* New attribute, missing encoding etc */
"-deleteAttr::\n" /* Deleted attribute with encoding etc */
"-deleteAttr\n" /* Deleted attribute without encoding etc */
"-@unidentified\n" /* Deleted object */
"#@unidentified\n" /* Truncated object */
"[i]flags::flg1,\n" /* Item flag */
"[-i]flags::flg1,\n" /* Negated item flag */
"[7n]quality::qualityAttribute\n" /* Attribute with quality setting */
"Incomplete line";
int main( int argc, char *argv[] )
{
enum { ATTR_AUTHOR,
ATTR_TITLE,
ATTR_TIME,
LAST_ATTR };
enum { OBJECT_BOOK,
OBJECT_FILM,
OBJECT_SONG,
LAST_OBJECT };
static const char *const attrs[] = { [ATTR_AUTHOR] = "author",
[ATTR_TITLE] = "title",
[ATTR_TIME] = "time",
[LAST_ATTR] = NULL };
static const char *const objs[] = { [OBJECT_BOOK] = "@book",
[OBJECT_FILM] = "@film",
[OBJECT_SONG] = "@song",
[LAST_OBJECT] = NULL };
char buffer[1024];
char *ppsdata = buffer;
int fd = -1;
pps_attrib_t info;
pps_status_t rc;
int lineno = 0;
if ( argc > 1 ) {
fd = open( argv[1], O_RDONLY );
if ( fd < 0 ) {
perror( argv[1] );
exit( 1 );
}
} else
strcpy( buffer, testdata );
memset( &info, 0, sizeof( info ) );
while ( ppsdata != NULL ) {
if ( fd >= 0 ) {
int n = read( fd, ppsdata, sizeof( buffer) - (ppsdata - buffer) - 1 );
if ( n <= 0 )
exit( 0 );
ppsdata[n] = '\0';
ppsdata = buffer;
}
while ( rc = ppsparse( &ppsdata, objs, attrs, &info, 0 ) ) {
printf( "%d ---------------------------\n%s ", ++lineno,
rc == PPS_ERROR ? "PPS_ERROR" :
rc == PPS_END ? "PPS_END" :
rc == PPS_OBJECT ? "PPS_OBJECT" :
rc == PPS_OBJECT_CREATED ? "PPS_OBJECT_CREATED" :
rc == PPS_OBJECT_DELETED ? "PPS_OBJECT_DELETED" :
rc == PPS_OBJECT_TRUNCATED ? "PPS_OBJECT_TRUNCATED" :
rc == PPS_ATTRIBUTE ? "PPS_ATTRIBUTE" :
rc == PPS_ATTRIBUTE_DELETED ? "PPS_ATTRIBUTE_DELETED" : "?" );
if ( info.flags ) {
printf( "flags:%s%s%s%s%s ", info.flags & PPS_INCOMPLETE ? "inc" : "",
info.flags & PPS_CREATED ? "+" : "",
info.flags & PPS_DELETED ? "-" : "",
info.flags & PPS_TRUNCATED ? "#" : "",
info.flags & PPS_PURGED ? "*" : "" );
}
if ( info.options || info.option_mask ) {
printf( "options:%s%s mask:%s%s ", info.options & PPS_NOPERSIST ? "n" : "",
info.options & PPS_ITEM ? "i" : "",
info.option_mask & PPS_NOPERSIST ? "n" : "",
info.option_mask & PPS_ITEM ? "i" : "" );
}
printf( "object:%s (%d) ",info.obj_name ? info.obj_name : "NULL", info.obj_index );
if ( rc == PPS_ATTRIBUTE || rc == PPS_OBJECT_DELETED ) {
printf( "attr:%s (%d) ", info.attr_name ? info.attr_name : "NULL",
info.attr_index );
if ( rc == PPS_ATTRIBUTE )
printf( "quality:%d encoding:%s value:%s", info.quality,
info.encoding, info.value );
}
printf( "\n" );
/* now put everything back so we can print out the line. */
if ( info.encoding )
info.encoding[-1] = ':';
if ( info.value )
info.value[-1] = ':';
printf( "%s\n", info.line );
}
if ( fd >= 0 ) {
/* Note: When reading directly from PPS, you don't need to deal with the PPS_INCOMPLETE
* flag. It is needed only to allow parsing of PPS data where the data is not provided
* in complete lines. In this case, the partial line is moved to the beginning of the
* buffer, more data is read and the parsing is attempted again. */
if ( info.flags & PPS_INCOMPLETE ) {
memmove( buffer, info.line, ppsdata - info.line );
ppsdata = buffer + (ppsdata - info.line);
} else
ppsdata = buffer;
} else
ppsdata = NULL;
}
return (0);
}

Классификация:

ЗОСРВ «Нейтрино»

Безопасность использования
Точка остановки потока
Нет
Обработчик прерываний
Да
Обработчик сигналов
Да
В потоке
Да

Предостережения:

При анализе разделители ":" и "\n" во входной строке могут быть заменены на символ NUL.

Тематические ссылки:

pps_attrib_t, pps_attrib_flags_t, pps_options_t, pps_status_t




Предыдущий раздел: Устойчивая служба публикации/подписки (PPS)