github.com/cristalhq/base64@v0.1.2/decoder.go (about) 1 package base64 2 3 import "unsafe" 4 5 //go:nosplit 6 func (e *Encoding) decode(dst []byte, src []byte) int { 7 dstlen := uintptr(len(dst)) 8 srclen := uintptr(len(src)) 9 if srclen == 0 || (e.pad && (srclen&3) != 0) { 10 return 0 11 } 12 ip := (*sliceHeader)(unsafe.Pointer(&src)).data 13 ipstart := ip 14 op := (*sliceHeader)(unsafe.Pointer(&dst)).data 15 opstart := op 16 var cu uint32 17 if srclen >= 8+4 { 18 ux := ctou32(ip) 19 vx := ctou32(ip + 4) 20 for ip < (ipstart+srclen)-(128+4) { 21 { 22 _u := ux 23 ux = ctou32(ip + 8 + 0*8) 24 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 25 cu |= _u 26 stou32(op+0*6, _u) 27 _v := vx 28 vx = ctou32(ip + 8 + 0*8 + 4) 29 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 30 cu |= _v 31 stou32(op+0*6+3, _v) 32 } 33 { 34 _u := ux 35 ux = ctou32(ip + 8 + 1*8) 36 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 37 cu |= _u 38 stou32(op+1*6, _u) 39 _v := vx 40 vx = ctou32(ip + 8 + 1*8 + 4) 41 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 42 cu |= _v 43 stou32(op+1*6+3, _v) 44 } 45 { 46 _u := ux 47 ux = ctou32(ip + 8 + 2*8) 48 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 49 cu |= _u 50 stou32(op+2*6, _u) 51 _v := vx 52 vx = ctou32(ip + 8 + 2*8 + 4) 53 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 54 cu |= _v 55 stou32(op+2*6+3, _v) 56 } 57 { 58 _u := ux 59 ux = ctou32(ip + 8 + 3*8) 60 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 61 cu |= _u 62 stou32(op+3*6, _u) 63 _v := vx 64 vx = ctou32(ip + 8 + 3*8 + 4) 65 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 66 cu |= _v 67 stou32(op+3*6+3, _v) 68 } 69 { 70 _u := ux 71 ux = ctou32(ip + 8 + 4*8) 72 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 73 cu |= _u 74 stou32(op+4*6, _u) 75 _v := vx 76 vx = ctou32(ip + 8 + 4*8 + 4) 77 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 78 cu |= _v 79 stou32(op+4*6+3, _v) 80 } 81 { 82 _u := ux 83 ux = ctou32(ip + 8 + 5*8) 84 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 85 cu |= _u 86 stou32(op+5*6, _u) 87 _v := vx 88 vx = ctou32(ip + 8 + 5*8 + 4) 89 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 90 cu |= _v 91 stou32(op+5*6+3, _v) 92 } 93 { 94 _u := ux 95 ux = ctou32(ip + 8 + 6*8) 96 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 97 cu |= _u 98 stou32(op+6*6, _u) 99 _v := vx 100 vx = ctou32(ip + 8 + 6*8 + 4) 101 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 102 cu |= _v 103 stou32(op+6*6+3, _v) 104 } 105 { 106 _u := ux 107 ux = ctou32(ip + 8 + 7*8) 108 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 109 cu |= _u 110 stou32(op+7*6, _u) 111 _v := vx 112 vx = ctou32(ip + 8 + 7*8 + 4) 113 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 114 cu |= _v 115 stou32(op+7*6+3, _v) 116 } 117 118 { 119 _u := ux 120 ux = ctou32(ip + 8 + 8*8) 121 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 122 cu |= _u 123 stou32(op+8*6, _u) 124 _v := vx 125 vx = ctou32(ip + 8 + 8*8 + 4) 126 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 127 cu |= _v 128 stou32(op+8*6+3, _v) 129 } 130 { 131 _u := ux 132 ux = ctou32(ip + 8 + 9*8) 133 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 134 cu |= _u 135 stou32(op+9*6, _u) 136 _v := vx 137 vx = ctou32(ip + 8 + 9*8 + 4) 138 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 139 cu |= _v 140 stou32(op+9*6+3, _v) 141 } 142 { 143 _u := ux 144 ux = ctou32(ip + 8 + 10*8) 145 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 146 cu |= _u 147 stou32(op+10*6, _u) 148 _v := vx 149 vx = ctou32(ip + 8 + 10*8 + 4) 150 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 151 cu |= _v 152 stou32(op+10*6+3, _v) 153 } 154 { 155 _u := ux 156 ux = ctou32(ip + 8 + 11*8) 157 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 158 cu |= _u 159 stou32(op+11*6, _u) 160 _v := vx 161 vx = ctou32(ip + 8 + 11*8 + 4) 162 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 163 cu |= _v 164 stou32(op+11*6+3, _v) 165 } 166 { 167 _u := ux 168 ux = ctou32(ip + 8 + 12*8) 169 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 170 cu |= _u 171 stou32(op+12*6, _u) 172 _v := vx 173 vx = ctou32(ip + 8 + 12*8 + 4) 174 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 175 cu |= _v 176 stou32(op+12*6+3, _v) 177 } 178 { 179 _u := ux 180 ux = ctou32(ip + 8 + 13*8) 181 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 182 cu |= _u 183 stou32(op+13*6, _u) 184 _v := vx 185 vx = ctou32(ip + 8 + 13*8 + 4) 186 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 187 cu |= _v 188 stou32(op+13*6+3, _v) 189 } 190 { 191 _u := ux 192 ux = ctou32(ip + 8 + 14*8) 193 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 194 cu |= _u 195 stou32(op+14*6, _u) 196 _v := vx 197 vx = ctou32(ip + 8 + 14*8 + 4) 198 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 199 cu |= _v 200 stou32(op+14*6+3, _v) 201 } 202 { 203 _u := ux 204 ux = ctou32(ip + 8 + 15*8) 205 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 206 cu |= _u 207 stou32(op+15*6, _u) 208 _v := vx 209 vx = ctou32(ip + 8 + 15*8 + 4) 210 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 211 cu |= _v 212 stou32(op+15*6+3, _v) 213 } 214 ip += 128 215 op += (128 / 4) * 3 216 } 217 for ip < (ipstart+srclen)-(16+4) { 218 { 219 _u := ux 220 ux = ctou32(ip + 8 + 0*8) 221 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 222 cu |= _u 223 stou32(op+0*6, _u) 224 _v := vx 225 vx = ctou32(ip + 8 + 0*8 + 4) 226 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 227 cu |= _v 228 stou32(op+0*6+3, _v) 229 } 230 { 231 _u := ux 232 ux = ctou32(ip + 8 + 1*8) 233 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 234 cu |= _u 235 stou32(op+1*6, _u) 236 _v := vx 237 vx = ctou32(ip + 8 + 1*8 + 4) 238 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 239 cu |= _v 240 stou32(op+1*6+3, _v) 241 } 242 ip += 16 243 op += (16 / 4) * 3 244 } 245 if ip < (ipstart+srclen)-(8+4) { 246 _u := ux 247 _u = (e.lutXd0[byte(_u)] | e.lutXd1[byte(_u>>8)] | e.lutXd2[byte(_u>>16)] | e.lutXd3[_u>>24]) 248 cu |= _u 249 stou32(op+0*6, _u) 250 _v := vx 251 _v = (e.lutXd0[byte(_v)] | e.lutXd1[byte(_v>>8)] | e.lutXd2[byte(_v>>16)] | e.lutXd3[_v>>24]) 252 cu |= _v 253 stou32(op+0*6+3, _v) 254 ip += 8 255 op += (8 / 4) * 3 256 } 257 } 258 for ip < (ipstart+srclen)-4 { 259 u := ctou32(ip) 260 u = (e.lutXd0[byte(u)] | e.lutXd1[byte(u>>8)] | e.lutXd2[byte(u>>16)] | e.lutXd3[u>>24]) 261 stou32(op, u) 262 cu |= u 263 ip += 4 264 op += 3 265 } 266 var u uint32 267 l := (ipstart + srclen) - ip 268 if e.pad && l == 4 { 269 if *(*byte)(unsafe.Pointer(ip + 3)) == '=' { 270 l = 3 271 if *(*byte)(unsafe.Pointer(ip + 2)) == '=' { 272 l = 2 273 } 274 } 275 } 276 up := (*[4]byte)(unsafe.Pointer(&u)) 277 switch l { 278 case 4: 279 if !e.pad && op-opstart+3 > dstlen { 280 return 0 281 } 282 u = ctou32(ip) 283 u = (e.lutXd0[byte(u)] | e.lutXd1[byte(u>>8)] | e.lutXd2[byte(u>>16)] | e.lutXd3[u>>24]) 284 putTail(op, up, 3) 285 op += 3 286 cu |= u 287 break 288 case 3: 289 if !e.pad && op-opstart+2 > dstlen { 290 return 0 291 } 292 u = e.lutXd0[*(*byte)(unsafe.Pointer(ip + 0))] | e.lutXd1[*(*byte)(unsafe.Pointer(ip + 1))] | e.lutXd2[*(*byte)(unsafe.Pointer(ip + 2))] 293 putTail(op, up, 2) 294 op += 2 295 cu |= u 296 break 297 case 2: 298 if !e.pad && op-opstart >= dstlen { 299 return 0 300 } 301 u = e.lutXd0[*(*byte)(unsafe.Pointer(ip + 0))] | e.lutXd1[*(*byte)(unsafe.Pointer(ip + 1))] 302 putTail(op, up, 1) 303 op++ 304 cu |= u 305 break 306 case 1: 307 return 0 308 } 309 if cu == 0xffffffff { 310 return 0 311 } 312 return int(op - opstart) 313 }