Offset returns the byte offset, in the raw JSON text of document, of the location referenced by this pointer's terminal token. Unlike [Pointer.Get] and [Pointer.Set], which operate on a decoded Go value, Offset operates directly on the textual JSON source. It drives an [encoding/json.Decoder] over
(document string)
| 155 | // |
| 156 | // All errors wrap [ErrPointer]. |
| 157 | func (p *Pointer) Offset(document string) (int64, error) { |
| 158 | dec := json.NewDecoder(strings.NewReader(document)) |
| 159 | var offset int64 |
| 160 | for _, ttk := range p.DecodedTokens() { |
| 161 | tk, err := dec.Token() |
| 162 | if err != nil { |
| 163 | return 0, err |
| 164 | } |
| 165 | switch tk := tk.(type) { |
| 166 | case json.Delim: |
| 167 | switch tk { |
| 168 | case '{': |
| 169 | offset, err = offsetSingleObject(dec, ttk) |
| 170 | if err != nil { |
| 171 | return 0, err |
| 172 | } |
| 173 | case '[': |
| 174 | offset, err = offsetSingleArray(dec, ttk) |
| 175 | if err != nil { |
| 176 | return 0, err |
| 177 | } |
| 178 | default: |
| 179 | return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) |
| 180 | } |
| 181 | default: |
| 182 | return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) |
| 183 | } |
| 184 | } |
| 185 | return skipJSONSeparator(document, offset), nil |
| 186 | } |
| 187 | |
| 188 | // skipJSONSeparator advances offset past trailing JSON whitespace and at most one value separator |
| 189 | // (comma) in document, so the result points at the first byte of the next JSON token. |