Анализ объекта, считанного из 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 );
NULL
-терминированный массив имен объектов. Если значение не равно NULL
, ppsparse() выполняет поиск объекта по указанному имени и возвращает его индекс в структуре pps_attrib_t.NULL
-терминированный массив имен атрибутов. Если значение не равно NULL
, ppsparse() выполняет поиск атрибута по указанному имени и возвращает его индекс в структуре pps_attrib_t.libpps
Функция ppsparse() выполняет анализ следующей строки из буфера данных PPS. Этот буфер должен быть NUL
-терминированным ("\0" в языке C или 0x00
в шестнадцатеричном представлении).
При первом вызове после чтения данных следует установить ppsdata на начало буфера с данными. Поскольку анализируется каждая строка данных, функция ppsparse() выполняет:
При успешном завершении анализа строки, функция ppsparse() также возвращает статус 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 );}} elsestrcpy( 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);} elseppsdata = buffer;} elseppsdata = NULL;}return (0);}
ЗОСРВ «Нейтрино»
При анализе разделители ":" и "\n" во входной строке могут быть заменены на символ NUL
.
pps_attrib_t, pps_attrib_flags_t, pps_options_t, pps_status_t
Предыдущий раздел: Устойчивая служба публикации/подписки (PPS)