 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			408 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			408 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package gojay
 | |
| 
 | |
| import (
 | |
| 	"reflect"
 | |
| 	"unsafe"
 | |
| )
 | |
| 
 | |
| // DecodeObject reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v.
 | |
| //
 | |
| // v must implement UnmarshalerJSONObject.
 | |
| //
 | |
| // See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
 | |
| func (dec *Decoder) DecodeObject(j UnmarshalerJSONObject) error {
 | |
| 	if dec.isPooled == 1 {
 | |
| 		panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
 | |
| 	}
 | |
| 	_, err := dec.decodeObject(j)
 | |
| 	return err
 | |
| }
 | |
| func (dec *Decoder) decodeObject(j UnmarshalerJSONObject) (int, error) {
 | |
| 	keys := j.NKeys()
 | |
| 	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
 | |
| 		switch dec.data[dec.cursor] {
 | |
| 		case ' ', '\n', '\t', '\r', ',':
 | |
| 		case '{':
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			// if keys is zero we will parse all keys
 | |
| 			// we run two loops for micro optimization
 | |
| 			if keys == 0 {
 | |
| 				for dec.cursor < dec.length || dec.read() {
 | |
| 					k, done, err := dec.nextKey()
 | |
| 					if err != nil {
 | |
| 						return 0, err
 | |
| 					} else if done {
 | |
| 						return dec.cursor, nil
 | |
| 					}
 | |
| 					err = j.UnmarshalJSONObject(dec, k)
 | |
| 					if err != nil {
 | |
| 						dec.err = err
 | |
| 						return 0, err
 | |
| 					} else if dec.called&1 == 0 {
 | |
| 						err := dec.skipData()
 | |
| 						if err != nil {
 | |
| 							return 0, err
 | |
| 						}
 | |
| 					} else {
 | |
| 						dec.keysDone++
 | |
| 					}
 | |
| 					dec.called &= 0
 | |
| 				}
 | |
| 			} else {
 | |
| 				for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys {
 | |
| 					k, done, err := dec.nextKey()
 | |
| 					if err != nil {
 | |
| 						return 0, err
 | |
| 					} else if done {
 | |
| 						return dec.cursor, nil
 | |
| 					}
 | |
| 					err = j.UnmarshalJSONObject(dec, k)
 | |
| 					if err != nil {
 | |
| 						dec.err = err
 | |
| 						return 0, err
 | |
| 					} else if dec.called&1 == 0 {
 | |
| 						err := dec.skipData()
 | |
| 						if err != nil {
 | |
| 							return 0, err
 | |
| 						}
 | |
| 					} else {
 | |
| 						dec.keysDone++
 | |
| 					}
 | |
| 					dec.called &= 0
 | |
| 				}
 | |
| 			}
 | |
| 			// will get to that point when keysDone is not lower than keys anymore
 | |
| 			// in that case, we make sure cursor goes to the end of object, but we skip
 | |
| 			// unmarshalling
 | |
| 			if dec.child&1 != 0 {
 | |
| 				end, err := dec.skipObject()
 | |
| 				dec.cursor = end
 | |
| 				return dec.cursor, err
 | |
| 			}
 | |
| 			return dec.cursor, nil
 | |
| 		case 'n':
 | |
| 			dec.cursor++
 | |
| 			err := dec.assertNull()
 | |
| 			if err != nil {
 | |
| 				return 0, err
 | |
| 			}
 | |
| 			return dec.cursor, nil
 | |
| 		default:
 | |
| 			// can't unmarshal to struct
 | |
| 			dec.err = dec.makeInvalidUnmarshalErr(j)
 | |
| 			err := dec.skipData()
 | |
| 			if err != nil {
 | |
| 				return 0, err
 | |
| 			}
 | |
| 			return dec.cursor, nil
 | |
| 		}
 | |
| 	}
 | |
| 	return 0, dec.raiseInvalidJSONErr(dec.cursor)
 | |
| }
 | |
| 
 | |
| func (dec *Decoder) decodeObjectNull(v interface{}) (int, error) {
 | |
| 	// make sure the value is a pointer
 | |
| 	vv := reflect.ValueOf(v)
 | |
| 	vvt := vv.Type()
 | |
| 	if vvt.Kind() != reflect.Ptr || vvt.Elem().Kind() != reflect.Ptr {
 | |
| 		dec.err = ErrUnmarshalPtrExpected
 | |
| 		return 0, dec.err
 | |
| 	}
 | |
| 	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
 | |
| 		switch dec.data[dec.cursor] {
 | |
| 		case ' ', '\n', '\t', '\r', ',':
 | |
| 		case '{':
 | |
| 			elt := vv.Elem()
 | |
| 			n := reflect.New(elt.Type().Elem())
 | |
| 			elt.Set(n)
 | |
| 			var j UnmarshalerJSONObject
 | |
| 			var ok bool
 | |
| 			if j, ok = n.Interface().(UnmarshalerJSONObject); !ok {
 | |
| 				dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil))
 | |
| 				return 0, dec.err
 | |
| 			}
 | |
| 			keys := j.NKeys()
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			// if keys is zero we will parse all keys
 | |
| 			// we run two loops for micro optimization
 | |
| 			if keys == 0 {
 | |
| 				for dec.cursor < dec.length || dec.read() {
 | |
| 					k, done, err := dec.nextKey()
 | |
| 					if err != nil {
 | |
| 						return 0, err
 | |
| 					} else if done {
 | |
| 						return dec.cursor, nil
 | |
| 					}
 | |
| 					err = j.UnmarshalJSONObject(dec, k)
 | |
| 					if err != nil {
 | |
| 						dec.err = err
 | |
| 						return 0, err
 | |
| 					} else if dec.called&1 == 0 {
 | |
| 						err := dec.skipData()
 | |
| 						if err != nil {
 | |
| 							return 0, err
 | |
| 						}
 | |
| 					} else {
 | |
| 						dec.keysDone++
 | |
| 					}
 | |
| 					dec.called &= 0
 | |
| 				}
 | |
| 			} else {
 | |
| 				for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys {
 | |
| 					k, done, err := dec.nextKey()
 | |
| 					if err != nil {
 | |
| 						return 0, err
 | |
| 					} else if done {
 | |
| 						return dec.cursor, nil
 | |
| 					}
 | |
| 					err = j.UnmarshalJSONObject(dec, k)
 | |
| 					if err != nil {
 | |
| 						dec.err = err
 | |
| 						return 0, err
 | |
| 					} else if dec.called&1 == 0 {
 | |
| 						err := dec.skipData()
 | |
| 						if err != nil {
 | |
| 							return 0, err
 | |
| 						}
 | |
| 					} else {
 | |
| 						dec.keysDone++
 | |
| 					}
 | |
| 					dec.called &= 0
 | |
| 				}
 | |
| 			}
 | |
| 			// will get to that point when keysDone is not lower than keys anymore
 | |
| 			// in that case, we make sure cursor goes to the end of object, but we skip
 | |
| 			// unmarshalling
 | |
| 			if dec.child&1 != 0 {
 | |
| 				end, err := dec.skipObject()
 | |
| 				dec.cursor = end
 | |
| 				return dec.cursor, err
 | |
| 			}
 | |
| 			return dec.cursor, nil
 | |
| 		case 'n':
 | |
| 			dec.cursor++
 | |
| 			err := dec.assertNull()
 | |
| 			if err != nil {
 | |
| 				return 0, err
 | |
| 			}
 | |
| 			return dec.cursor, nil
 | |
| 		default:
 | |
| 			// can't unmarshal to struct
 | |
| 			dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil))
 | |
| 			err := dec.skipData()
 | |
| 			if err != nil {
 | |
| 				return 0, err
 | |
| 			}
 | |
| 			return dec.cursor, nil
 | |
| 		}
 | |
| 	}
 | |
| 	return 0, dec.raiseInvalidJSONErr(dec.cursor)
 | |
| }
 | |
| 
 | |
| func (dec *Decoder) skipObject() (int, error) {
 | |
| 	var objectsOpen = 1
 | |
| 	var objectsClosed = 0
 | |
| 	for j := dec.cursor; j < dec.length || dec.read(); j++ {
 | |
| 		switch dec.data[j] {
 | |
| 		case '}':
 | |
| 			objectsClosed++
 | |
| 			// everything is closed return
 | |
| 			if objectsOpen == objectsClosed {
 | |
| 				// add char to object data
 | |
| 				return j + 1, nil
 | |
| 			}
 | |
| 		case '{':
 | |
| 			objectsOpen++
 | |
| 		case '"':
 | |
| 			j++
 | |
| 			var isInEscapeSeq bool
 | |
| 			var isFirstQuote = true
 | |
| 			for ; j < dec.length || dec.read(); j++ {
 | |
| 				if dec.data[j] != '"' {
 | |
| 					continue
 | |
| 				}
 | |
| 				if dec.data[j-1] != '\\' || (!isInEscapeSeq && !isFirstQuote) {
 | |
| 					break
 | |
| 				} else {
 | |
| 					isInEscapeSeq = false
 | |
| 				}
 | |
| 				if isFirstQuote {
 | |
| 					isFirstQuote = false
 | |
| 				}
 | |
| 				// loop backward and count how many anti slash found
 | |
| 				// to see if string is effectively escaped
 | |
| 				ct := 0
 | |
| 				for i := j - 1; i > 0; i-- {
 | |
| 					if dec.data[i] != '\\' {
 | |
| 						break
 | |
| 					}
 | |
| 					ct++
 | |
| 				}
 | |
| 				// is pair number of slashes, quote is not escaped
 | |
| 				if ct&1 == 0 {
 | |
| 					break
 | |
| 				}
 | |
| 				isInEscapeSeq = true
 | |
| 			}
 | |
| 		default:
 | |
| 			continue
 | |
| 		}
 | |
| 	}
 | |
| 	return 0, dec.raiseInvalidJSONErr(dec.cursor)
 | |
| }
 | |
| 
 | |
| func (dec *Decoder) nextKey() (string, bool, error) {
 | |
| 	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
 | |
| 		switch dec.data[dec.cursor] {
 | |
| 		case ' ', '\n', '\t', '\r', ',':
 | |
| 			continue
 | |
| 		case '"':
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			start, end, err := dec.getString()
 | |
| 			if err != nil {
 | |
| 				return "", false, err
 | |
| 			}
 | |
| 			var found byte
 | |
| 			for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
 | |
| 				if dec.data[dec.cursor] == ':' {
 | |
| 					found |= 1
 | |
| 					break
 | |
| 				}
 | |
| 			}
 | |
| 			if found&1 != 0 {
 | |
| 				dec.cursor++
 | |
| 				d := dec.data[start : end-1]
 | |
| 				return *(*string)(unsafe.Pointer(&d)), false, nil
 | |
| 			}
 | |
| 			return "", false, dec.raiseInvalidJSONErr(dec.cursor)
 | |
| 		case '}':
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			return "", true, nil
 | |
| 		default:
 | |
| 			// can't unmarshall to struct
 | |
| 			return "", false, dec.raiseInvalidJSONErr(dec.cursor)
 | |
| 		}
 | |
| 	}
 | |
| 	return "", false, dec.raiseInvalidJSONErr(dec.cursor)
 | |
| }
 | |
| 
 | |
| func (dec *Decoder) skipData() error {
 | |
| 	for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
 | |
| 		switch dec.data[dec.cursor] {
 | |
| 		case ' ', '\n', '\t', '\r', ',':
 | |
| 			continue
 | |
| 		// is null
 | |
| 		case 'n':
 | |
| 			dec.cursor++
 | |
| 			err := dec.assertNull()
 | |
| 			if err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 			return nil
 | |
| 		case 't':
 | |
| 			dec.cursor++
 | |
| 			err := dec.assertTrue()
 | |
| 			if err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 			return nil
 | |
| 		// is false
 | |
| 		case 'f':
 | |
| 			dec.cursor++
 | |
| 			err := dec.assertFalse()
 | |
| 			if err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 			return nil
 | |
| 		// is an object
 | |
| 		case '{':
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			end, err := dec.skipObject()
 | |
| 			dec.cursor = end
 | |
| 			return err
 | |
| 		// is string
 | |
| 		case '"':
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			err := dec.skipString()
 | |
| 			return err
 | |
| 		// is array
 | |
| 		case '[':
 | |
| 			dec.cursor = dec.cursor + 1
 | |
| 			end, err := dec.skipArray()
 | |
| 			dec.cursor = end
 | |
| 			return err
 | |
| 		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
 | |
| 			end, err := dec.skipNumber()
 | |
| 			dec.cursor = end
 | |
| 			return err
 | |
| 		}
 | |
| 		return dec.raiseInvalidJSONErr(dec.cursor)
 | |
| 	}
 | |
| 	return dec.raiseInvalidJSONErr(dec.cursor)
 | |
| }
 | |
| 
 | |
| // DecodeObjectFunc is a func type implementing UnmarshalerJSONObject.
 | |
| // Use it to cast a `func(*Decoder, k string) error` to Unmarshal an object on the fly.
 | |
| type DecodeObjectFunc func(*Decoder, string) error
 | |
| 
 | |
| // UnmarshalJSONObject implements UnmarshalerJSONObject.
 | |
| func (f DecodeObjectFunc) UnmarshalJSONObject(dec *Decoder, k string) error {
 | |
| 	return f(dec, k)
 | |
| }
 | |
| 
 | |
| // NKeys implements UnmarshalerJSONObject.
 | |
| func (f DecodeObjectFunc) NKeys() int {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| // Add Values functions
 | |
| 
 | |
| // AddObject decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
 | |
| func (dec *Decoder) AddObject(v UnmarshalerJSONObject) error {
 | |
| 	return dec.Object(v)
 | |
| }
 | |
| 
 | |
| // AddObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
 | |
| func (dec *Decoder) AddObjectNull(v interface{}) error {
 | |
| 	return dec.ObjectNull(v)
 | |
| }
 | |
| 
 | |
| // Object decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
 | |
| func (dec *Decoder) Object(value UnmarshalerJSONObject) error {
 | |
| 	initialKeysDone := dec.keysDone
 | |
| 	initialChild := dec.child
 | |
| 	dec.keysDone = 0
 | |
| 	dec.called = 0
 | |
| 	dec.child |= 1
 | |
| 	newCursor, err := dec.decodeObject(value)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	dec.cursor = newCursor
 | |
| 	dec.keysDone = initialKeysDone
 | |
| 	dec.child = initialChild
 | |
| 	dec.called |= 1
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
 | |
| // v should be a pointer to an UnmarshalerJSONObject,
 | |
| // if `null` value is encountered in JSON, it will leave the value v untouched,
 | |
| // else it will create a new instance of the UnmarshalerJSONObject behind v.
 | |
| func (dec *Decoder) ObjectNull(v interface{}) error {
 | |
| 	initialKeysDone := dec.keysDone
 | |
| 	initialChild := dec.child
 | |
| 	dec.keysDone = 0
 | |
| 	dec.called = 0
 | |
| 	dec.child |= 1
 | |
| 	newCursor, err := dec.decodeObjectNull(v)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	dec.cursor = newCursor
 | |
| 	dec.keysDone = initialKeysDone
 | |
| 	dec.child = initialChild
 | |
| 	dec.called |= 1
 | |
| 	return nil
 | |
| }
 |