Changeset 4588:e20a1b790be1 in roaraudio


Ignore:
Timestamp:
11/07/10 01:46:30 (13 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

implemented Base64

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r4585 r4588  
    33        * Updated VS API (Closes: #54, #3) 
    44        * Added support for CRC24 (RFC 4880) 
     5        * Added Base64 support. 
    56 
    67v. 0.4beta1 - Mon Nov 01 2010 16:14 CET 
  • include/libroar/base64.h

    r4587 r4588  
    5656#define roar_base64_init_decode(state,flags) roar_base64_init((state),(flags)) 
    5757 
    58 ssize_t roar_base64_encode(struct roar_base64 * state, void * out, size_t outlen, void * in, size_t inlen, size_t * off, int eof); 
     58ssize_t roar_base64_encode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off, int eof); 
    5959 
    60 ssize_t roar_base64_decode(struct roar_base64 * state, void * out, size_t outlen, void * in, size_t inlen, size_t * off); 
     60ssize_t roar_base64_decode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off); 
    6161 
    6262int roar_base64_is_eof(struct roar_base64 * state); 
  • libroar/base64.c

    r4587 r4588  
    7171 
    7272static inline void _libroar_base64_encode_block(unsigned char out[4], const unsigned char in[3]) { 
     73// printf("in={'%c', '%c', '%c'}\n", in[0], in[1], in[2]); 
    7374 out[0] = _base64_tab_fw[(in[0] >> 2) & 0x3F]; 
    7475 out[1] = _base64_tab_fw[(((in[0] & 0x03) << 4) | (in[1] >> 4)) & 0x3F]; 
     
    7778} 
    7879 
    79 #define _setoff(x) do { if ( off != NULL ) { *off = (x) } } while (0) 
    80  
    81 ssize_t roar_base64_encode(struct roar_base64 * state, void * out, size_t outlen, void * in, size_t inlen, size_t * off, int eof) { 
     80#define _setoff(x) do { if ( off != NULL ) { *off = (x); } } while (0) 
     81 
     82ssize_t roar_base64_encode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off, int eof) { 
    8283 struct roar_base64 state_store; 
    8384 size_t offset = 0; 
    8485 size_t tlen; 
     86 ssize_t ret = 0; 
     87 unsigned char * outp; 
     88 const unsigned char * inp; 
    8589 
    8690 if ( inlen && in == NULL ) 
     
    9498  return -1; 
    9599 
     100 // we can not write anything anyway... 
     101 if ( outlen < 4 ) 
     102  return 0; 
     103 
    96104 if ( state == NULL ) { 
    97105  state = &state_store; 
    98   roar_base64_init_encode(state); 
     106  roar_base64_init_encode(state, ROAR_BASE64_FLAG_NONE); 
    99107  eof = 1; 
    100108 } 
    101109 
    102110 if ( state->buflen ) { 
    103   if ( (state->buflen + inlen) >= 3 ) { 
    104    tlen = 3 - state->buflen; 
    105    memcpy(state->buf + state->buflen, in, tlen); 
     111  tlen = 3 - state->buflen; 
     112  ROAR_DBG("roar_base64_encode(state=%p,...): Still %llu bytes in state", state, (long long unsigned int)state->buflen); 
     113  ROAR_DBG("roar_base64_encode(state=%p,...): Need %llu bytes", state, (long long unsigned int)tlen); 
     114  if ( inlen >= tlen ) { 
     115   memcpy(state->iobuf + state->buflen, in, tlen); 
    106116   offset += tlen; 
    107117   in += tlen; 
    108118   inlen -= tlen; 
     119   _libroar_base64_encode_block(out, state->iobuf); 
     120   out += 4; 
     121   outlen -= 4; 
     122   ret += 4; 
     123   state->buflen = 0; 
    109124  } else { 
    110    memcpy(state->buf + state->buflen, in, inlen); 
     125   memcpy(state->iobuf + state->buflen, in, inlen); 
     126   state->buflen += inlen; 
    111127   _setoff(inlen); 
    112128   return 0; 
    113129  } 
    114130 } 
    115 } 
    116  
    117 ssize_t roar_base64_decode(struct roar_base64 * state, void * out, size_t outlen, void * in, size_t inlen, size_t * off); 
     131 
     132 for (; inlen >= 3 && outlen >= 4;) { 
     133  _libroar_base64_encode_block(out, in); 
     134  ret += 4; 
     135  out += 4; 
     136  in  += 3; 
     137  offset += 3; 
     138  inlen -= 3; 
     139  outlen -= 4; 
     140 } 
     141 
     142 // something left? 
     143 if ( inlen ) { 
     144  if ( eof ) { 
     145   if ( outlen >= 4 ) { 
     146    outp = out; 
     147    inp  = in; 
     148    switch (inlen) { 
     149     case 1: 
     150       outp[0] = _base64_tab_fw[inp[0] >> 2]; 
     151       outp[1] = _base64_tab_fw[(inp[0] & 0x03) << 4]; 
     152       outp[2] = '='; 
     153       outp[3] = '='; 
     154       ret += 4; 
     155       out += 4; 
     156       in  += 1; 
     157       offset += 1; 
     158       inlen  -= 1; 
     159       outlen -= 4; 
     160      break; 
     161     case 2: 
     162       outp[0] = _base64_tab_fw[inp[0] >> 2]; 
     163       outp[1] = _base64_tab_fw[(((inp[0] & 0x03) << 4) | (inp[1] >> 4)) & 0x3F]; 
     164       outp[2] = _base64_tab_fw[(((inp[1] & 0x0F) << 2))                 & 0x3F]; 
     165       outp[3] = '='; 
     166       ret += 4; 
     167       out += 4; 
     168       in  += 2; 
     169       offset += 2; 
     170       inlen  -= 2; 
     171       outlen -= 4; 
     172      break; 
     173    } 
     174   } 
     175  } else { 
     176   memcpy(state->iobuf, in, inlen); 
     177   state->buflen = inlen; 
     178   offset += inlen; 
     179   in += inlen; 
     180   inlen -= inlen; 
     181  } 
     182 } 
     183 
     184 if ( outlen ) { 
     185  *(char*)out = 0; 
     186 } 
     187 
     188 _setoff(offset); 
     189 
     190 return 0; 
     191} 
     192 
     193ssize_t roar_base64_decode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off) { 
     194 struct roar_base64 state_store; 
     195 ssize_t ret = 0; 
     196 unsigned char c; 
     197 int bits; 
     198 const unsigned char * inp = in; 
     199 unsigned char * outp = out; 
     200 size_t offset = 0; 
     201 
     202 if ( inlen && in == NULL ) 
     203  return -1; 
     204 
     205 if ( outlen && out == NULL ) 
     206  return -1; 
     207 
     208 // this test should be removed as soon as those modes are supported. 
     209 if ( in == NULL || out == NULL ) 
     210  return -1; 
     211 
     212 if ( state == NULL ) { 
     213  state = &state_store; 
     214  roar_base64_init_encode(state, ROAR_BASE64_FLAG_NONE); 
     215 } 
     216 
     217 if ( state->reglen >= 8 ) { 
     218  *outp  = (state->reg >> (state->reglen - 8)) & 0xFF; 
     219  state->reglen -= 8; 
     220  outp++; 
     221  outlen--; 
     222  ret++; 
     223 } 
     224 
     225 if ( state->flags & ROAR_BASE64_FLAG_EOF ) { 
     226  if ( outlen ) { 
     227   *outp = 0; 
     228  } 
     229  return ret; 
     230 } 
     231 
     232 //printf("state->reglen=%i\n", (int)state->reglen); 
     233 
     234 for (; inlen && outlen; ) { 
     235  c = *inp; 
     236  inp++; 
     237  inlen--; 
     238  offset++; 
     239 
     240  if ( c == '=' ) { 
     241   bits = 0; 
     242  } else { 
     243   // hi-bit set chars need to be ignored. 
     244   if ( (size_t)c > sizeof(_base64_tab_bw) ) 
     245    continue; 
     246 
     247   bits = _base64_tab_bw[c]; 
     248 
     249   // ignore unknown chars. 
     250   if ( bits == (char)0xFF ) 
     251    continue; 
     252  } 
     253 
     254  state->reg   <<= 6; 
     255  state->reg    |= bits; 
     256  state->reglen += 6; 
     257 
     258  if ( state->reglen >= 8 ) { 
     259   *outp  = (state->reg >> (state->reglen - 8)) & 0xFF; 
     260   state->reglen -= 8; 
     261   outp++; 
     262   outlen--; 
     263   ret++; 
     264  } 
     265 
     266  if ( c == '=' ) { 
     267   state->flags |= ROAR_BASE64_FLAG_EOF; 
     268   if ( state->reglen <= 6 ) { 
     269    state->reglen = 0; 
     270   } 
     271   if ( inlen ) { 
     272    if ( *inp == '=' ) { 
     273     offset++; 
     274    } 
     275   } 
     276   break; 
     277  } 
     278 } 
     279 
     280 if ( off != NULL ) { 
     281  *off = offset; 
     282 } 
     283 
     284 if ( outlen ) { 
     285  *outp = 0; 
     286 } 
     287 
     288 return ret; 
     289} 
    118290 
    119291int roar_base64_is_eof(struct roar_base64 * state) { 
     
    121293  return -1; 
    122294 
     295 if ( state->reglen >= 8 ) 
     296  return 0; 
     297 
    123298 return !!(state->flags & ROAR_BASE64_FLAG_EOF); 
    124299} 
     
    129304 
    130305 if ( state->buflen ) { 
    131   ROAR_WARN("roar_base64_uninit(state=%p): State has bytes left in IO buffer. This is a application error."); 
     306  ROAR_WARN("roar_base64_uninit(state=%p): State has %i bytes left in IO buffer. This is a application error.", state, state->buflen); 
    132307 } 
    133308 
    134309 if ( state->reglen ) { 
    135   ROAR_WARN("roar_base64_uninit(state=%p): State has bits left in decode register. This is a application error."); 
     310  ROAR_WARN("roar_base64_uninit(state=%p): State has %i bits left in decode register. This is a application error.", state, state->reglen); 
    136311 } 
    137312 
Note: See TracChangeset for help on using the changeset viewer.