OpenPrinting / libcups

OpenPrinting CUPS Library Sources
https://openprinting.github.io/cups/cups3.html
Apache License 2.0
35 stars 17 forks source link

Develop public IPP Data File API #14

Closed michaelrsweet closed 2 years ago

michaelrsweet commented 2 years ago

Currently ipptool and ippeveprinter use a private API to read ipptool test files and ippeveprinter attribute files. They share a common core syntax for specifying IPP attributes with a callback interface for processing tool-specific directives/commands and reporting errors. This same private API has been used in the PWG's ippsample project for ippserver and ipp3dprinter, but now that ippsample is using libcups it is inappropriate for them to use a private API. Also, the private API has been in use long enough to develop a stable public API, and there are other third-party tools and printer applications that could make use of the API as well.

The current private API:

typedef struct _ipp_file_s _ipp_file_t;/**** File Parser ****/
typedef struct _ipp_vars_s _ipp_vars_t;/**** Variables ****/

typedef int (*_ipp_fattr_cb_t)(_ipp_file_t *f, void *user_data, const char *attr);
                    /**** File Attribute (Filter) Callback ****/
typedef int (*_ipp_ferror_cb_t)(_ipp_file_t *f, void *user_data, const char *error);
                    /**** File Parser Error Callback ****/
typedef int (*_ipp_ftoken_cb_t)(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *token);
                    /**** File Parser Token Callback ****/

struct _ipp_vars_s          /**** Variables ****/
{
  char      *uri,           /* URI for printer */
        scheme[64],     /* Scheme from URI */
        username[256],      /* Username from URI */
        *password,      /* Password from URI (if any) */
        host[256],      /* Hostname from URI */
        portstr[32],        /* Port number string */
        resource[1024];     /* Resource path from URI */
  int       port;           /* Port number from URI */
  size_t    num_vars;       /* Number of variables */
  cups_option_t *vars;          /* Array of variables */
  int       password_tries;     /* Number of retries for password */
  _ipp_fattr_cb_t attrcb;       /* Attribute (filter) callback */
  _ipp_ferror_cb_t errorcb;     /* Error callback */
  _ipp_ftoken_cb_t tokencb;     /* Token callback */
};

struct _ipp_file_s          /**** File Parser */
{
  const char        *filename;  /* Filename */
  cups_file_t       *fp;        /* File pointer */
  int           linenum;    /* Current line number */
  ipp_t         *attrs;     /* Attributes */
  ipp_tag_t     group_tag;  /* Current group for new attributes */
};

extern ipp_t        *_ippFileParse(_ipp_vars_t *v, const char *filename, void *user_data);
extern int      _ippFileReadToken(_ipp_file_t *f, char *token, size_t tokensize);

extern void     _ippVarsDeinit(_ipp_vars_t *v);
extern void     _ippVarsExpand(_ipp_vars_t *v, char *dst, const char *src, size_t dstsize);
extern const char   *_ippVarsGet(_ipp_vars_t *v, const char *name);
extern void     _ippVarsInit(_ipp_vars_t *v, _ipp_fattr_cb_t attrcb, _ipp_ferror_cb_t errorcb, _ipp_ftoken_cb_t tokencb);
extern const char   *_ippVarsPasswordCB(const char *prompt, http_t *http, const char *method, const char *resource, void *user_data);
extern int      _ippVarsSet(_ipp_vars_t *v, const char *name, const char *value);
michaelrsweet commented 2 years ago

IPP Data File API

API to read and write IPP attributes and other commands or data using a common base format that supports tools such as ipptool and ippeveprinter.

Base Types

typedef struct _ipp_file_s ipp_file_t;

An open IPP tools file with associated variables and callbacks. The following standard variables are typically defined:

An IPP attribute filter callback. The "name" parameter is the name of an IPP attribute. The callback returns true to use the attribute and false otherwise. Typically this is used to filter out attributes that are generated by the application or that cannot be configured through the file (status, supported operations, etc.) The default NULL callback does no filtering.

typedef bool (*ipp_ferror_cb_t)(ipp_file_t *file, void *cb_data, const char *error);

An IPP error message callback. The "error" parameter contains an error message. The callback returns true to continue or false to stop. The default NULL callback writes the error message to stderr and returns true.

typedef bool (*ipp_ftoken_cb_t)(ipp_file_t *file, void *cb_data, const char *token);

An IPP token callback. The "token" parameter contains the token to be processed. The callback can use the ippFileReadToken function to read additional tokens from the file and the ippFileExpandToken function to expand any variables in the token string. Return false to stop reading the file and true to continue. The default NULL callback reports an unknown token error through the error callback end returns false.

Public API

ipp_file_t *
ippFileOpen(const char *filename, const char *mode, ipp_file_t *parent,
            ipp_fattr_cb_t attr_cb, ipp_ferror_cb_t error_cb,
            void *cb_data);

Open an IPP tools file for reading (mode = "r") or writing (mode = "w"). If an error occurs while opening the file, NULL is returned and the reason for the error can be found by calling the cupsLastErrorString function. If an error callback is specified, that function is also called with the error message.

The "parent" pointer causes the new file to contain the same variables as the parent and is typically used when processing the INCLUDE directive.

bool
ippFileClose(ipp_file_t *file);

Closes an IPP tools file, frees all memory used, and returns true on success or false on failure.

ipp_t *
ippFileGetAttributes(ipp_file_t *file);

Get the IPP attributes that have been read so far. You must call ippDelete or cupsDo*Request to free the resulting attributes.

const char *
ippFileGetFilename(ipp_file_t *file);

Gets the current filename.

int
ippFileGetLineNumber(ipp_file_t *file);

Gets the current line number in the file.

const char *
ippFileGetVar(ipp_file_t *file, const char *name);

void
ippFileSetVar(ipp_file_t *file, const char *name, const char *value);

Get and set file variables. Setting the "uri" variable also sets the "hostname", "port", "resource", "scheme", and "uriuser" variables.

bool
ippFileRead(ipp_file_t *file, ipp_ftoken_cb_t token_cb);

Reads the IPP tools file using the specified token callback.

bool
ippFileReadToken(ipp_file_t *file, char *buffer, size_t bufsize);

Reads a single token from the file, returning false on end-of-file.

bool
ippFileWrite(ipp_file_t *file, ipp_t *ipp);

Writes the attributes in "ipp" to the file. Returns false on error or true on success.

bool
ippFileWriteToken(ipp_file_t *file, const char *token);

bool
ippFileWriteTokenf(ipp_file_t *file, const char *token, ...);

Write a single token to the file. The second form allows for printf-style format strings.