FreeBSD/contrib/subversion/subversion/libsvn_ra_svn/marshal.c
/* Given the first non-whitespace character FIRST_CHAR, read an item
 * into the already allocated structure ITEM.  LEVEL should be set
 * to 0 for the first call and is used to enforce a recursion limit
 * on the parser. */
Given the first non-whitespace character FIRST_CHAR, read an item
into the already allocated structure ITEM.  LEVEL should be set
to 0 for the first call and is used to enforce a recursion limit
on the parser.
Given the first non - whitespace character FIRST_CHAR read an item into the already allocated structure ITEM . LEVEL should be set to 0 for the first call and is used to enforce a recursion limit on the parser .
static svn_error_t *read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                              svn_ra_svn_item_t *item, char first_char,
                              int level)
{
  char c = first_char;
  apr_uint64_t val;
  svn_ra_svn_item_t *listitem;
  if (++level >= ITEM_NESTING_LIMIT)
    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                            _("Items are nested too deeply"));
  if (svn_ctype_isdigit(c))
    {
      val = c - '0';
      while (1)
        {
          apr_uint64_t prev_val = val;
          SVN_ERR(readbuf_getchar(conn, pool, &c));
          if (!svn_ctype_isdigit(c))
            break;
          val = val * 10 + (c - '0');
          if ((prev_val >= (APR_UINT64_MAX / 10))
              && (val < APR_UINT64_MAX - 10))
            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                    _("Number is larger than maximum"));
        }
      if (c == ':')
        {
          SVN_ERR(read_string(conn, pool, item, val));
          SVN_ERR(readbuf_getchar(conn, pool, &c));
        }
      else
        {
          item->kind = SVN_RA_SVN_NUMBER;
          item->u.number = val;
        }
    }
  else if (svn_ctype_isalpha(c))
    {
      char *buffer = apr_palloc(pool, MAX_WORD_LENGTH + 1);
      char *end = buffer + MAX_WORD_LENGTH;
      char *p = buffer + 1;
      buffer[0] = c;
      while (1)
        {
          SVN_ERR(readbuf_getchar(conn, pool, p));
          if (!svn_ctype_isalnum(*p) && *p != '-')
            break;
          if (++p == end)
            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                    _("Word is too long"));
        }
      c = *p;
      *p = '\0';
      item->kind = SVN_RA_SVN_WORD;
      item->u.word = buffer;
    }
  else if (c == '(')
    {
      item->kind = SVN_RA_SVN_LIST;
      item->u.list = apr_array_make(pool, 4, sizeof(svn_ra_svn_item_t));
      while (1)
        {
          SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
          if (c == ')')
            break;
          listitem = apr_array_push(item->u.list);
          SVN_ERR(read_item(conn, pool, listitem, c, level));
        }
      SVN_ERR(readbuf_getchar(conn, pool, &c));
    }
  if (!svn_iswhitespace(c))
    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                            _("Malformed network data"));
  return SVN_NO_ERROR;
}
static svn_error_t * read_item ( svn_ra_svn_conn_t * conn , apr_pool_t * pool , svn_ra_svn_item_t * item , char first_char , int level ) { char c = first_char ; apr_uint64_t val ; svn_ra_svn_item_t * listitem ; if ( ++ level >= ITEM_NESTING_LIMIT ) return svn_error_create ( SVN_ERR_RA_SVN_MALFORMED_DATA , NULL , _ ( " " ) ) ; if ( svn_ctype_isdigit ( c ) ) { val = c - ' ' ; while ( 1 ) { apr_uint64_t prev_val = val ; SVN_ERR ( readbuf_getchar ( conn , pool , & c ) ) ; if ( ! svn_ctype_isdigit ( c ) ) break ; val = val * 10 + ( c - ' ' ) ; if ( ( prev_val >= ( APR_UINT64_MAX / 10 ) ) && ( val < APR_UINT64_MAX - 10 ) ) return svn_error_create ( SVN_ERR_RA_SVN_MALFORMED_DATA , NULL , _ ( " " ) ) ; } if ( c == ' ' ) { SVN_ERR ( read_string ( conn , pool , item , val ) ) ; SVN_ERR ( readbuf_getchar ( conn , pool , & c ) ) ; } else { item -> kind = SVN_RA_SVN_NUMBER ; item -> u . number = val ; } } else if ( svn_ctype_isalpha ( c ) ) { char * buffer = apr_palloc ( pool , MAX_WORD_LENGTH + 1 ) ; char * end = buffer + MAX_WORD_LENGTH ; char * p = buffer + 1 ; buffer [ 0 ] = c ; while ( 1 ) { SVN_ERR ( readbuf_getchar ( conn , pool , p ) ) ; if ( ! svn_ctype_isalnum ( * p ) && * p != ' ' ) break ; if ( ++ p == end ) return svn_error_create ( SVN_ERR_RA_SVN_MALFORMED_DATA , NULL , _ ( " " ) ) ; } c = * p ; * p = ' \0 ' ; item -> kind = SVN_RA_SVN_WORD ; item -> u . word = buffer ; } else if ( c == ' ' ) { item -> kind = SVN_RA_SVN_LIST ; item -> u . list = apr_array_make ( pool , 4 , sizeof ( svn_ra_svn_item_t ) ) ; while ( 1 ) { SVN_ERR ( readbuf_getchar_skip_whitespace ( conn , pool , & c ) ) ; if ( c == ' ' ) break ; listitem = apr_array_push ( item -> u . list ) ; SVN_ERR ( read_item ( conn , pool , listitem , c , level ) ) ; } SVN_ERR ( readbuf_getchar ( conn , pool , & c ) ) ; } if ( ! svn_iswhitespace ( c ) ) return svn_error_create ( SVN_ERR_RA_SVN_MALFORMED_DATA , NULL , _ ( " " ) ) ; return SVN_NO_ERROR ; }
Given the first non-whitespace character FIRST_CHAR, read an item
 into the already allocated structure ITEM.
Given the first non - whitespace character FIRST_CHAR read an item into the already allocated structure ITEM .
/* Determine the item type and read it in.  Make sure that c is the
   * first character at the end of the item so we can test to make
   * sure it's whitespace. */ /* It's a number or a string.  Read the number part, either way. */ /* val wrapped past maximum value? */ /* It's a string. */ /* It's a number. */ /* It's a word.  Read it into a buffer of limited size. */ /* Read in the list items. */