IPP>PRO: sorry, but binary is better

IPP>PRO: sorry, but binary is better

IPP>PRO: sorry, but binary is better

Robert Herriot Robert.Herriot at Eng.Sun.COM
Fri Jun 20 17:38:54 EDT 1997

You raise an important issue about a buffer that may contain only a
partial parameter (attribute) but I come to a very different conclusion
as I explain below.  I think that the 'name ":" value CRLF' may again
be the simplest solution from an implementation stand point, even
though we keep rejecting it.  The reason lies with the way the buffers
align with parameters (attributes).

This buffer problem exists for both the current IPP proposal and for
the previous binary proposal that you prefer.  The two byte binary
integer could span buffers and a parameter name or value buffer could
span buffers. Similar spans could occur with the current IPP protocol
proposal. The code to deal with processing an attribute that spans two
buffers seems rather messy to me because the break can occur during any
element. It sees like a good place to generate lots of occasional bugs.

You observed that with the two-byte lengths in the binary proposal,
it is easy to determine if the buffer ends in the middle of the string.
It is also easy in the current proposal to get the same information by
putting a " " (space character) just after the last character in the
buffer to stop the scan-for-space algorithm.

You also observed that with CRLF and a maximum line length, it is easy 
to ensure that a buffer has a full unit because functions, such as fgets
read upto the next CRLF. Perhaps we need to revisit the solution that
uses CRLF, namely the one where each parameter has the syntax

   name ":" value CRLF .

The syntax for such a solution would be

    parameter = single-value / set-of / continued-value
    single-value = parameter-name ":" value CRLF
    set-of = parameter-name 2*( ":" value CRLF)
    continued-value = " " value CRLF

from a raw level the syntax for a parameter is:

    parameter = 1*998 BYTE CRLF
    BYTE = %x00..%x09 / %x0B / %x0C / %x0E..%xFF  ; any value except CR or LF

    CR in a value is represented by =0C
    LF in a value is represented by =0A
    =  in a value is represented by =3D

The following is the GrabAttr function is designed along the lines of your
function except that it returns the type of the parameter (attribute).
It assumes that the buffer holds at least 1000 bytes and ends with a
"CRLF" so there are no partial parameter issues to deal with in the
GrabATTR function. I am assuming that the caller of GrabAttr copies the
strings referenced by pAttr and for the value it translates an =xx to
the actual character.  I am also assuming that it used the value
returned (attrType) to determine how to use the attribute just read.

int GrabAttr(ATTR *pAttr)
  char * pNext;
  int length;
  int attrType;
  switch (*pBuf) { 
     case ' ':  /* contination line /*
        attrType = CONTINUED_VALUE;
     case ':':  / another member of a set */ 
        attrType = SET_OF;
        attrType = SINGLE_VALUE;
        pNext = strchr(pBuf,':');
        pAttr->nNameLength = pNext-pBuf;  /* this works now */
        pAttr->pName = pBuf;
        pBuf = pNext + 1;
  pNext = strchr(pBuf,'\r');
  pAttr->nValLen = pNext-pBuf;  /* this works now */
  pAttr->pVal = pBuf;
  pBuf = pNext + 2;             /* skip CRLF */
  return attrType;

Perhaps this pure textual solution is easier to program once you consider
the buffer problem.


Bob Herriot

> From SBUTLER at hpbs2024.boi.hp.com Fri Jun 20 08:51:08 1997
> Bob Herriot wrote:
> >binary protocol. Also, my ANSI C book states that atoi assumes decimal, but
> >recommends using strtol as I have done below. 
> Ahh, yes.  How did I miss that...
> >int GrabAttr(ATTR *pAttr)
> >{
> >  char * pNext; 
> >  int length; 
> >   
> >  pNext = strchr(pBuf,' '); 
> Probably safe given my initial assumption that the buffer would hold 
> the entire name...  But hard for the upper layer to validate.
> >  pAttr->nNameLength = pNext-pBuf;
> >  pAttr->pName = pBuf
> >  pBuf = pNext + 1;
> >   
> >  length = strtol(pBuf,&pNext,10);  /* ANSI C function */
> Doh!  Hardcoding the base.  I missed that one.
> Again, we have the potentially hard to verify issue of searching 
> forward.
> >  pAttr->nValLen = length; 
> >  pNext++; 
> >  pAttr->pVal = pNext;
> >  pBuf = pNext + length;
> >  return ERROR_OK 
> >}
> Looks good, better than I expected.
> I am concerned with how the upper layer can validate the assumption 
> that the delimiters will be in the buffer for this lower layer.  A 
> "pure" text (with max line lengths defined, CRLF endings, etc) can 
> read until it gets the entire line (or declare an error when the 
> line is found to be too long) and know it has the whole thing.  With 
> unknown line lengths it is risky to assume that without verification.
> With the binary lengths the GrabAttr doesn't loop searching for 
> anything and the layer above can compare lengths with the len of data 
> in the buffer to verify that all is well.
> >would expect than an implementation might have a keywordToInt function
> >which would map keywords to integers that in turn could be used in
> Of course, but remind me again, what does an implementation gain by 
> having such a function as opposed to just communicating in binary?
> >> From SBUTLER at hpbs2024.boi.hp.com Thu Jun 19 18:06:36 1997
>  ...
> >> What do we get with ASCII?  My list of "pros"
> >> from the meeting is really short.  The biggest I've been able to
> >> identify is vendor extensibility.
> [proposal, examples, etc. deleted]
> sdb
>  | Sylvan Butler | sbutler at boi.hp.com | AreaCode 208 Phone/TelNet 396-2282 |

More information about the Ipp mailing list