podman
1// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
2// Use of this source code is governed by a MIT license found in the LICENSE file.
3
4package codec5
6import (7"bufio"8"bytes"9"io"10"strings"11)
12
13// decReader abstracts the reading source, allowing implementations that can
14// read from an io.Reader or directly off a byte slice with zero-copying.
15type decReader interface {16// readx will return a view of the []byte if decoding from a []byte, OR17// read into the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR18// create a new []byte and read into that19readx(n uint) []byte20
21readb([]byte)22
23readn1() byte24readn2() [2]byte25readn3() [3]byte26readn4() [4]byte27readn8() [8]byte28// readn1eof() (v uint8, eof bool)29
30// // read up to 8 bytes at a time31// readn(num uint8) (v [8]byte)32
33numread() uint // number of bytes read34
35// skip any whitespace characters, and return the first non-matching byte36skipWhitespace() (token byte)37
38// jsonReadNum will include last read byte in first element of slice,39// and continue numeric characters until it sees a non-numeric char40// or EOF. If it sees a non-numeric character, it will unread that.41jsonReadNum() []byte42
43// jsonReadAsisChars will read json plain characters (anything but " or \)44// and return a slice terminated by a non-json asis character.45jsonReadAsisChars() []byte46
47// skip will skip any byte that matches, and return the first non-matching byte48// skip(accept *bitset256) (token byte)49
50// readTo will read any byte that matches, stopping once no-longer matching.51// readTo(accept *bitset256) (out []byte)52
53// readUntil will read, only stopping once it matches the 'stop' byte (which it excludes).54readUntil(stop byte) (out []byte)55}
56
57// ------------------------------------------------
58
59type unreadByteStatus uint860
61// unreadByteStatus goes from
62// undefined (when initialized) -- (read) --> canUnread -- (unread) --> canRead ...
63const (64unreadByteUndefined unreadByteStatus = iota65unreadByteCanRead
66unreadByteCanUnread
67)
68
69// const defBufReaderSize = 4096
70
71// --------------------
72
73// ioReaderByteScanner contains the io.Reader and io.ByteScanner interfaces
74type ioReaderByteScanner interface {75io.Reader76io.ByteScanner77// ReadByte() (byte, error)78// UnreadByte() error79// Read(p []byte) (n int, err error)80}
81
82// ioReaderByteScannerT does a simple wrapper of a io.ByteScanner
83// over a io.Reader
84type ioReaderByteScannerT struct {85r io.Reader86
87l byte // last byte88ls unreadByteStatus // last byte status89
90_ [2]byte // padding91b [4]byte // tiny buffer for reading single bytes92}
93
94func (z *ioReaderByteScannerT) ReadByte() (c byte, err error) {95if z.ls == unreadByteCanRead {96z.ls = unreadByteCanUnread97c = z.l98} else {99_, err = z.Read(z.b[:1])100c = z.b[0]101}102return103}
104
105func (z *ioReaderByteScannerT) UnreadByte() (err error) {106switch z.ls {107case unreadByteCanUnread:108z.ls = unreadByteCanRead109case unreadByteCanRead:110err = errDecUnreadByteLastByteNotRead111case unreadByteUndefined:112err = errDecUnreadByteNothingToRead113default:114err = errDecUnreadByteUnknown115}116return117}
118
119func (z *ioReaderByteScannerT) Read(p []byte) (n int, err error) {120if len(p) == 0 {121return122}123var firstByte bool124if z.ls == unreadByteCanRead {125z.ls = unreadByteCanUnread126p[0] = z.l127if len(p) == 1 {128n = 1129return130}131firstByte = true132p = p[1:]133}134n, err = z.r.Read(p)135if n > 0 {136if err == io.EOF && n == len(p) {137err = nil // read was successful, so postpone EOF (till next time)138}139z.l = p[n-1]140z.ls = unreadByteCanUnread141}142if firstByte {143n++144}145return146}
147
148func (z *ioReaderByteScannerT) reset(r io.Reader) {149z.r = r150z.ls = unreadByteUndefined151z.l = 0152}
153
154// ioDecReader is a decReader that reads off an io.Reader.
155type ioDecReader struct {156rr ioReaderByteScannerT // the reader passed in, wrapped into a reader+bytescanner157
158n uint // num read159
160blist *bytesFreelist161
162bufr []byte // buffer for readTo/readUntil163br ioReaderByteScanner // main reader used for Read|ReadByte|UnreadByte164bb *bufio.Reader // created internally, and reused on reset if needed165
166x [64 + 40]byte // for: get struct field name, swallow valueTypeBytes, etc167}
168
169func (z *ioDecReader) reset(r io.Reader, bufsize int, blist *bytesFreelist) {170z.blist = blist171z.n = 0172z.bufr = z.blist.check(z.bufr, 256)173z.br = nil174
175var ok bool176
177if bufsize <= 0 {178z.br, ok = r.(ioReaderByteScanner)179if !ok {180z.rr.reset(r)181z.br = &z.rr182}183return184}185
186// bufsize > 0 ...187
188// if bytes.[Buffer|Reader], no value in adding extra buffer189// if bufio.Reader, no value in extra buffer unless size changes190switch bb := r.(type) {191case *strings.Reader:192z.br = bb193case *bytes.Buffer:194z.br = bb195case *bytes.Reader:196z.br = bb197case *bufio.Reader:198if bb.Size() == bufsize {199z.br = bb200}201}202
203if z.br == nil {204if z.bb != nil && z.bb.Size() == bufsize {205z.bb.Reset(r)206} else {207z.bb = bufio.NewReaderSize(r, bufsize)208}209z.br = z.bb210}211}
212
213func (z *ioDecReader) numread() uint {214return z.n215}
216
217func (z *ioDecReader) readn1() (b uint8) {218b, err := z.br.ReadByte()219halt.onerror(err)220z.n++221return222}
223
224func (z *ioDecReader) readn2() (bs [2]byte) {225z.readb(bs[:])226return227}
228
229func (z *ioDecReader) readn3() (bs [3]byte) {230z.readb(bs[:])231return232}
233
234func (z *ioDecReader) readn4() (bs [4]byte) {235z.readb(bs[:])236return237}
238
239func (z *ioDecReader) readn8() (bs [8]byte) {240z.readb(bs[:])241return242}
243
244func (z *ioDecReader) readx(n uint) (bs []byte) {245if n == 0 {246return zeroByteSlice247}248if n < uint(len(z.x)) {249bs = z.x[:n]250} else {251bs = make([]byte, n)252}253nn, err := readFull(z.br, bs)254z.n += nn255halt.onerror(err)256return257}
258
259func (z *ioDecReader) readb(bs []byte) {260if len(bs) == 0 {261return262}263nn, err := readFull(z.br, bs)264z.n += nn265halt.onerror(err)266}
267
268// func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
269// b, err := z.br.ReadByte()
270// if err == nil {
271// z.n++
272// } else if err == io.EOF {
273// eof = true
274// } else {
275// halt.onerror(err)
276// }
277// return
278// }
279
280func (z *ioDecReader) jsonReadNum() (bs []byte) {281z.unreadn1()282z.bufr = z.bufr[:0]283LOOP:284// i, eof := z.readn1eof()285i, err := z.br.ReadByte()286if err == io.EOF {287return z.bufr288}289if err != nil {290halt.onerror(err)291}292z.n++293if isNumberChar(i) {294z.bufr = append(z.bufr, i)295goto LOOP296}297z.unreadn1()298return z.bufr299}
300
301func (z *ioDecReader) jsonReadAsisChars() (bs []byte) {302z.bufr = z.bufr[:0]303LOOP:304i := z.readn1()305z.bufr = append(z.bufr, i)306if i == '"' || i == '\\' {307return z.bufr308}309goto LOOP310}
311
312func (z *ioDecReader) skipWhitespace() (token byte) {313LOOP:314token = z.readn1()315if isWhitespaceChar(token) {316goto LOOP317}318return319}
320
321// func (z *ioDecReader) readUntil(stop byte) []byte {
322// z.bufr = z.bufr[:0]
323// LOOP:
324// token := z.readn1()
325// z.bufr = append(z.bufr, token)
326// if token == stop {
327// return z.bufr[:len(z.bufr)-1]
328// }
329// goto LOOP
330// }
331
332func (z *ioDecReader) readUntil(stop byte) []byte {333z.bufr = z.bufr[:0]334LOOP:335token := z.readn1()336if token == stop {337return z.bufr338}339z.bufr = append(z.bufr, token)340goto LOOP341}
342
343func (z *ioDecReader) unreadn1() {344err := z.br.UnreadByte()345halt.onerror(err)346z.n--347}
348
349// ------------------------------------
350
351// bytesDecReader is a decReader that reads off a byte slice with zero copying
352//
353// Note: we do not try to convert index'ing out of bounds to an io error.
354// instead, we let it bubble up to the exported Encode/Decode method
355// and recover it as an io error.
356//
357// Every function here MUST defensively check bounds either explicitly
358// or via a bounds check.
359//
360// see panicValToErr(...) function in helper.go.
361type bytesDecReader struct {362b []byte // data363c uint // cursor364}
365
366func (z *bytesDecReader) reset(in []byte) {367z.b = in[:len(in):len(in)] // reslicing must not go past capacity368z.c = 0369}
370
371func (z *bytesDecReader) numread() uint {372return z.c373}
374
375// Note: slicing from a non-constant start position is more expensive,
376// as more computation is required to decipher the pointer start position.
377// However, we do it only once, and it's better than reslicing both z.b and return value.
378
379func (z *bytesDecReader) readx(n uint) (bs []byte) {380// x := z.c + n381// bs = z.b[z.c:x]382// z.c = x383bs = z.b[z.c : z.c+n]384z.c += n385return386}
387
388func (z *bytesDecReader) readb(bs []byte) {389copy(bs, z.readx(uint(len(bs))))390}
391
392// MARKER: do not use this - as it calls into memmove (as the size of data to move is unknown)
393// func (z *bytesDecReader) readnn(bs []byte, n uint) {
394// x := z.c
395// copy(bs, z.b[x:x+n])
396// z.c += n
397// }
398
399// func (z *bytesDecReader) readn(num uint8) (bs [8]byte) {
400// x := z.c + uint(num)
401// copy(bs[:], z.b[z.c:x]) // slice z.b completely, so we get bounds error if past
402// z.c = x
403// return
404// }
405
406// func (z *bytesDecReader) readn1() uint8 {
407// z.c++
408// return z.b[z.c-1]
409// }
410
411// MARKER: readn{1,2,3,4,8} should throw an out of bounds error if past length.
412// MARKER: readn1: explicitly ensure bounds check is done
413// MARKER: readn{2,3,4,8}: ensure you slice z.b completely so we get bounds error if past end.
414
415func (z *bytesDecReader) readn1() (v uint8) {416v = z.b[z.c]417z.c++418return419}
420
421func (z *bytesDecReader) readn2() (bs [2]byte) {422// copy(bs[:], z.b[z.c:z.c+2])423// bs[1] = z.b[z.c+1]424// bs[0] = z.b[z.c]425bs = okBytes2(z.b[z.c : z.c+2])426z.c += 2427return428}
429
430func (z *bytesDecReader) readn3() (bs [3]byte) {431// copy(bs[1:], z.b[z.c:z.c+3])432bs = okBytes3(z.b[z.c : z.c+3])433z.c += 3434return435}
436
437func (z *bytesDecReader) readn4() (bs [4]byte) {438// copy(bs[:], z.b[z.c:z.c+4])439bs = okBytes4(z.b[z.c : z.c+4])440z.c += 4441return442}
443
444func (z *bytesDecReader) readn8() (bs [8]byte) {445// copy(bs[:], z.b[z.c:z.c+8])446bs = okBytes8(z.b[z.c : z.c+8])447z.c += 8448return449}
450
451func (z *bytesDecReader) jsonReadNum() []byte {452z.c-- // unread453i := z.c454LOOP:455// gracefully handle end of slice, as end of stream is meaningful here456if i < uint(len(z.b)) && isNumberChar(z.b[i]) {457i++458goto LOOP459}460z.c, i = i, z.c461// MARKER: 20230103: byteSliceOf here prevents inlining of jsonReadNum462// return byteSliceOf(z.b, i, z.c)463return z.b[i:z.c]464}
465
466func (z *bytesDecReader) jsonReadAsisChars() []byte {467i := z.c468LOOP:469token := z.b[i]470i++471if token == '"' || token == '\\' {472z.c, i = i, z.c473return byteSliceOf(z.b, i, z.c)474// return z.b[i:z.c]475}476goto LOOP477}
478
479func (z *bytesDecReader) skipWhitespace() (token byte) {480i := z.c481LOOP:482token = z.b[i]483if isWhitespaceChar(token) {484i++485goto LOOP486}487z.c = i + 1488return489}
490
491func (z *bytesDecReader) readUntil(stop byte) (out []byte) {492i := z.c493LOOP:494if z.b[i] == stop {495out = byteSliceOf(z.b, z.c, i)496// out = z.b[z.c:i]497z.c = i + 1498return499}500i++501goto LOOP502}
503
504// --------------
505
506type decRd struct {507rb bytesDecReader
508ri *ioDecReader509
510decReader
511
512bytes bool // is bytes reader513
514// MARKER: these fields below should belong directly in Encoder.515// we pack them here for space efficiency and cache-line optimization.516
517mtr bool // is maptype a known type?518str bool // is slicetype a known type?519
520be bool // is binary encoding521js bool // is json handle522jsms bool // is json handle, and MapKeyAsString523cbor bool // is cbor handle524
525cbreak bool // is a check breaker526
527}
528
529// From out benchmarking, we see the following impact performance:
530//
531// - functions that are too big to inline
532// - interface calls (as no inlining can occur)
533//
534// decRd is designed to embed a decReader, and then re-implement some of the decReader
535// methods using a conditional branch.
536//
537// We only override the ones where the bytes version is inlined AND the wrapper method
538// (containing the bytes version alongside a conditional branch) is also inlined.
539//
540// We use ./run.sh -z to check.
541//
542// Right now, only numread and "carefully crafted" readn1 can be inlined.
543
544func (z *decRd) numread() uint {545if z.bytes {546return z.rb.numread()547}548return z.ri.numread()549}
550
551func (z *decRd) readn1() (v uint8) {552if z.bytes {553// return z.rb.readn1()554// MARKER: calling z.rb.readn1() prevents decRd.readn1 from being inlined.555// copy code, to manually inline and explicitly return here.556// Keep in sync with bytesDecReader.readn1557v = z.rb.b[z.rb.c]558z.rb.c++559return560}561return z.ri.readn1()562}
563
564// func (z *decRd) readn4() [4]byte {
565// if z.bytes {
566// return z.rb.readn4()
567// }
568// return z.ri.readn4()
569// }
570
571// func (z *decRd) readn3() [3]byte {
572// if z.bytes {
573// return z.rb.readn3()
574// }
575// return z.ri.readn3()
576// }
577
578// func (z *decRd) skipWhitespace() byte {
579// if z.bytes {
580// return z.rb.skipWhitespace()
581// }
582// return z.ri.skipWhitespace()
583// }
584
585type devNullReader struct{}586
587func (devNullReader) Read(p []byte) (int, error) { return 0, io.EOF }588func (devNullReader) Close() error { return nil }589
590func readFull(r io.Reader, bs []byte) (n uint, err error) {591var nn int592for n < uint(len(bs)) && err == nil {593nn, err = r.Read(bs[n:])594if nn > 0 {595if err == io.EOF {596// leave EOF for next time597err = nil598}599n += uint(nn)600}601}602// do not do this below - it serves no purpose603// if n != len(bs) && err == io.EOF { err = io.ErrUnexpectedEOF }604return605}
606
607var _ decReader = (*decRd)(nil)608