decoder.go 8.6 KB

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