Kurzübersicht

Funktionen, die als Natural-Objekte ausgeliefert werden

Dieses Dokument beschreibt Funktionen, die unter Verwendung von Natural-Objekten des Typs Function implementiert wurden.

Diese Function-Objekte (und ihre Prototyp-Definitionen), deren Namen mit SAG beginnen, werden in der Natural-Library SYSTEM in der Systemdatei FNAT ausgeliefert. Beispiele für Function Calls sind in der Library SYSEXPG vorhanden.

Weitere Informationen siehe Function Call im Leitfaden zur Programmierung.


URL-Kodierung

Bei HTTP-Anfragen über Natural-Anwendungsschnittstellen ist es oftmals notwendig, dass der URI (Uniform Resource Identifier) URL-kodiert ist. Das Statement REQUEST DOCUMENT benötigt eine solche URL, um auf ein Dokument zugreifen zu können.

URL-Kodierung, auch Prozentkodierung genannt, ist ein Mechanismus, um bestimmte Sonderzeichen in Teilen einer URL zu ersetzen. Zur Bildung einer URL werden nur Zeichen des US-ASCII-Zeichensatzes verwendet. Einige Zeichen des US-ASCII-Zeichensatzes haben bei Verwendung in einer URL eine besondere Bedeutung - sie sind als "reservierte" Steuerzeichen eingestuft, die zur Strukturierung der Zeichenkette in verschiedene sematische Unterkomponenten dienen. Der Quasi-Standard bezüglich der generischen Syntax einer URL ist im Dokument RFC3986 enthalten, das von der Internet-Community zusammengestellt worden ist. Darin wird beschrieben, unter welchen Bedingungen eine URL-Kodierung notwendig ist. Dazu gehört auch die Darstellung von Zeichen, welche nicht Bestandteil des US-ASCII-Zeichensatzes sind (zum Beispiel das Euro-Zeichen) und die Verwendung der reservierten Zeichen.

Reservierte Zeichen sind:

? = & # ! $ % ' ( ) * + , / : ; @ [ ]

Nicht reservierte Zeichen sind:

A-Z a-z 0-9 - _ . ~

Eine URL besteht aus reservierten und nicht-reservierten Zeichen; andere Zeichen dürfen in ihr nicht vorkommen. Wenn andere Byte-Werte benötigt werden (die keinem der reservierten und nicht reservierten Zeichen entsprechen) oder wenn reservierte Zeichen als Daten verwendet werden (die keine besondere semantische Bedeutung im URL-Kontext haben sollen), müssen diese Werte in die "Prozentkodierung" konvertiert werden: ein Prozentzeichen und direkt danach die aus zwei Zeichen bestehende hexadezimale Darstellung des Codepoint (bedingt durch das Kodierschema Windows-1252). Das hat zur Folge, dass ein Pluszeichen (+) als %2B, ein Prozentzeichen als %25 und ein "at"-Zeichen (@) als %40 in der Zeichenkette erscheint.

Die nachfolgend beschriebenen Kodierfunktionen bearbeiten die kompletten Eingabe-Zeichenkette. Bitte beachten Sie, dass Sie keine komplette URL oder Teile davon kodieren, falls diese Steuerzeichen (reservierte Zeichen) enthalten, die nicht in die Prozentform umgesetzt werden dürfen. Die hier beschriebenen Funktionen sollten nur bei Zeichen angewendet werden, welche nicht für den Gebrauch in einer URL erlaubt sind, und bei Zeichen mit einer besonderen Bedeutung im URL-Kontext, die als Datenelement übergeben werden.

Einfache Kodierung

Der einzelne Eingabeparameter enthält die zu kodierende oder zu dekodierende Zeichenkette. Alle darin enthaltenen Daten werden so betrachtet, als ob sie in der Codepage EBCDIC 1140 dargestellt sind, und zwar unabhängig davon welche Session-Codepage zurzeit aktiv ist. Zur Ausführung der Funktion SAGENC bzw. SAGDEC ist keine Unicode-Unterstützung erforderlich. Die folgenden Zeichen werden durch die entsprechenden hexadezimalen US-ASCII-Zeichen ersetzt.

Das Zeichen,...
< ( + | & ! $ * ) ; / , % > ? ` : # @ ' = " ^ [ ] { } \
das sich am EBCDIC Codepoint befindet, 4C 4D 4E 4F 50 5A 5B 5C 5D 5E 61 6B 6C 6E 6F 79 7A 7B 7C 7D 7E 7F B0 BA BB C0 D0 E0
wird kodiert zu %nn 3C 28 2B 7C 26 21 24 2A 29 3B 2F 2C 25 3E 3F 60 3A 23 40 27 3D 22 5E 5B 5D 7B 7D 5C

Folgende Funktionen stehen zur Verfügung:

  • SAGENC - Einfache Kodierung (Format A nach Format A)

  • SAGDEC - Einfache Dekodierung (Format A nach Format A)

SAGENC - Einfache Kodierung (Format A nach Format A)

Die Funktion SAGENC kodiert eine Zeichenkette in die prozentkodierte Form. Gemäß Standard RFC3986 werden reservierte Zeichen und Zeichen unterhalb von US-ASCII x'7F' (die in einer URL nicht erlaubt sind) prozentkodiert; ein Leerzeichen wird durch ein Pluszeichen (+) ersetzt. Nicht reservierte Zeichen gemäß RCF3986 und Zeichen oberhalb von US-ASCII x'7F', zum Beispiel deutsche Umlaute, werden nicht kodiert. Falls Sie solche Zeichen kodieren möchten, müssen Sie die erweitere Kodierfunktion SAGENCE.

Objekt Beschreibung
SAGENC Dies ist der Aufruf der einfachen Kodierfunktion.
SAGENCP Der Copycode, der die Prototyp-Definition enthält, wird nur bei der Kompilierung benutzt, um den Typ der Rückgabevariablen als Referenz für den Funktionsaufruf zu bestimmen und um die Parameter zu prüfen, falls dies gewünscht wird.

SAGENCP ist optional.

URLX01 Beispiel-Programm in der Library SYSEXPG.
#URL-ENC := SAGENC(<#URL-DEC>)

SAGDEC - Einfache Dekodierung (Format A nach Format A)

Die Funktion SAGDEC dient zum Dekodieren der von der Funktion SAGENC gelieferten Prozentkodierungen. Außer der zu dekodierenden Zeichenkette werden keine weiteren Parameter benötigt.

Objekt Beschreibung
SAGDEC Dies ist der Aufruf der einfachen Dekodierfunktion.
SAGDECP Der Copycode, der die Prototyp-Definition enthält, wird nur bei der Kompilierung benutzt, um den Typ der Rückgabevariablen als Referenz für den Funktionsaufruf zu bestimmen und um die Parameter zu prüfen, falls dies gewünscht wird.

SAGDECP ist optional.

URLX01 Beispiel-Programm in der Library SYSEXPG.
#URL-DEC := SAGDEC(<#URL-ENC>) 

Erweiterte Kodierung

Die erweiterte Funktion berücksichtigt alle in der Spezifikation RFC3986 aufgeführten Sonderfälle. Die folgenden Parameter können berücksichtigt werden (Die Standardvorgabewerte sind fett hervorgehoben.):

  1. <dynamic U-string> soll kodiert/dekodiert werden.

  2. Return Code: <> 0 (Natural-Fehler) bei Auftreten eines Fehlers im MOVE ENCODED-Statement.

  3. Fehlerzeichen falls Return Code <> 0.

  4. Leerzeichen: %20/+/nicht kodieren (Standardeinstellung: +)

  5. Nicht reservierte Zeichen: kodieren/nicht kodieren

  6. Reservierte Zeichen: kodieren/nicht kodieren

  7. Sonstige Sonderzeichen (weder nicht reservierte noch reservierte Zeichen): kodieren/nicht kodieren

  8. Zeichen-Prozentkodierung: ISO-8859-1/UTF-8/beliebige andere Codepage/falls = ' ' dann *CODEPAGE (Natural-Standard-Codepage, nicht die Codepage für die Standardkodierung!)

  9. Vom Benutzer gewähltes Zeichen in einem X-array des Formats U, welches nicht nach den oben aufgeführten Parametern prozentkodiert werden soll (zum Beispiel das Euro-Symbolzeichen, das in der Codepage ISO-8859-1 nicht vorhanden ist) oder um zu verhindern, dass ein Zeichen prozentkodiert wird.

  10. Benutzer-definierte Prozentkodierung in ein X-array des Formats A, für ein vom Benutzer gewähltes Zeichen in derselben Ausprägung des X-array.

Der Eingabeparameter für eine Zeichenkette hat das Natural-Format U. Das bedeutet, dass die Eingabezeichenkette alle Unicode-Zeichen enthalten darf. Die Ausgabezeichenkette der erweiterten Funktion hat das Natural-Format A und ist in der Natural-Standard-Codepage (*CODEPAGE) kodiert. Die Codepage der Prozentkodierung kann gewählt werden. Die Prozentkodierung gemäß UTF-8, ISO-8859-1, des Euro-Symbolzeichens erfolgt mittels eines MOVE ENCODED-Statements. Ist ein Eingabezeichen in der für die Prozentkodierung verwendeten Ziel-Codepage nicht vorhanden, dann wird dieses Zeichen nicht kodiert. Das bedeutet, das Zeichen wird unverändert in der Natural-Standard-Codepage zurückgegeben. Falls das Zeichen in der Natural-Standard-Codepage auch nicht vorhanden ist, wird es durch das vom MOVE ENCODED-Statement zurückgelieferte Ersetzungszeichen ersetzt. Das Ersetzungszeichen wird prozentkodiert. Dieser Fall kann nur dann eintreten, wenn die Codepage zur Prozentkodierung nicht UTF-8 ist. Der zuletzt aufgetretene MOVE ENCODED-Fehler wird zurückgeliefert.

Die Parameter sind optional. Wenn der Benutzer einen Parameter nicht angibt, wird der Standardvorgabewert verwendet. Falls der Benutzer eine eigene Zeichenumsetzungstabelle angibt, werden die Zeichen in der Tabelle entsprechend dieser Tabelle und nicht entsprechend den anderen Parametern prozentkodiert. Wenn die Prozentkodierung eines Zeichens in der benutzerdefinierten Umsetzungstabelle gleich dem Zeichen oder leer ist, wird dieses Zeichen nicht kodiert. Somit können einzelne Zeichen aus dem reservierten oder nicht reservierten Zeichensatz ausgeschlossen werden.

Folgende Funktionen stehen zur Verfügung:

  • SAGENCE - Erweiterte Kodierung (Format U nach Format A, optionale Parameter)

  • SAGDECE - Erweiterte Dekodierung (Format A nach Format U, optionale Parameter)

SAGENCE - Erweiterte Kodierung (Format U nach Format A, optionale Parameter)

Die Funktion SAGENCE dient zur Prozentkodierung einer Zeichenkette unter Verwendung des Hexadezimalwerts aus der gewählten Codepage (standardmäßi UTF-8). Gemäß dem Standard RFC3986 werden reservierte Zeichen und Zeichen unterhalb von US-ASCII x'7F', welche in einer URL nicht zulässig sind, prozentkodiert. Außerdem werden das Zeichen für den Leerschritt und das Prozentzeichen (%) kodiert.

Darüber hinaus werden nicht reservierte Zeichen gemäß RCF3986 und Zeichen oberhalb von US-ASCII x'7F', zum Beispiel deutsche Umlaute, von dieser Funktion kodiert.

SAGENCE benötigt Natural-Unicode-Unterstützung.

Objekt Beschreibung
SAGENCE Dies ist der Aufruf der erweiterten Kodierfunktion.
Parameter:
P-DEC-STR-E    (U)
P-RET          (I4)     OPTIONAL  /* 0:    ok
                                  /* else: Natural error returned
                                  /*       by the GIVING clause of
                                  /*       MOVE ENCODED.
                                  /*       This is the error which
                                  /*       comes up when a character
                                  /*       cannot be converted into
                                  /*       the target code page.
/* Error strategy:
/* Step 1: If a character shall be %-encoded and is not available
/* in the code page for %-encoding, the character will not be
/* %-encoded. It will be copied.
/* Step 2: If a character will not be %-encoded but copied from the
/* input format U-variable to a format A-variable (in *CODEPAGE)
/* and the character is not available in *CODEPAGE, a substitution
/* character will be used instead. The substitution character will
/* be %-encoded.
/* The last error will be returned in P-RET.
P-ERR-CHAR     (U1)     OPTIONAL  /* Character causing the error
P-SPACE        (A1)     OPTIONAL  /* '%'  => %20
                                  /* ' '  => ' '
                                  /* else => '+' (default)
P-UNRES        (A1)     OPTIONAL  /* 'E'  => encode
                                  /* else => don't encode (default)
P-RES          (A1)     OPTIONAL  /* 'E'  => encode (default)
                                 /* else => don't encode
P-OTHER        (A1)     OPTIONAL  /* 'E'  => encode (default)
                                  /* else => don't encode
P-CP           (A64)    OPTIONAL  /* IANA name e.g. UTF-8 (default)
                                  /* or ISO-8859-1
/* On mainframe only code page names defined with the macro NTCPAGE
/* in the source module NATCONFG can be used. Other code page names
/* are rejected with a corresponding runtime error.
/*
P-CP-TABLE-CHAR(U1/1:*)  OPTIONAL /* user selected char to be
                                  /* %-encoded, e.g. 'ö' or '/'
P-CP-TABLE-ENC (A12/1:*) OPTIONAL /* user %-encoding
                                  /* e.g. character 'ö'
                                  /*      '%F6'    -> ISO-8859-1
                                  /*      '%C3%B6' -> UTF-8
                                  /* e.g. character '/'
                                  /*      '/'    -> '/' not encoded
                                  /*       although P-RES = 'E'
/* Characters in this table will be encoded according to the
/* specifed %-encoding. If the U12 encoding part is blank (space
/* according to *CODEPAGE) or the P-CP-TABLE-ENC value is equal to
/* the character, then the character will not be encoded at all.
/*
SAGENCEP Der Copycode, der die Prototyp-Definition enthält, wird nur bei der Kompilierung benutzt, um den Typ der Rückgabevariablen als Referenz für den Funktionsaufruf zu bestimmen und um die Parameter zu prüfen, falls dies gewünscht wird.

SAGENCEP ist optional.

URLX01 Beispiel-Programm in der Library SYSEXPG.

Beispielaufrufe

Verwendet werden die Standardvorgabewerte:

#URL-ENC := SAGENCE(<#URL-DEC-U>)

Alle Parameter, die möglich sind, werden angegeben:

#URL-ENC := SAGENCE(<#URL-DEC-U,L-RET,L-ERR-CHAR,L-SPACE,L-UNRES, L-RES,L-OTHER,L-CP,L-CP-TAB-CHAR(*),L-CP-TAB-ENC(*) >)

SAGDECE - Erweiterte Dekodierung (Format A nach Format U, optionale Parameter)

Die Funktion SAGDECE dient zum Dekodieren der von der Funktion SAGENCE gelieferten Prozentkodierungen. Falls ein Leerschrittzeichen und/oder eine Codepage angegeben werden, müssen die Werte mit den bei der Kodierung angegebenen Werte übereinstimmen.

SAGDECE benötigt Natural-Unicode-Unterstützung.

Objekt Beschreibung
SAGDECE Dies ist der Aufruf der erweiterten Dekodierfunktion.
Parameter:
1 P-ENC-STR-E    (A)
1 P-RET          (I4)     OPTIONAL  /* 0:    ok
                                    /* else: Natural error returned
                                    /*       by the GIVING clause of
                                    /*       MOVE ENCODED.
                                    /*       This error comes up
                                    /*       when a %-encoded
                                    /*       character cannot be
                                    /*       converted into the
                                    /*       target code page.
  /* The last error will be returned in P-RET.
1 P-ERR-CHAR     (A12)    OPTIONAL  /* Error character %-encoded
1 P-SPACE        (A1)     OPTIONAL  /* ' '  => ' '
                                    /* else => '+' (default)
1 P-CP           (A64)    OPTIONAL  /* IANA name e.g. UTF-8 (default)
                                    /* or ISO-8859-1
/* On mainframe only code page names defined with the macro NTCPAGE
/* in the source module NATCONFG can be used. Other code page names
/* are rejected with a corresponding runtime error.
/*
SAGDECEP Der Copycode, der die Prototyp-Definition enthält, wird nur bei der Kompilierung benutzt, um den Typ der Rückgabevariablen als Referenz für den Funktionsaufruf zu bestimmen und um die Parameter zu prüfen, falls dies gewünscht wird.

SAGDECEP ist optional.

URLX01 Example program in der Library SYSEXPG.

Beispielaufrufe

Verwendet werden die Standardvorgabewerte:

#URL-DEC-U := SAGDECE(<#URL-ENC>)

Alle Parameter, die möglich sind, werden angegeben:

#URL-DEC-U := SAGDECE(<#URL-ENC,L-RET,L-ERR-CHAR-DEC,L-SPACE,L-CP>)

Beispiel-Programm

Dieses Beispiel-Programm befindet sich in der Library SYSEXPG:

** Example 'URLX01': ENCODED-STR := SAGENC(<DECODED-STR>)                
************************************************************************ 
DEFINE DATA                                                              
LOCAL                                                                    
1 SAMPLE-STRING (A72)                                                    
/*                                                                       
1 #URL-DEC      (A) DYNAMIC                                              
1 #URL-ENC      (A) DYNAMIC                                              
/*                                                                       
1 #URL-DEC-U    (U) DYNAMIC                                              
/*                                                                       
1 L-RET         (I4)   /* Return code                                    
1 L-ERR-CHAR    (U1)   /* Error character                                
1 L-ERR-CHAR-DEC(A12)  /* Decoded error character                        
1 L-SPACE       (A1)   /* '%'  => %20, ' '  => ' ',                      
                       /* else => '+' (default)                          
1 L-UNRES       (A1)   /* 'E' => encode, else => don't encode (default)  
1 L-RES         (A1)   /* 'E' => encode (default), else => don't encode  
1 L-OTHER       (A1)   /* 'E' => encode (default), else => don't encode  
1 L-CP          (A64)  /* default *CODEPAGE                              
1 L-CP-TAB-CHAR (U1/1:1)                                                 
1 L-CP-TAB-ENC  (A12/1:1)                                                
1 L-MSG         (U72)                                                    
END-DEFINE                                                               
/*                                                                       
/*                                                                       
/*                                                                       
WRITE 'Sample string to be processed:'                                   
/* The string below shall be encoded and decoded again.                  
/* After decoding it should be unchanged.                                
SAMPLE-STRING := '"Decoded data!"'                                       
WRITE SAMPLE-STRING (AL=72) /                                            
/*                                                                       
/* Assign the sample string to the input variable #URL-DEC of the        
/* simple encoding function.                                             
#URL-DEC      := SAMPLE-STRING                                           
/*                                                                       
/* Copycode SAGENCP containing the prototype definition is used at       
/* compilation time only in order to determine the type of the return    
/* variable for function call reference and to check the parameters,     
/* if this is desired. SAGENCP is optional.                              
INCLUDE SAGENCP                                                          
/*                                                                       
/* SAGENC(<#URL-DEC>) is the simple encoding function call.              
/*                                                                       
/* Function SAGENC %-encodes a string to code page ISO-8859-1.           
/* According to standard RFC3986 reserved characters and characters      
/* below US-ASCII x'7F' which are not allowed in a URL will be           
/* %-encoded.                                                            
/* Also the space and the percent sign will be encoded.                  
/* Unreserved characters according to RCF3986 and characters above       
/* US-ASCII x'7F' will not be encoded. If you want to encode such        
/* characters, use the extended encoding function.                       
/*                                                                       
/* ---- Space                       ' ' -> '+'                           
/* ---- Percent sign                '%' -> '%25'                         
/*                                                                       
/* Unreserved characters according to RFC3986 (will not be encoded!):    
/* ---- Period (fullstop)           '.' -- '%2E'                         
/* ---- Tilde                       '~' -- '%7E'                         
/* ---- Hyphen                      '-' -- '%2D'                         
/* ---- Underscore character        '_' -- '%5F'                         
/* ---- digits, lower and upper case characters                          
/* ---- 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ   
/*                                                                       
/* Reserved characters according to RFC3986:                             
/* ---- Exclamation mark            '!' -> '%21'                         
/* ---- Number sign                 '#' -> '%23'                         
/* ---- Dollar sign                 '$' -> '%24'                         
/* ---- Ampersand                   '&' -> '%26'                         
/* ---- Apostrophe                  ''' -> '%27'                         
/* ---- Left parenthesis            '(' -> '%28'                         
/* ---- Right parenthesis           ')' -> '%29'                         
/* ---- Asterisk                    '*' -> '%2A'                         
/* ---- Plus sign                   '+' -> '%2B'                         
/* ---- Comma                       ',' -> '%2C'                         
/* ---- Reverse solidus (backslash) '/' -> '%2F'                         
/* ---- Colon                       ':' -> '%3A'                         
/* ---- Semi-colon                  ';' -> '%3B'                         
/* ---- Equals sign                 '=' -> '%3D'                         
/* ---- Question mark               '?' -> '%3F'                         
/* ---- Commercial at               '@' -> '%40'                         
/* ---- Square bracket open         '[' -> '%5B'                         
/* ---- Square bracket close        ']' -> '%5D'                         
/*                                                                       
/* Other characters below x'7F' (US-ASCII) but not allowed in URL        
/* ---- Quotation mark              '"' -> '%22'                         
/* ---- Less than                   '<' -> '%3C'                         
/* ---- Greater than                '>' -> '%3E'                         
/* ---- Reverse solidus (backslash) '\' -> '%5C'                         
/* ---- Accent, Circumflex          '^' -> '%5E'                         
/* ---- Accent, Grave               '`' -> '%60'                         
/* ---- Opening brace               '{' -> '%7B'                         
/* ---- Vertical bar                '|' -> '%7C'                         
/* ---- Closing brace               '}' -> '%7D'                         
/*                                                                       
#URL-ENC := SAGENC(<#URL-DEC>)                                           
/*                                                                       
/*                                                                       
WRITE 'Simple function, encoded:'                                        
WRITE #URL-ENC (AL=72)                                                   
/*                                                                       
/* Copycode SAGDECP containing the prototype definition is used at       
/* compilation time only in order to determine the type of the return    
/* variable for function call reference and to check the parameters,     
/* if this is desired. SAGDECP is optional.                              
INCLUDE SAGDECP                                                          
/*                                                                       
/* SAGDEC(<#URL-ENC>) is the simple decoding function call.              
/* It decodes the above described %-encodings.                           
/*                                                                       
#URL-DEC := SAGDEC(<#URL-ENC>)                                           
/*                                                                       
/*                                                                       
/* The result after encoding and decoding must be equal to the original  
/* SAMPLE-STRING.                                                        
WRITE 'Simple function, decoded:'                                        
WRITE #URL-DEC (AL=72)                                                   
/*                                                                       
/*                                                                       
/*                                                                       
WRITE /                                                                  
/*                                                                       
/*                                                                       
/*                                                                       
/* Assign the sample string to the input variable #URL-DEC-U of the      
/* enhanced encoding function.                                           
#URL-DEC-U := SAMPLE-STRING                                              
/*                                                                       
/* Copycode SAGENCEP containing the prototype definition is used at      
/* compilation time only in order to determine the type of the return    
/* variable for function call reference and to check the parameters,     
/* if this is desired. SAGENCEP is optional.                             
INCLUDE SAGENCEP                                                         
/*                                                                       
/* This is the enhanced encoding function call.                          
/* The way, characters will be %-encoded dependes on the input           
/* parameter of the function.                                            
/* The parameters of the encoding and decoding function are preset       
/* with the default values.                                              
/* L-CP-TAB-CHAR(*) and L-CP-TAB-ENC(*) don't have default values.       
/* L-CP-TAB-CHAR(1) = 'ä' and L-CP-TAB-ENC(1) = '%C3%A4' will not be     
/* used for the sample string '"Decoded data!"'. The string does not     
/* contain an 'ä'.                                                       
L-SPACE     := '+'           /* encoding and decoding                    
L-UNRES     := 'D'           /* encoding only                            
L-RES       := 'E'           /* encoding only                            
L-OTHER     := 'E'           /* encoding only                            
L-CP        := 'UTF-8'       /* encoding and decoding                    
                             /* e.g. ISO-8859-1, UTF-16BE, UTF-32BE      
L-CP-TAB-CHAR(1) := 'ä'      /* encoding only                            
L-CP-TAB-ENC (1) := '%C3%A4' /* encoding only                            
/*                                                                       
/* Note that all possible parameters are specified for this sample       
/* call.                                                                 
/* If the default values shall be used and no return code is wanted,     
/* all parameters can be omitted, besides the string #URL-DEC-U.         
/*                                                                       
#URL-ENC := SAGENCE(<#URL-DEC-U,L-RET,L-ERR-CHAR,L-SPACE,L-UNRES,        
  L-RES,L-OTHER,L-CP,L-CP-TAB-CHAR(*),L-CP-TAB-ENC(*) >)                 
WRITE 'Extended function, encoded:'                                      
WRITE #URL-ENC (AL=72)                                                   
IF L-RET NE 0 THEN                                                       
  /* If L-RET = 0, the function worked ok. Else L-RET contains the       
  /* Natural error returned by the GIVING clause of MOVE ENCODED.        
  /* The error comes up when a character cannot be converted into        
  /* the target codepage, e.g. because a character does not exist        
  /* in the target codepage.                                             
  COMPRESS 'Error' L-RET 'with MOVE ENCODED of' L-ERR-CHAR INTO L-MSG    
  WRITE L-MSG                                                            
END-IF                                                                   
/*                                                                       
/* Copycode SAGDECEP containing the prototype definition is used at      
/* compilation time only in order to determine the type of the return    
/* variable for function call reference and to check the parameters,     
/* if this is desired. SAGDECEP is optional.                             
INCLUDE SAGDECEP                                                         
/*                                                                       
/* This is the 1st enhanced decoding function call with 5 parameters.    
/* Note that all possible parameters are specified for this sample       
/* call.                                                                 
/* Since the parameters have the default values, the subsequent          
/* function calls return the same result although parameters             
/* have been omitted.                                                    
#URL-DEC-U := SAGDECE(<#URL-ENC,L-RET,L-ERR-CHAR-DEC,L-SPACE,L-CP>)      
WRITE 'Extended function, decoded:'                                      
WRITE #URL-DEC-U (AL=72)                                                 
IF L-RET NE 0 THEN                                                       
  /* If L-RET = 0, the function worked ok. Else L-RET contains the       
  /* Natural error returned by the GIVING clause of MOVE ENCODED.        
  /* The error comes up when a %-encoded character cannot be converted   
  /* into the target codepage, e.g. because a character does not exist   
  /* in the target codepage.                                             
  COMPRESS 'Error' L-RET 'with MOVE ENCODED of' L-ERR-CHAR INTO L-MSG    
  WRITE L-MSG                                                            
  RESET L-RET                                                            
END-IF                                                                   
/*                                                                       
/* This is the 2nd enhanced decoding function call with one parameter.   
#URL-DEC-U := SAGDECE(<#URL-ENC>)                                        
WRITE #URL-DEC-U (AL=72)                                                 
/* L-RET will not be returned                                            
/*                                                                       
/* This is the 3rd enhanced decoding function call with 3 parameters.    
#URL-DEC-U := SAGDECE(<#URL-ENC,L-RET,2X,L-CP>)                          
WRITE #URL-DEC-U (AL=72)                                                 
IF L-RET NE 0 THEN                                                       
  COMPRESS 'Error' L-RET 'with MOVE ENCODED of' L-ERR-CHAR INTO L-MSG    
  WRITE L-MSG                                                            
  RESET L-RET                                                            
END-IF                                                                   
/*                                                                       
END                                                                      

Base64-Kodierung

Dieser Abschnitt beschreibt Natural-Funktionen, die Sie benutzen können, um mittels Base64-Konvertierung Binärdaten in druckbare, netzkompatible Daten bzw. in umgekehrter Richtung zu konvertieren.

Base64-Konvertierung bedeutet eine Umwandlung vom Format B in das Format A und zurück nach Format B. Dabei werden 6 (binäre) Bits in 8 (alphanumerische) Bits umgewandelt. Beispiel: Ein Wert mit Format/Länge B3 wird in einen Wert mit Format/Länge A4 umgewandelt.

Anmerkung:
Jeder Binärwert wird in einen eindeutigen alphanumerischen Wert umgewandelt. Die Rückumwandlung dieses alphanumerischen Werts ergibt dann wieder den ursprünglichen Binärwert. Dies ist jedoch bei den meisten Umwandlungen von Format A nach Format B und zurück nach Format A nicht der Fall.

Die Konvertierung kann benutzt werden, um eine Datei vom Typ .bmp per TCP/IP zu übertragen oder um Natural-Binär- oder Ganzzahlwerte per Utility-Protokoll zu übertragen.

Nur bei Open Systems: Es stehen drei Modi zur Verfügung: RFC3548, RFC2045 und NATRPC (Standardeinstellung). NATRPC bedeutet, dass die Umwandlung entsprechend der NATRPC-Ligik erfolgt. Diese ist zu 100% großrechnerkompatibel. RFC2045 ist der Standardvorgabewert für den CMBASE64-Aufruf. RFC3548 ist wie NATRPC, aber nicht benötigte alphanumerische Bytes werden mit einem Gleichheitszeichen (=) gefüllt.

Folgende Funktionen stehen zur Verfügung:

  • SAG64BA - Konvertierung von binär nach alphanumerisch

  • SAG64AB - Konvertierung von alphanumerisch nach binär

Diese beiden Funktionen zusammengenommen bieten die gleiche Funktionalität wie das API USR4210N. Dieses API befindet sich in der Library SYSEXT.

SAG64BA - Konvertierung von binär nach alphanumerisch

Die Funktion SAG64BA wandelt mittels Base64-Konvertierung Binärdaten in druckbare, netzkompatible Daten

Objekt Beschreibung
SAG64BA Dies ist die Funktion zur Wandlung vom Binärformat in alphanumerisches Format.
Parameter:
1 PARM-B         (B)      DYNAMIC BY VALUE
                /* Binary source input/target output
1 PARM-RC        (I4)     OPTIONAL
                /* 0:    ok
                /* Mainframe
                /* 1  Source is not numeric
                /* 2  Source is not packed
                /* 3  Source is not floating point
                /* 4  Overflow, source doesn't fit into target
                /* 5  Integer overflow
                /* 6  Source is not a valid date or time
                /* 7  Length error (hex input not even)
                /* 8  Target precision is less than source precision
                /* 9  Float underflow (result->0)
                /* 10 Alpha source contains non-hex characters
                /* 20 Invalid function code
                /* Open Systems
                /* 1  Invalid value for RFC parameter
                /* 2  Invalid function code
                /* 3  CMBASE64: Overflow, source doesn't fit into
                /*              target
                /* 4  CMBASE64: Non-base64 character found in encoded
                /*              data
                /* 5  CMBASE64: Out of memory
                /* 6  CMBASE64: Invalid number of parameters
                /* 7  CMBASE64: Invalid parameter type
                /* 8  CMBASE64: Invalid parameter length
                /* 9  CMBASE64: Invalid function code
                /* 10 CMBASE64: Unkown return code
1 PARM-ERRTXT    (A72)    OPTIONAL
                /* blank, if ok no error
                /* else error text
1 PARM-RFC       (B1)     OPTIONAL
                /* OS only, not used for MF
                /* 0 - RFC3548; 3 - RFC2045; 4 - NATRPC;
SAG64BAP Der Copycode, der die Prototyp-Definition enthält, wird nur bei der Kompilierung benutzt, um den Typ der Rückgabevariablen als Referenz für den Funktionsaufruf zu bestimmen und um die Parameter zu prüfen, falls dies gewünscht wird.

SAG64BAP ist optional.

B64X01 Beispiel-Programm in der Library SYSEXPG.

Verwendet werden die Standardvorgabewerte:

PARM-A := SAG64BA(<PARM-B>)

Alle Parameter, die möglich sind, werden angegeben (PARM-RFC gilt nicht bei Großrechnern):

PARM-A := SAG64BA(<PARM-B,PARM-RC,PARM-ERRTXT,PARM-RFC>)

SAG64AB - Wandlung vom alphanumerischen Format in das Binärformat

Die Funktion SAG64AB wandelt mittels Base64-Konvertierung druckbare, netzkompatible Daten in Binärdaten.

Objekt Beschreibung
SAG64AB Dies ist die Funktion zur Wandlung vom alphanumerischen Format in das Binärformat.
Parameter:
1 PARM-A         (A)
                /* Alpha source input/target output
1 PARM-RC        (I4)     OPTIONAL
                /* 0:    ok
                /* Mainframe
                /* 1  Source is not numeric
                /* 2  Source is not packed
                /* 3  Source is not floating point
                /* 4  Overflow, source doesn't fit into target
                /* 5  Integer overflow
                /* 6  Source is not a valid date or time
                /* 7  Length error (hex input not even)
                /* 8  Target precision is less than source precision
                /* 9  Float underflow (result->0)
                /* 10 Alpha source contains non-hex characters
                /* 20 Invalid function code
                /* Open Systems
                /* 1  Invalid value for RFC parameter
                /* 2  Invalid function code
                /* 3  CMBASE64: Overflow, source doesn't fit into
                /*              target
                /* 4  CMBASE64: Non-base64 character found in encoded
                /*              data
                /* 5  CMBASE64: Out of memory
                /* 6  CMBASE64: Invalid number of parameters
                /* 7  CMBASE64: Invalid parameter type
                /* 8  CMBASE64: Invalid parameter length
                /* 9  CMBASE64: Invalid function code
                /* 10 CMBASE64: Unkown return code
1 PARM-ERRTXT    (A72)    OPTIONAL
                /* blank, if ok no error
                /* else error text
1 PARM-RFC       (B1)     OPTIONAL
                /* OS only, not used for MF
                /* 0 - RFC3548; 3 - RFC2045; 4 - NATRPC;
SAG64ABP Der Copycode, der die Prototyp-Definition enthält, wird nur bei der Kompilierung benutzt, um den Typ der Rückgabevariablen als Referenz für den Funktionsaufruf zu bestimmen und um die Parameter zu prüfen, falls dies gewünscht wird.

SAG64ABP ist optional.

B64X01 Beispiel-Programm in der Library SYSEXPG.

Verwendet werden die Standardvorgabewerte:

PARM-B := SAG64AB(<PARM-A>)

Alle Parameter, die möglich sind, werden angegeben (PARM-RFC gilt nicht bei Großrechnern):

PARM-B := SAG64AB(<PARM-A,PARM-RC,PARM-ERRTXT,PARM-RFC>)

Beispiel-Programm

Beispiel-Programm B64X01 in der Library SYSEXPG:

** Example 'B64X01': BASE64-A-STR := SAG64BA(<BASE64-B-STR>)             
************************************************************************ 
* Function ......... Convert binary data into printable,                 
*                    network-compatible data or vice versa using         
*                    Base64 encoding.                                    
*                                                                        
*                    Base64 encoding means (B) -> (A) -> (B),            
*                    where 6 (binary) bits will be encoded into 8        
*                    (alpha) bits, e.g a (B3) value will be encoded      
*                    into a (A4) value.                                  
*                                                                        
*                    Note: Every binary value will be encoded into       
*                    a non-ambiguous alpha value. Re-encoding this       
*                    alpha value again will result in the original       
*                    binary value. However, this is not the case with    
*                    most of the (A) -> (B) -> (A) encodings.            
*                                                                        
*                    The encoding may be used to transfer a .bmp         
*                    file via TCP/IP, or to transfer Natural binary or   
*                    integer values via the utility protocol.            
*                                                                        
*                    Open Systems only:                                  
*                    On Open Systems, there are 3 modes:                 
*                    RFC3548, RFC2045 and NATRPC (default).              
*                    NATRPC means the encoding follows                   
*                    the NATRPC logic. This is 100% MF compatible.       
*                    RFC2045 is the default of the CMBASE64 call.        
*                    RFC3548 is like NATRPC, but alpha bytes not         
*                    needed are filled with '='.                         
*                                                                        
DEFINE DATA                                                              
LOCAL                                                                    
1 FUNCTION        (A2)                                                   
                  /* 'AB' Alpha to binary encoding                       
                  /* 'BA' Binary to alpha encoding                       
1 PARM-RC         (I4)                                                   
                  /* 0:    ok                                            
                  /* Mainframe                                           
                  /* 1  Source is not numeric                            
                  /* 2  Source is not packed                             
                  /* 3  Source is not floating point                     
                  /* 4  Overflow, source doesn't fit into target         
                  /* 5  Integer overflow                                 
                  /* 6  Source is not a valid date or time               
                  /* 7  Length error (hex input not even)                
                  /* 8  Target precision is less than source precision   
                  /* 9  Float underflow (result->0)                      
                  /* 10 Alpha source contains non-hex characters         
                  /* 20 Invalid function code                            
                  /* Open Systems                                        
                  /* 1  Invalid value for RFC parameter                  
                  /* 2  Invalid function code                            
                  /* 3  CMBASE64: Overflow, source doesn't fit into      
                  /*              target                                 
                  /* 4  CMBASE64: Non-base64 character found in encoded  
                  /*              data                                   
                  /* 5  CMBASE64: Out of memory                          
                  /* 6  CMBASE64: Inalid number of parameters            
                  /* 7  CMBASE64: Invalid parameter type                 
                  /* 8  CMBASE64: Invalid parameter length               
                  /* 9  CMBASE64: Invalid function code                  
                  /* 10 CMBASE64: Unkown return code                     
1 PARM-ERRTXT     (A72)                                                  
                  /* blank, if ok no error                               
                  /* else error text                                     
1 PARM-A          (A)   DYNAMIC                                          
                  /* Alpha source input/target output                    
1 PARM-B          (B)   DYNAMIC                                          
*                 /* Binary source input/target output                   
1 PARM-RFC        (B1)                                                   
                  /* OS only, not used for MF                            
                  /* 0 - RFC3548; 3 - RFC2045; 4 - NATRPC;               
/*                                                                       
1 #BACKUP-A       (A) DYNAMIC                                            
1 #BACKUP-B       (B) DYNAMIC                                            
END-DEFINE                                                               
/*                                                                       
/*                                                                       
SET KEY ALL                                                              
/*                                                                       
/* Copycode SAG64BAP and SAG64ABP containing the prototype definition    
/* is used at compilation time only in order to determine the type of    
/* the return variable for function call reference and to check the      
/* parameters, if this is desired. SAG64BAP and SAG64ABP are optional.   
INCLUDE SAG64BAP                                                         
INCLUDE SAG64ABP                                                         
/*                                                                       
REPEAT                                                                   
  RESET PARM-A PARM-B                                                    
  REDUCE DYNAMIC PARM-A TO 0                                             
  REDUCE DYNAMIC PARM-B TO 0                                             
  FUNCTION := 'BA'                                                       
  PARM-B := H'0123456789ABCDEF'                                          
  INPUT (AD=MIL IP=OFF CD=NE) WITH TEXT PARM-ERRTXT                      
   // 10T 'Base64 Encoding:' (YEI)                                       
    / 10T '-' (19) (YEI) /                                               
    / 10T 'Function (BA,AB) ..' (TU) FUNCTION (AD=T)                     
    / 10T 'Alpha In/Output ...' (TU) PARM-A (AL=30)                      
    / 10T 'Binary In/Output ..' (TU) PARM-B (EM=HHHHHHHH)                
    / 10T 'Response ..........' (TU) PARM-RC (AD=OD CD=TU)               
    / PARM-ERRTXT (AD=OD CD=TU)                                          
  RESET PARM-ERRTXT                                                      
  IF *PF-KEY NE 'ENTR'                                                   
    ESCAPE BOTTOM                                                        
  END-IF                                                                 
  /*                                                                     
  RESET #BACKUP-A #BACKUP-B                                              
  REDUCE DYNAMIC #BACKUP-A TO 0                                          
  REDUCE DYNAMIC #BACKUP-B TO 0                                          
  #BACKUP-A := PARM-A                                                    
  #BACKUP-B := PARM-B                                                    
  /*                                                                     
  IF FUNCTION = 'BA'                                                     
    /* Parameter PARM-RC, PARM-ERRTXT and PARM-RFC are optional          
    /* Parameter PARM-RFC does not apply to mainframe                    
    /* PARM-A := SAG64BA(<PARM-B,PARM-RC,PARM-ERRTXT,PARM-RFC>)          
    PARM-A := SAG64BA(<PARM-B,PARM-RC,PARM-ERRTXT>)                      
    /* PARM-A := SAG64BA(<PARM-B,PARM-RC>)                               
    /* PARM-A := SAG64BA(<PARM-B>)                                       
  ELSE                                                                   
    /* Parameter PARM-RC, PARM-ERRTXT and PARM-RFC are optional          
    /* Parameter PARM-RFC does not apply to mainframe                    
    /* PARM-B := SAG64AB(<PARM-A,PARM-RC,PARM-ERRTXT,PARM-RFC>)          
    PARM-B := SAG64AB(<PARM-A,PARM-RC,PARM-ERRTXT>)                      
    /* PARM-B := SAG64AB(<PARM-A,PARM-RC>)                               
    /* PARM-B := SAG64AB(<PARM-A>)                                       
  END-IF                                                                 
  /*                                                                     
  IF PARM-RC NE 0 THEN                                                   
    WRITE 'Encoding' FUNCTION                                            
    WRITE NOTITLE PARM-ERRTXT                                            
  ELSE                                                                   
    IF FUNCTION = 'BA' THEN                                              
      WRITE 'Binary -> Alpha'                                            
      WRITE '=' PARM-B (EM=HHHHHHHHHHHHHHHHHHHHHHHHH)                    
        / '=' PARM-A (AL=50)                                             
      RESET PARM-B                                                       
      REDUCE DYNAMIC PARM-B TO 0                                         
      FUNCTION := 'AB'                                                   
    ELSE                                                                 
      WRITE 'Alpha -> Binary'                                            
      WRITE '=' PARM-A (AL=50) /                                         
        '=' PARM-B (EM=HHHHHHHHHHHHHHHHHHHHHHHHH)                        
      RESET PARM-A                                                       
      REDUCE DYNAMIC PARM-A TO 0                                         
      FUNCTION := 'BA'                                                   
    END-IF                                                               
    /*                                                                   
    IF FUNCTION = 'BA'                                                   
      /* Parameter PARM-RC, PARM-ERRTXT and PARM-RFC are optional        
      /* Parameter PARM-RFC does not apply to mainframe                  
      /* PARM-A := SAG64BA(<PARM-B,PARM-RC,PARM-ERRTXT,PARM-RFC>)        
      PARM-A := SAG64BA(<PARM-B,PARM-RC,PARM-ERRTXT>)                    
      /* PARM-A := SAG64BA(<PARM-B,PARM-RC>)                             
      /* PARM-A := SAG64BA(<PARM-B>)                                     
    ELSE                                                                 
      /* Parameter PARM-RC, PARM-ERRTXT and PARM-RFC are optional        
      /* Parameter PARM-RFC does not apply to mainframe                  
      /* PARM-B := SAG64AB(<PARM-A,PARM-RC,PARM-ERRTXT,PARM-RFC>)        
      PARM-B := SAG64AB(<PARM-A,PARM-RC,PARM-ERRTXT>)                    
      /* PARM-B := SAG64AB(<PARM-A,PARM-RC>)                             
      /* PARM-B := SAG64AB(<PARM-A>)                                     
    END-IF                                                               
    IF PARM-RC NE 0 THEN                                                 
      WRITE 'Encoding' FUNCTION                                          
      WRITE NOTITLE PARM-ERRTXT                                          
    ELSE                                                                 
      IF FUNCTION = 'BA' THEN                                            
        WRITE 'Binary -> Alpha'                                          
        WRITE '=' PARM-B (EM=HHHHHHHHHHHHHHHHHHHHHHHHH)                  
          / '=' PARM-A (AL=50)                                           
        IF PARM-A = #BACKUP-A THEN                                       
          WRITE '******** Encoding successful ********'                  
        ELSE                                                             
          WRITE '******** Value changed by encoding ********'            
        END-IF                                                           
      ELSE                                                               
        WRITE 'Alpha -> Binary'                                          
        WRITE '=' PARM-A (AL=50) /                                       
          '=' PARM-B (EM=HHHHHHHHHHHHHHHHHHHHHHHHH)                      
        IF PARM-B = #BACKUP-B THEN                                       
          WRITE '******** Encoding successful ********'                  
        ELSE                                                             
          WRITE '******** Value changed by encoding ********'            
        END-IF                                                           
      END-IF                                                             
    END-IF                                                               
  END-IF                                                                 
END-REPEAT                                                               
END