ppsparse()
Parse an object read from PPS
Synopsis:
#include <ppsparse.h> extern pps_status_t ppsparse( char **ppsdata, const char * const *objnames, const char * const *attrnames, pps_attrib_t *info, int parse_flags );
Arguments:
-
ppsdata
- A pointer to a pointer to the current position in the buffer of PPS data. The function updates this pointer as it parses the options; see the “Description” below. objnames
- A pointer to a NULL-terminated array of object names. If this value is not NULL, ppsparse() looks up any object name it finds and provides its index in the pps_attrib_t structure. attrnames
- A pointer to a NULL-terminated array of attribute names. If this value is not NULL, ppsparse() looks up any attribute name it finds and provides its index in the pps_attrib_t structure. info
- A pointer to the data structure pps_attrib_t, which carries detailed about a line of PPS data. parse_flags
- Reserved for future use.
Library:
libc.
Description:
The function ppsparse() parses the next line of a buffer of PPS data. This buffer must be terminated by a null (“\0” in C, or hexadecimal0x00).
The first time you call this function after reading PPS data, you should set ppsdata to reference the start of the buffer with the data. As it parses each line of data,ppsparse():
- places the information parsed from the buffer in the pps_attrib_t data structure
- updates the pointer to the next PPS line in the buffer
When it successfully completes parsing a line, ppsparse() returns the type of line parsed, or end of data; seepps_status_t below.
pps_attrib_t
typedef struct { char *obj_name; int obj_index; char *attr_name; int attr_index; char *encoding; char *value; int flags; int options; int option_mask; int quality; char *line; int reserved[3]; } pps_attrib_t;
The pps_attrib_t data structure carries parsed PPS object and attribute information. It includes the members described in the table below:
Member | Type | Description |
---|---|---|
obj_name | char | A pointer to the name of the last PPS object encountered. ppsparse() sets this pointer only if it encounters a PPS object name. You should initialize this pointer before calling ppsparse(). |
obj_index | int | The index for obj_name in the objnames array. It is set to -1 if the index is not found orobjnames is NULL. You should initialize this value before callingppsparse(). |
attr_name | char | A pointer to the name of the attribute from the line PPS data that ppsparse() just parsed. It is set toNULL if no attribute name was found. |
attr_index | int | The index for attrj_name in the attrnames array. It is set to -1 if the index is not found orattrnames is NULL. |
encoding | char | A pointer to a string that indicates the encoding used for the PPS attribute. See“Attributes” in the chapter PPS Objects and Attributes. This value is only relevant if the ppsparse() return value isPPS_ATTRIBUTE. See pps_status_t below. |
value | char | A pointer to the value of a PPS attribute. This value is only relevant if the ppsparse() return value isPPS_ATTRIBUTE. See pps_status_t below. |
flags | int | Flags indicating that parsing has found a PPS special character prefixed to a line, or that the line is incomplete. Seepps_attrib_flags_t below. |
options | int | Indicates which non-negated options are prefixed in square brackets to a line. See“Object and attribute options” in the chapter Options. |
option_mask | int | A mask of the options (both negated and non-negated) prefixed to a line. See pps_options_t below. |
quality | int | Not used. |
line | char | Pointer to the beginning of the line parsed by ppsparse(), for use in case of a parsing error. |
reserved[3] | int | For internal use. |
pps_attrib_flags_t
The enumerated values PPS_* defined by pps_attrib_flags_t define the possible states for PPS objects and attributes. These states include:
- PPS_INCOMPLETE — the object or attribute line is incomplete
- PPS_DELETED — the object or attribute has been deleted
- PPS_CREATED — the object has been created
- PPS_TRUNCATED — the object or attribute has been truncated
- PPS_PURGED — a critical publisher has closed its connection and all non-persistent attributes have been deleted; see“Critical option” in the chapter Options.
See also “Change notification” in the chapter PPS Objects.
pps_options_t
The enumerated values PPS_NOPERSIST defined by pps_options_t define values for PPS options:
- PPS_NOPERSIST — no-persistence option
- PPS_ITEM — item option
pps_status_t
The enumerated values PPS_* defined by pps_status_t define the possible ppsparse() return values. These values include:
- PPS_ERROR — the line of PPS data is invalid
- PPS_END — end of data, or incomplete line
- PPS_OBJECT — data for the given object follows
- PPS_OBJECT_CREATED — an object has been created
- PPS_OBJECT_DELETED — an object has been deleted
- PPS_OBJECT_TRUNCATED — an object has been truncated (all attributes were removed)
- PPS_ATTRIBUTE — and attribute has been updated
- PPS_ATTRIBUTE_DELETED — an attribute has been deleted
Returns:
The ppsparse() function returns:
-
≥0
- Success. -1
-
An error occured (errno is set).
#ifdef PPSPARSE_TEST
#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
};
static const char *const attrs[] ={
[ATTR_AUTHOR] = "author",
[ATTR_TITLE] = "title",
[ATTR_TIME] = "time",
[LAST_ATTR] = NULL
};
enum {
OBJECT_BOOK,
OBJECT_FILM,
OBJECT_SONG,
LAST_OBJECT
};
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;
}
#endif
参考: http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_pps%2Fpps.html