Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

niml_b64.c

Go to the documentation of this file.
00001 #include "niml_private.h"
00002 
00003 /*************************************************************************/
00004 /************************ Functions for Base64 ***************************/
00005 /** [Most are not actually used in NIML, but are here for completeness] **/
00006 /*************************************************************************/
00007 
00008 int  dtable_mode = -1 ;    /* 1=encode, 2=decode, -1=neither */
00009 byte dtable[256] ;         /* encode/decode table */
00010 int  linelen = 72 ;        /* line length (max 76) */
00011 int  ncrlf   = 1 ;
00012 int  nocrlf  = 0 ;         /* disable CR LF output? */
00013 
00014 /*----------------------------------------------------------------------*/
00015 /*! Set the number of characters to use for end of line:
00016     1 = Unix standard (LF only); 2 = DOS standard (CR LF).
00017 ------------------------------------------------------------------------*/
00018 
00019 void B64_set_crlf( int nn )
00020 {
00021    if( nn >= 1 && nn <= 2 ) ncrlf  = nn ;
00022    else                     nocrlf = !nocrlf ;
00023    return ;
00024 }
00025 
00026 /*----------------------------------------------------------------------*/
00027 /*! Set the length of a line of output in base64; ll should be
00028     between 16 and 76 (inclusive). Will round down to a multiple of 4.
00029 ------------------------------------------------------------------------*/
00030 
00031 void B64_set_linelen( int ll )
00032 {
00033    if( ll >= 16 && ll <= 76 ) linelen = 4*(ll/4) ; /* multiple of 4 */
00034    else                       linelen = 72 ;       /* default */
00035    return ;
00036 }
00037 
00038 /*----------------------------------------------------------------------*/
00039 /*! Load the base64 encoding table.
00040 ------------------------------------------------------------------------*/
00041 
00042 void load_encode_table(void)
00043 {
00044     int i ;
00045     if( dtable_mode == 1 ) return ;
00046     for (i = 0; i < 26; i++) {
00047         dtable[i] = 'A' + i;
00048         dtable[26 + i] = 'a' + i;
00049     }
00050     for (i = 0; i < 10; i++) dtable[52 + i] = '0' + i;
00051     dtable[62] = '+'; dtable[63] = '/'; dtable_mode = 1 ;
00052     return ;
00053 }
00054 
00055 /*----------------------------------------------------------------------*/
00056 /*! Load the base64 decoding table.
00057 ------------------------------------------------------------------------*/
00058 
00059 void load_decode_table(void)
00060 {
00061     int i;
00062     if( dtable_mode == 2 ) return ;
00063     for (i = 0  ; i < 255 ; i++) dtable[i] = 0x80;             /* bad */
00064     for (i = 'A'; i <= 'Z'; i++) dtable[i] =  0 + (i - 'A');
00065     for (i = 'a'; i <= 'z'; i++) dtable[i] = 26 + (i - 'a');
00066     for (i = '0'; i <= '9'; i++) dtable[i] = 52 + (i - '0');
00067     dtable['+'] = 62; dtable['/'] = 63; dtable['='] = 0; dtable_mode = 2 ;
00068     return ;
00069 }
00070 
00071 /*----------------------------------------------------------------------*/
00072 /*! Convert base64-encoded array to a binary array (decoding).
00073 
00074    Inputs:
00075     - nb64 = number of bytes in b64
00076     - b64  = array of base64 encoding bytes
00077              - values not in the base64 encoding set will be skipped
00078 
00079    Outputs:
00080     - *nbin = number of binary bytes [*nbin==0 flags an error]
00081     -  *bin = pointer to newly malloc()-ed space with bytes
00082 
00083    Example:
00084      -  byte *b64 , *bin ;
00085      -  int  nb64 , nbin=0 ;
00086      -  **load b64 and nb64 somehow**
00087      -  B64_to_binary( nb64,b64 , &nbin, &bin ) ;
00088      -  if( nbin == 0 ){ **failure** }
00089      -  else           { **bin[0..nbin-1] is decoded data** }
00090 ------------------------------------------------------------------------*/
00091 
00092 void B64_to_binary( int nb64 , byte *b64 , int *nbin , byte **bin )
00093 {
00094    int ii,jj , nn ;
00095    byte a,b,c , w,x,y,z ;
00096 
00097    /*- sanity checks -*/
00098 
00099    if( nbin == NULL || bin == NULL ) return ;
00100 
00101    if( nb64 < 4 || b64 == NULL ){ *nbin = 0 ; *bin = NULL ; return ; }
00102 
00103    *bin = (byte *) malloc(sizeof(byte)*(2+3*nb64/4)) ;
00104    if( *bin == NULL ){ *nbin = 0 ; return ; }
00105 
00106    /*- some work -*/
00107 
00108    load_decode_table() ;
00109    for( ii=jj=0 ; ii < nb64 ; ){  /* scan inputs, skipping bad characters */
00110 
00111       /* get next 4 characters (use '=' if we hit the end early) */
00112 
00113       w = b64[ii++] ;
00114       while( !B64_goodchar(w) && ii < nb64 ) w = b64[ii++] ;
00115       x = (ii < nb64) ? b64[ii++] : '=' ;
00116       while( !B64_goodchar(x) && ii < nb64 ) x = b64[ii++] ;
00117       y = (ii < nb64) ? b64[ii++] : '=' ;
00118       while( !B64_goodchar(y) && ii < nb64 ) y = b64[ii++] ;
00119       z = (ii < nb64) ? b64[ii++] : '=' ;
00120       while( !B64_goodchar(z) && ii < nb64 ) z = b64[ii++] ;
00121 
00122       B64_decode4(w,x,y,z,a,b,c) ;           /* decode 4 bytes into 3 */
00123 
00124       if( z == '=' ){                        /* got to the end? */
00125          nn = B64_decode_count(w,x,y,z) ;    /* see how many to save */
00126          if( nn > 0 ) (*bin)[jj++] = a ;
00127          if( nn > 1 ) (*bin)[jj++] = b ;
00128          break ;                             /* end of decoding loop */
00129       }
00130 
00131       /* not at the end => save all 3 outputs, loop back */
00132 
00133       (*bin)[jj++] = a ; (*bin)[jj++] = b ; (*bin)[jj++] = c ;
00134    }
00135 
00136    /* resize output array to be exact fit */
00137 
00138    *bin  = (byte *) realloc( *bin , sizeof(byte)*jj ) ;
00139    *nbin = jj ;
00140    return ;
00141 }
00142 
00143 /*----------------------------------------------------------------------*/
00144 /*! Convert binary array to base64 encoding.
00145 
00146    Inputs: nbin = number of bytes in bin
00147             bin = array of binary bytes to encode
00148 
00149    Outputs: *nb64 = number of base64 bytes [*nb64==0 flags an error]
00150              *b64 = pointer to newly malloc()-ed space with bytes
00151 
00152    The output array (*b64) line length can be set by
00153       B64_set_linelen(n)
00154    where n is from 16 to 76.  The default is 72.  Note, however, that
00155    encoded bytes will always be written out in groups of 4.
00156    The output array line separator can be the LF character only (Unix)
00157    or the CR-LF combination (DOS, etc.).  This is controlled by
00158       B64_set_crlf(n)
00159    where n=1 for LF, n=2 for CR LF.  The default is LF.  The output
00160    array will be terminated with a line separator.  If you call
00161       B64_set_crlf(0)
00162    then this will toggle the use of line separators.
00163 
00164    There will be no ASCII NUL character at the end of *b64 -- that is,
00165    the output is not a C string.
00166 
00167    Example:
00168      -  byte *b64 , *bin ;
00169      -  int  nb64=0 , nbin ;
00170      -  **load bin and nbin somehow**
00171      -  B64_to_base64( nbin,bin , &nb64,&b64 ) ;
00172      -  if( nb64 == 0 ){ **failure** }
00173      -  else           { **b64[0..nb64-1] is encoded data**
00174                          printf("%.*s\n",nb64,b64) ;       }
00175 ------------------------------------------------------------------------*/
00176 
00177 void B64_to_base64( int nbin , byte *bin , int *nb64 , byte **b64 )
00178 {
00179    int ii,jj , nn,n3 ;
00180    byte a,b,c , w,x,y,z ;
00181 
00182    /*- sanity checks -*/
00183 
00184    if( nb64 == NULL || b64 == NULL ) return ;
00185    if( nbin <= 0    || bin == NULL ){ *nb64 = 0 ; *b64 = NULL ; return ; }
00186 
00187    /* calculate size of output (3 bytes in -> 4 bytes out, plus EOL */
00188 
00189    nn   = (int)((4.0*(linelen+ncrlf+1.0)/(3.0*linelen))*nbin + 256.0) ;
00190    *b64 = (byte *) malloc(sizeof(byte)*nn) ;
00191    if( *b64 == NULL ){ *nb64 = 0 ; return ; }  /* this is bad */
00192 
00193    /*- do blocks of 3 bytes in -*/
00194 
00195    load_encode_table() ;
00196    n3 = (nbin/3)*3 ;
00197    for( nn=jj=ii=0 ; ii < n3 ; ){
00198 
00199       /* encode next 3 bytes to 4 outputs */
00200 
00201       a = bin[ii++] ; b = bin[ii++] ; c = bin[ii++] ;
00202       B64_encode3(a,b,c,w,x,y,z) ;
00203       (*b64)[jj++] = w ;
00204       (*b64)[jj++] = x ;
00205       (*b64)[jj++] = y ;
00206       (*b64)[jj++] = z ;
00207 
00208       /* if we past the line length, add the EOL stuff */
00209 
00210       if( !nocrlf ){
00211         nn += 4 ; if( nn >= linelen ){
00212                      if( ncrlf == 2 ) (*b64)[jj++] = B64_EOL1 ;
00213                      (*b64)[jj++] = B64_EOL2 ;
00214                      nn = 0 ;
00215                   }
00216       }
00217    }
00218 
00219    /*- do the leftover data, if any (1 or 2 bytes) -*/
00220 
00221    if( ii < nbin ){
00222       if( ii == nbin-2 )
00223          B64_encode2(bin[ii],bin[ii+1],w,x,y,z) ;
00224       else
00225          B64_encode1(bin[ii],w,x,y,z) ;
00226 
00227       (*b64)[jj++] = w ;
00228       (*b64)[jj++] = x ;
00229       (*b64)[jj++] = y ;
00230       (*b64)[jj++] = z ; nn += 4 ;
00231    }
00232 
00233    /* if any output bytes are left, add EOL */
00234 
00235    if( nn > 0 && !nocrlf ){
00236       if( ncrlf == 2 ) (*b64)[jj++] = B64_EOL1 ;
00237       (*b64)[jj++] = B64_EOL2 ;
00238    }
00239 
00240    /* resize output array to be exact fit */
00241 
00242    *b64  = (byte *) realloc( *b64 , sizeof(byte)*jj ) ;
00243    *nb64 = jj ;
00244    return ;
00245 }
 

Powered by Plone

This site conforms to the following standards: