...

Source file src/github.com/chenzhuoyu/base64x/base64x.go

Documentation: github.com/chenzhuoyu/base64x

     1  package base64x
     2  
     3  import (
     4      `encoding/base64`
     5  )
     6  
     7  // An Encoding is a radix 64 encoding/decoding scheme, defined by a
     8  // 64-character alphabet. The most common encoding is the "base64"
     9  // encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
    10  // (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
    11  // the standard encoding with - and _ substituted for + and /.
    12  type Encoding int
    13  
    14  const (
    15      _MODE_URL  = 1 << 0
    16      _MODE_RAW  = 1 << 1
    17      _MODE_AVX2 = 1 << 2
    18      _MODE_JSON = 1 << 3
    19  )
    20  
    21  // StdEncoding is the standard base64 encoding, as defined in
    22  // RFC 4648.
    23  const StdEncoding Encoding = 0
    24  
    25  // URLEncoding is the alternate base64 encoding defined in RFC 4648.
    26  // It is typically used in URLs and file names.
    27  const URLEncoding Encoding = _MODE_URL
    28  
    29  // RawStdEncoding is the standard raw, unpadded base64 encoding,
    30  // as defined in RFC 4648 section 3.2.
    31  //
    32  // This is the same as StdEncoding but omits padding characters.
    33  const RawStdEncoding Encoding = _MODE_RAW
    34  
    35  // RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
    36  // It is typically used in URLs and file names.
    37  //
    38  // This is the same as URLEncoding but omits padding characters.
    39  const RawURLEncoding Encoding = _MODE_RAW | _MODE_URL
    40  
    41  // JSONStdEncoding is the StdEncoding and encoded as JSON string as RFC 8259.
    42  const JSONStdEncoding Encoding = _MODE_JSON;
    43  
    44  var (
    45      archFlags = 0
    46  )
    47  
    48  /** Encoder Functions **/
    49  
    50  // Encode encodes src using the specified encoding, writing
    51  // EncodedLen(len(src)) bytes to out.
    52  //
    53  // The encoding pads the output to a multiple of 4 bytes,
    54  // so Encode is not appropriate for use on individual blocks
    55  // of a large data stream.
    56  //
    57  // If out is not large enough to contain the encoded result,
    58  // it will panic.
    59  func (self Encoding) Encode(out []byte, src []byte) {
    60      if len(src) != 0 {
    61          if buf := out[:0:len(out)]; self.EncodedLen(len(src)) <= len(out) {
    62              self.EncodeUnsafe(&buf, src)
    63          } else {
    64              panic("encoder output buffer is too small")
    65          }
    66      }
    67  }
    68  
    69  // EncodeUnsafe behaves like Encode, except it does NOT check if
    70  // out is large enough to contain the encoded result.
    71  //
    72  // It will also update the length of out.
    73  func (self Encoding) EncodeUnsafe(out *[]byte, src []byte) {
    74      b64encode(out, &src, int(self) | archFlags)
    75  }
    76  
    77  // EncodeToString returns the base64 encoding of src.
    78  func (self Encoding) EncodeToString(src []byte) string {
    79      nbs := len(src)
    80      ret := make([]byte, 0, self.EncodedLen(nbs))
    81  
    82      /* encode in native code */
    83      self.EncodeUnsafe(&ret, src)
    84      return mem2str(ret)
    85  }
    86  
    87  // EncodedLen returns the length in bytes of the base64 encoding
    88  // of an input buffer of length n.
    89  func (self Encoding) EncodedLen(n int) int {
    90      if (self & _MODE_RAW) == 0 {
    91          return (n + 2) / 3 * 4
    92      } else {
    93          return (n * 8 + 5) / 6
    94      }
    95  }
    96  
    97  /** Decoder Functions **/
    98  
    99  // Decode decodes src using the encoding enc. It writes at most
   100  // DecodedLen(len(src)) bytes to out and returns the number of bytes
   101  // written. If src contains invalid base64 data, it will return the
   102  // number of bytes successfully written and base64.CorruptInputError.
   103  //
   104  // New line characters (\r and \n) are ignored.
   105  //
   106  // If out is not large enough to contain the encoded result,
   107  // it will panic.
   108  func (self Encoding) Decode(out []byte, src []byte) (int, error) {
   109      if len(src) == 0 {
   110          return 0, nil
   111      } else if buf := out[:0:len(out)]; self.DecodedLen(len(src)) <= len(out) {
   112          return self.DecodeUnsafe(&buf, src)
   113      } else {
   114          panic("decoder output buffer is too small")
   115      }
   116  }
   117  
   118  // DecodeUnsafe behaves like Decode, except it does NOT check if
   119  // out is large enough to contain the decoded result.
   120  //
   121  // It will also update the length of out.
   122  func (self Encoding) DecodeUnsafe(out *[]byte, src []byte) (int, error) {
   123      if n := b64decode(out, mem2addr(src), len(src), int(self) | archFlags); n >= 0 {
   124          return n, nil
   125      } else {
   126          return 0, base64.CorruptInputError(-n - 1)
   127      }
   128  }
   129  
   130  // DecodeString returns the bytes represented by the base64 string s.
   131  func (self Encoding) DecodeString(s string) ([]byte, error) {
   132      src := str2mem(s)
   133      ret := make([]byte, 0, self.DecodedLen(len(s)))
   134  
   135      /* decode into the allocated buffer */
   136      if _, err := self.DecodeUnsafe(&ret, src); err != nil {
   137          return nil, err
   138      } else {
   139          return ret, nil
   140      }
   141  }
   142  
   143  // DecodedLen returns the maximum length in bytes of the decoded data
   144  // corresponding to n bytes of base64-encoded data.
   145  func (self Encoding) DecodedLen(n int) int {
   146      if (self & _MODE_RAW) == 0 {
   147          return n / 4 * 3
   148      } else {
   149          return n * 6 / 8
   150      }
   151  }
   152  

View as plain text