iter_skip.go raw

   1  package jsoniter
   2  
   3  import "fmt"
   4  
   5  // ReadNil reads a json object as nil and
   6  // returns whether it's a nil or not
   7  func (iter *Iterator) ReadNil() (ret bool) {
   8  	c := iter.nextToken()
   9  	if c == 'n' {
  10  		iter.skipThreeBytes('u', 'l', 'l') // null
  11  		return true
  12  	}
  13  	iter.unreadByte()
  14  	return false
  15  }
  16  
  17  // ReadBool reads a json object as BoolValue
  18  func (iter *Iterator) ReadBool() (ret bool) {
  19  	c := iter.nextToken()
  20  	if c == 't' {
  21  		iter.skipThreeBytes('r', 'u', 'e')
  22  		return true
  23  	}
  24  	if c == 'f' {
  25  		iter.skipFourBytes('a', 'l', 's', 'e')
  26  		return false
  27  	}
  28  	iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
  29  	return
  30  }
  31  
  32  // SkipAndReturnBytes skip next JSON element, and return its content as []byte.
  33  // The []byte can be kept, it is a copy of data.
  34  func (iter *Iterator) SkipAndReturnBytes() []byte {
  35  	iter.startCapture(iter.head)
  36  	iter.Skip()
  37  	return iter.stopCapture()
  38  }
  39  
  40  // SkipAndAppendBytes skips next JSON element and appends its content to
  41  // buffer, returning the result.
  42  func (iter *Iterator) SkipAndAppendBytes(buf []byte) []byte {
  43  	iter.startCaptureTo(buf, iter.head)
  44  	iter.Skip()
  45  	return iter.stopCapture()
  46  }
  47  
  48  func (iter *Iterator) startCaptureTo(buf []byte, captureStartedAt int) {
  49  	if iter.captured != nil {
  50  		panic("already in capture mode")
  51  	}
  52  	iter.captureStartedAt = captureStartedAt
  53  	iter.captured = buf
  54  }
  55  
  56  func (iter *Iterator) startCapture(captureStartedAt int) {
  57  	iter.startCaptureTo(make([]byte, 0, 32), captureStartedAt)
  58  }
  59  
  60  func (iter *Iterator) stopCapture() []byte {
  61  	if iter.captured == nil {
  62  		panic("not in capture mode")
  63  	}
  64  	captured := iter.captured
  65  	remaining := iter.buf[iter.captureStartedAt:iter.head]
  66  	iter.captureStartedAt = -1
  67  	iter.captured = nil
  68  	return append(captured, remaining...)
  69  }
  70  
  71  // Skip skips a json object and positions to relatively the next json object
  72  func (iter *Iterator) Skip() {
  73  	c := iter.nextToken()
  74  	switch c {
  75  	case '"':
  76  		iter.skipString()
  77  	case 'n':
  78  		iter.skipThreeBytes('u', 'l', 'l') // null
  79  	case 't':
  80  		iter.skipThreeBytes('r', 'u', 'e') // true
  81  	case 'f':
  82  		iter.skipFourBytes('a', 'l', 's', 'e') // false
  83  	case '0':
  84  		iter.unreadByte()
  85  		iter.ReadFloat32()
  86  	case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  87  		iter.skipNumber()
  88  	case '[':
  89  		iter.skipArray()
  90  	case '{':
  91  		iter.skipObject()
  92  	default:
  93  		iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
  94  		return
  95  	}
  96  }
  97  
  98  func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) {
  99  	if iter.readByte() != b1 {
 100  		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
 101  		return
 102  	}
 103  	if iter.readByte() != b2 {
 104  		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
 105  		return
 106  	}
 107  	if iter.readByte() != b3 {
 108  		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
 109  		return
 110  	}
 111  	if iter.readByte() != b4 {
 112  		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
 113  		return
 114  	}
 115  }
 116  
 117  func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) {
 118  	if iter.readByte() != b1 {
 119  		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
 120  		return
 121  	}
 122  	if iter.readByte() != b2 {
 123  		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
 124  		return
 125  	}
 126  	if iter.readByte() != b3 {
 127  		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
 128  		return
 129  	}
 130  }
 131