github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_object.go (about) 1 package jzon 2 3 // use after the first `"` is consumed 4 // will read the object field as well as the colon 5 func (it *Iterator) readObjectFieldAsSlice() (field []byte, err error) { 6 field, err = it.readStringAsSlice() 7 if err != nil { 8 return 9 } 10 c, err := it.nextToken() 11 if err != nil { 12 return 13 } 14 if c != ':' { 15 err = UnexpectedByteError{got: c, exp: ':'} 16 return 17 } 18 it.head++ 19 return 20 } 21 22 // called only when a '"' is consumed 23 func (it *Iterator) readObjectField() (_ string, err error) { 24 field, err := it.readObjectFieldAsSlice() 25 if err != nil { 26 return "", err 27 } 28 return string(field), nil 29 } 30 31 func (it *Iterator) skipObjectField() error { 32 err := skipString(it, '"') 33 if err != nil { 34 return err 35 } 36 c, err := it.nextToken() 37 if err != nil { 38 return err 39 } 40 if c != ':' { 41 return UnexpectedByteError{got: c, exp: ':'} 42 } 43 it.head++ 44 return nil 45 } 46 47 // ReadObjectBegin starts to read an object 48 func (it *Iterator) ReadObjectBegin() (_ bool, _ string, err error) { 49 c, err := it.nextToken() 50 if err != nil { 51 return 52 } 53 if c != '{' { 54 err = UnexpectedByteError{got: c, exp: '{'} 55 return 56 } 57 it.head++ 58 c, err = it.nextToken() 59 if err != nil { 60 return 61 } 62 switch c { 63 case '}': 64 // no more items 65 it.head++ 66 return 67 case '"': 68 it.head++ 69 var fieldBytes []byte 70 fieldBytes, err = it.readObjectFieldAsSlice() 71 if err != nil { 72 return 73 } 74 return true, string(fieldBytes), nil 75 default: 76 err = UnexpectedByteError{got: c, exp: '}', exp2: '"'} 77 return 78 } 79 } 80 81 // ReadObjectMore tells if there is more field to read in the object 82 func (it *Iterator) ReadObjectMore() (_ bool, _ string, err error) { 83 c, err := it.nextToken() 84 if err != nil { 85 return 86 } 87 switch c { 88 case '}': 89 it.head++ 90 return 91 case ',': 92 it.head++ 93 c, err = it.nextToken() 94 if err != nil { 95 return 96 } 97 if c != '"' { 98 err = UnexpectedByteError{got: c, exp: '"'} 99 return 100 } 101 it.head++ 102 var fieldBytes []byte 103 fieldBytes, err = it.readObjectFieldAsSlice() 104 if err != nil { 105 return 106 } 107 return true, string(fieldBytes), nil 108 default: 109 err = UnexpectedByteError{got: c, exp: '}', exp2: ','} 110 return 111 } 112 } 113 114 // ReadObjectCB reads the object with a callback 115 // The caller should make sure that the callback is correct 116 func (it *Iterator) ReadObjectCB(cb func(it *Iterator, field string) error) error { 117 c, err := it.nextToken() 118 if err != nil { 119 return err 120 } 121 if c != '{' { 122 return UnexpectedByteError{got: c, exp: '{'} 123 } 124 it.head++ 125 c, err = it.nextToken() 126 if err != nil { 127 return err 128 } 129 if c == '}' { 130 it.head++ 131 return nil 132 } 133 if c != '"' { 134 return UnexpectedByteError{got: c, exp: '"', exp2: '}'} 135 } 136 it.head++ 137 for { 138 field, err := it.readObjectField() 139 if err != nil { 140 return err 141 } 142 if err := cb(it, field); err != nil { 143 return err 144 } 145 c, err = it.nextToken() 146 if err != nil { 147 return err 148 } 149 switch c { 150 case '}': 151 it.head++ 152 return nil 153 case ',': 154 it.head++ 155 c, err = it.nextToken() 156 if err != nil { 157 return err 158 } 159 if c != '"' { 160 return UnexpectedByteError{got: c, exp: '"'} 161 } 162 it.head++ 163 default: 164 return UnexpectedByteError{got: c, exp: '}', exp2: ','} 165 } 166 } 167 }