github.com/cristalhq/base64@v0.1.2/encoder.go (about)

     1  package base64
     2  
     3  import "unsafe"
     4  
     5  //go:nosplit
     6  func (e *Encoding) encode(dst []byte, src []byte, outlen uintptr) {
     7  	inlen := len(src)
     8  	ip := (*sliceHeader)(unsafe.Pointer(&src)).data
     9  	ipstart := ip
    10  	op := (*sliceHeader)(unsafe.Pointer(&dst)).data
    11  	opstart := op
    12  	if outlen >= 8+12 {
    13  		u0x := bswap32(ip)
    14  		u1x := bswap32(ip + 3)
    15  		for op <= (opstart+outlen)-(128+12) {
    16  			{
    17  				_u0, _u1 := u0x, u1x
    18  				u0x = bswap32(ip + 6 + 0*6)
    19  				u1x = bswap32(ip + 6 + 0*6 + 3)
    20  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    21  				stou32(op+0*8, _u0)
    22  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    23  				stou32(op+0*8+4, _u1)
    24  			}
    25  			{
    26  				_u0, _u1 := u0x, u1x
    27  				u0x = bswap32(ip + 6 + 1*6)
    28  				u1x = bswap32(ip + 6 + 1*6 + 3)
    29  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    30  				stou32(op+1*8, _u0)
    31  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    32  				stou32(op+1*8+4, _u1)
    33  			}
    34  			{
    35  				_u0, _u1 := u0x, u1x
    36  				u0x = bswap32(ip + 6 + 2*6)
    37  				u1x = bswap32(ip + 6 + 2*6 + 3)
    38  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    39  				stou32(op+2*8, _u0)
    40  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    41  				stou32(op+2*8+4, _u1)
    42  			}
    43  			{
    44  				_u0, _u1 := u0x, u1x
    45  				u0x = bswap32(ip + 6 + 3*6)
    46  				u1x = bswap32(ip + 6 + 3*6 + 3)
    47  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    48  				stou32(op+3*8, _u0)
    49  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    50  				stou32(op+3*8+4, _u1)
    51  			}
    52  			{
    53  				_u0, _u1 := u0x, u1x
    54  				u0x = bswap32(ip + 6 + 4*6)
    55  				u1x = bswap32(ip + 6 + 4*6 + 3)
    56  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    57  				stou32(op+4*8, _u0)
    58  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    59  				stou32(op+4*8+4, _u1)
    60  			}
    61  			{
    62  				_u0, _u1 := u0x, u1x
    63  				u0x = bswap32(ip + 6 + 5*6)
    64  				u1x = bswap32(ip + 6 + 5*6 + 3)
    65  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    66  				stou32(op+5*8, _u0)
    67  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    68  				stou32(op+5*8+4, _u1)
    69  			}
    70  			{
    71  				_u0, _u1 := u0x, u1x
    72  				u0x = bswap32(ip + 6 + 6*6)
    73  				u1x = bswap32(ip + 6 + 6*6 + 3)
    74  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    75  				stou32(op+6*8, _u0)
    76  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    77  				stou32(op+6*8+4, _u1)
    78  			}
    79  			{
    80  				_u0, _u1 := u0x, u1x
    81  				u0x = bswap32(ip + 6 + 7*6)
    82  				u1x = bswap32(ip + 6 + 7*6 + 3)
    83  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    84  				stou32(op+7*8, _u0)
    85  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    86  				stou32(op+7*8+4, _u1)
    87  			}
    88  			{
    89  				_u0, _u1 := u0x, u1x
    90  				u0x = bswap32(ip + 6 + 8*6)
    91  				u1x = bswap32(ip + 6 + 8*6 + 3)
    92  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
    93  				stou32(op+8*8, _u0)
    94  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
    95  				stou32(op+8*8+4, _u1)
    96  			}
    97  			{
    98  				_u0, _u1 := u0x, u1x
    99  				u0x = bswap32(ip + 6 + 9*6)
   100  				u1x = bswap32(ip + 6 + 9*6 + 3)
   101  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   102  				stou32(op+9*8, _u0)
   103  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   104  				stou32(op+9*8+4, _u1)
   105  			}
   106  			{
   107  				_u0, _u1 := u0x, u1x
   108  				u0x = bswap32(ip + 6 + 10*6)
   109  				u1x = bswap32(ip + 6 + 10*6 + 3)
   110  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   111  				stou32(op+10*8, _u0)
   112  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   113  				stou32(op+10*8+4, _u1)
   114  			}
   115  			{
   116  				_u0, _u1 := u0x, u1x
   117  				u0x = bswap32(ip + 6 + 11*6)
   118  				u1x = bswap32(ip + 6 + 11*6 + 3)
   119  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   120  				stou32(op+11*8, _u0)
   121  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   122  				stou32(op+11*8+4, _u1)
   123  			}
   124  			{
   125  				_u0, _u1 := u0x, u1x
   126  				u0x = bswap32(ip + 6 + 12*6)
   127  				u1x = bswap32(ip + 6 + 12*6 + 3)
   128  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   129  				stou32(op+12*8, _u0)
   130  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   131  				stou32(op+12*8+4, _u1)
   132  			}
   133  			{
   134  				_u0, _u1 := u0x, u1x
   135  				u0x = bswap32(ip + 6 + 13*6)
   136  				u1x = bswap32(ip + 6 + 13*6 + 3)
   137  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   138  				stou32(op+13*8, _u0)
   139  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   140  				stou32(op+13*8+4, _u1)
   141  			}
   142  			{
   143  				_u0, _u1 := u0x, u1x
   144  				u0x = bswap32(ip + 6 + 14*6)
   145  				u1x = bswap32(ip + 6 + 14*6 + 3)
   146  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   147  				stou32(op+14*8, _u0)
   148  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   149  				stou32(op+14*8+4, _u1)
   150  			}
   151  			{
   152  				_u0, _u1 := u0x, u1x
   153  				u0x = bswap32(ip + 6 + 15*6)
   154  				u1x = bswap32(ip + 6 + 15*6 + 3)
   155  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   156  				stou32(op+15*8, _u0)
   157  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   158  				stou32(op+15*8+4, _u1)
   159  			}
   160  			op += 128
   161  			ip += (128 / 4) * 3
   162  		}
   163  		for op <= (opstart+outlen)-(16+12) {
   164  			{
   165  				_u0, _u1 := u0x, u1x
   166  				u0x = bswap32(ip + 6 + 0*6)
   167  				u1x = bswap32(ip + 6 + 0*6 + 3)
   168  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   169  				stou32(op+0*8, _u0)
   170  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   171  				stou32(op+0*8+4, _u1)
   172  			}
   173  			{
   174  				_u0, _u1 := u0x, u1x
   175  				u0x = bswap32(ip + 6 + 1*6)
   176  				u1x = bswap32(ip + 6 + 1*6 + 3)
   177  				_u0 = e.lutXe[(_u0>>8)&0xfff]<<16 | e.lutXe[_u0>>20]
   178  				stou32(op+1*8, _u0)
   179  				_u1 = e.lutXe[(_u1>>8)&0xfff]<<16 | e.lutXe[_u1>>20]
   180  				stou32(op+1*8+4, _u1)
   181  			}
   182  			op += 16
   183  			ip += (16 / 4) * 3
   184  		}
   185  		if op <= (opstart+outlen)-(8+12) {
   186  			_u0 := e.lutXe[(u0x>>8)&0xfff]<<16 | e.lutXe[u0x>>20]
   187  			stou32(op+0*8, _u0)
   188  			_u1 := e.lutXe[(u1x>>8)&0xfff]<<16 | e.lutXe[u1x>>20]
   189  			stou32(op+0*8+4, _u1)
   190  			op += 8
   191  			ip += (8 / 4) * 3
   192  		}
   193  	}
   194  	for op < (opstart+outlen)-4 {
   195  		_u := bswap32(ip)
   196  		stou32(op, e.lutXe[(_u>>8)&0xfff]<<16|e.lutXe[_u>>20])
   197  		op += 4
   198  		ip += 3
   199  	}
   200  	_l := uint32((ipstart + uintptr(inlen)) - ip)
   201  	if _l == 3 {
   202  		_u := uint32(*(*byte)(unsafe.Pointer(ip + 0)))<<24 | uint32(*(*byte)(unsafe.Pointer(ip + 1)))<<16 | uint32(*(*byte)(unsafe.Pointer(ip + 2)))<<8
   203  		stou32(op, uint32(e.lutSe[(_u>>8)&0x3f])<<24|uint32(e.lutSe[(_u>>14)&0x3f])<<16|uint32(e.lutSe[(_u>>20)&0x3f])<<8|uint32(e.lutSe[(_u>>26)&0x3f]))
   204  	} else if _l != 0 {
   205  		*(*byte)(unsafe.Pointer(op)) = e.lutSe[(*(*byte)(unsafe.Pointer(ip + 0))>>2)&0x3f]
   206  		op++
   207  		if _l == 2 {
   208  			*(*byte)(unsafe.Pointer(op)) = e.lutSe[(*(*byte)(unsafe.Pointer(ip + 0))&0x3)<<4|(*(*byte)(unsafe.Pointer(ip + 1))&0xf0)>>4]
   209  			op++
   210  			*(*byte)(unsafe.Pointer(op)) = e.lutSe[(*(*byte)(unsafe.Pointer(ip + 1))&0xf)<<2]
   211  			op++
   212  		} else {
   213  			*(*byte)(unsafe.Pointer(op)) = e.lutSe[(*(*byte)(unsafe.Pointer(ip + 0))&0x3)<<4]
   214  			op++
   215  			if e.pad {
   216  				*(*byte)(unsafe.Pointer(op)) = '='
   217  				op++
   218  			}
   219  		}
   220  		if e.pad {
   221  			*(*byte)(unsafe.Pointer(op)) = '='
   222  		}
   223  	}
   224  }