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 }