### ----------------------------------------------------
### -- URI::Template
### -- Licenses: Artistic-2.0
### -- Authors: Jonathan Stowe <jns+git@gellyfish.co.uk>
### -- File: doc/rfc6570.txt
### ----------------------------------------------------
### -- Chunk 3 of 3
 algorithm that has only minor variations
   in process per operator.  This non-normative appendix describes one
   such algorithm.

   Initialize an empty result string and its non-error state.

   Scan the template and copy literals to the result string (as in
   Section 3.1) until an expression is indicated by a "{", an error is
   indicated by the presence of a non-literals character other than "{",
   or the template ends.  When it ends, return the result string and its
   current error or non-error state.

   o  If an expression is found, scan the template to the next "}" and
      extract the characters in between the braces.

   o  If the template ends before a "}", then append the "{" and
      extracted characters to the result string and return with an error
      status indicating the expression is malformed.

   Examine the first character of the extracted expression for an
   operator.

   o  If the expression ended (i.e., is "{}"), an operator is found that
      is unknown or unimplemented, or the character is not in the
      varchar set (Section 2.3), then append "{", the extracted
      expression, and "}" to the result string, remember that the result
      is in an error state, and then go back to scan the remainder of
      the template.

   o  If a known and implemented operator is found, store the operator
      and skip to the next character to begin the varspec-list.

   o  Otherwise, store the operator as NUL (simple string expansion).

   Use the following value table to determine the processing behavior by
   expression type operator.  The entry for "first" is the string to
   append to the result first if any of the expression's variables are
   defined.  The entry for "sep" is the separator to append to the
   result before any second (or subsequent) defined variable expansion.
   The entry for "named" is a boolean for whether or not the expansion
   includes the variable or key name when no explode modifier is given.
   The entry for "ifemp" is a string to append to the name if its
   corresponding value is empty.  The entry for "allow" indicates what



Gregorio, et al.             Standards Track                   [Page 30]

RFC 6570                      URI Template                    March 2012


   characters to allow unencoded within the value expansion: (U) means
   any character not in the unreserved set will be encoded; (U+R) means
   any character not in the union of (unreserved / reserved / pct-
   encoding) will be encoded; and, for both cases, each disallowed
   character is first encoded as its sequence of octets in UTF-8 and
   then each such octet is encoded as a pct-encoded triplet.

   .------------------------------------------------------------------.
   |          NUL     +      .       /       ;      ?      &      #   |
   |------------------------------------------------------------------|
   | first |  ""     ""     "."     "/"     ";"    "?"    "&"    "#"  |
   | sep   |  ","    ","    "."     "/"     ";"    "&"    "&"    ","  |
   | named | false  false  false   false   true   true   true   false |
   | ifemp |  ""     ""     ""      ""      ""     "="    "="    ""   |
   | allow |   U     U+R     U       U       U      U      U     U+R  |
   `------------------------------------------------------------------'

   With the above table in mind, process the variable-list as follows:

   For each varspec, extract a variable name and optional modifier from
   the expression by scanning the variable-list until a character not in
   the varname set is found or the end of the expression is reached.

   o  If it is the end of the expression and the varname is empty, go
      back to scan the remainder of the template.

   o  If it is not the end of the expression and the last character
      found indicates a modifier ("*" or ":"), remember that modifier.
      If it is an explode ("*"), scan the next character.  If it is a
      prefix (":"), continue scanning the next one to four characters
      for the max-length represented as a decimal integer and then, if
      it is still not the end of the expression, scan the next
      character.

   o  If it is not the end of the expression and the last character
      found is not a comma (","), append "{", the stored operator (if
      any), the scanned varname and modifier, the remaining expression,
      and "}" to the result string, remember that the result is in an
      error state, and then go back to scan the remainder of the
      template.

   Lookup the value for the scanned variable name, and then

   o  If the varname is unknown or corresponds to a variable with an
      undefined value (Section 2.3), then skip to the next varspec.






Gregorio, et al.             Standards Track                   [Page 31]

RFC 6570                      URI Template                    March 2012


   o  If this is the first defined variable for this expression, append
      the first string for this expression type to the result string and
      remember that it has been done.  Otherwise, append the sep string
      to the result string.

   o  If this variable's value is a string, then

      *  if named is true, append the varname to the result string using
         the same encoding process as for literals, and

         +  if the value is empty, append the ifemp string to the result
            string and skip to the next varspec;

         +  otherwise, append "=" to the result string.

      *  if a prefix modifier is present and the prefix length is less
         than the value string length in number of Unicode characters,
         append that number of characters from the beginning of the
         value string to the result string, after pct-encoding any
         characters that are not in the allow set, while taking care not
         to split multi-octet or pct-encoded triplet characters that
         represent a single Unicode code point;

      *  otherwise, append the value to the result string after pct-
         encoding any characters that are not in the allow set.

   o  else if no explode modifier is given, then

      *  if named is true, append the varname to the result string using
         the same encoding process as for literals, and

         +  if the value is empty, append the ifemp string to the result
            string and skip to the next varspec;

         +  otherwise, append "=" to the result string; and

      *  if this variable's value is a list, append each defined list
         member to the result string, after pct-encoding any characters
         that are not in the allow set, with a comma (",") appended to
         the result between each defined list member;

      *  if this variable's value is an associative array or any other
         form of paired (name, value) structure, append each pair with a
         defined value to the result string as "name,value", after pct-
         encoding any characters that are not in the allow set, with a
         comma (",") appended to the result between each defined pair.





Gregorio, et al.             Standards Track                   [Page 32]

RFC 6570                      URI Template                    March 2012


   o  else if an explode modifier is given, then

      *  if named is true, then for each defined list member or array
         (name, value) pair with a defined value, do:

         +  if this is not the first defined member/value, append the
            sep string to the result string;

         +  if this is a list, append the varname to the result string
            using the same encoding process as for literals;

         +  if this is a pair, append the name to the result string
            using the same encoding process as for literals;

         +  if the member/value is empty, append the ifemp string to the
            result string; otherwise, append "=" and the member/value to
            the result string, after pct-encoding any member/value
            characters that are not in the allow set.

      *  else if named is false, then

         +  if this is a list, append each defined list member to the
            result string, after pct-encoding any characters that are
            not in the allow set, with the sep string appended to the
            result between each defined list member.

         +  if this is an array of (name, value) pairs, append each pair
            with a defined value to the result string as "name=value",
            after pct-encoding any characters that are not in the allow
            set, with the sep string appended to the result between each
            defined pair.

   When the variable-list for this expression is exhausted, go back to
   scan the remainder of the template.

















Gregorio, et al.             Standards Track                   [Page 33]

RFC 6570                      URI Template                    March 2012


Authors' Addresses

   Joe Gregorio
   Google

   EMail: joe@bitworking.org
   URI:   http://bitworking.org/


   Roy T. Fielding
   Adobe Systems Incorporated

   EMail: fielding@gbiv.com
   URI:   http://roy.gbiv.com/


   Marc Hadley
   The MITRE Corporation

   EMail: mhadley@mitre.org
   URI:   http://mitre.org/


   Mark Nottingham
   Rackspace

   EMail: mnot@mnot.net
   URI:   http://www.mnot.net/


   David Orchard
   Salesforce.com

   EMail: orchard@pacificspirit.com
   URI:   http://www.pacificspirit.com/
















Gregorio, et al.             Standards Track                   [Page 34]



