Initial working version.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
module gitea.cozeon.cloud/anand.ekka-ext/jaeson
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require github.com/antlr/antlr4/runtime/Go/antlr v1.4.10
|
||||
|
||||
require gitea.cozeon.cloud/anand.ekka-ext/parser v0.0.0-20260929115114-8ff7130c8636
|
||||
@@ -0,0 +1,623 @@
|
||||
package jaeson
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
JSON_VAL_TYPE_STRING = "str"
|
||||
JSON_VAL_TYPE_INT = "int"
|
||||
JSON_VAL_TYPE_FLOAT = "float"
|
||||
JSON_VAL_TYPE_BOOL = "jsbln"
|
||||
JSON_VAL_TYPE_OBJECT = "jsobj"
|
||||
JSON_VAL_TYPE_ARRAY = "jsarr"
|
||||
)
|
||||
|
||||
type JSONObject struct {
|
||||
|
||||
ms map[string]string
|
||||
mo map[string]*JSONObject
|
||||
marr map[string]*JSONArray
|
||||
mn map[string]int
|
||||
mbln map[string]bool
|
||||
mflt64 map[string]float64
|
||||
|
||||
//contains all valid keys
|
||||
mAllkeys map[string]string
|
||||
|
||||
ctms int
|
||||
ctmo int
|
||||
ctmarr int
|
||||
ctmn int
|
||||
ctmbln int
|
||||
ctmflt64 int
|
||||
|
||||
hasVal bool
|
||||
//isSorted bool
|
||||
}
|
||||
|
||||
func NewJSONObject() *JSONObject {
|
||||
jsObj := new(JSONObject)
|
||||
jsObj.Init()
|
||||
return jsObj
|
||||
}
|
||||
func NewJSONArray() *JSONArray {
|
||||
jsArr := new(JSONArray)
|
||||
jsArr.Init()
|
||||
return jsArr
|
||||
}
|
||||
|
||||
func (v *JSONObject) Init() {
|
||||
v.ctms = 0
|
||||
v.ctmo = 0
|
||||
v.ctmarr = 0
|
||||
v.ctmn = 0
|
||||
v.ctmbln = 0
|
||||
v.ctmflt64 = 0
|
||||
|
||||
v.ms = make(map[string]string, 0)
|
||||
v.mo = make(map[string]*JSONObject, 0)
|
||||
v.marr = make(map[string]*JSONArray, 0)
|
||||
v.mn = make(map[string]int, 0)
|
||||
v.mbln = make(map[string]bool, 0)
|
||||
v.mflt64 = make(map[string]float64, 0)
|
||||
|
||||
v.hasVal = false
|
||||
//v.isSorted = false
|
||||
|
||||
v.mAllkeys = make(map[string]string, 0)
|
||||
|
||||
}
|
||||
|
||||
func (v *JSONObject) KeySetSize() int {
|
||||
return v.ctms + v.ctmo + v.ctmarr + v.ctmn + v.ctmbln
|
||||
}
|
||||
|
||||
func (v *JSONObject) Map() map[string]string {
|
||||
return v.mAllkeys
|
||||
}
|
||||
|
||||
//---------- PUT ----------//
|
||||
|
||||
func (v *JSONObject) PutString(key string, value string) {
|
||||
if v.mAllkeys[key] == JSON_VAL_TYPE_OBJECT {
|
||||
v.RemoveJSONObject(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_ARRAY {
|
||||
v.RemoveJSONArray(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_INT {
|
||||
v.RemoveInt(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_BOOL {
|
||||
v.RemoveBool(key)
|
||||
}
|
||||
v.ms[key] = value
|
||||
v.ctms += 1
|
||||
v.hasVal = true
|
||||
|
||||
v.mAllkeys[key] = JSON_VAL_TYPE_STRING
|
||||
}
|
||||
|
||||
func (v *JSONObject) PutJSONObject(key string, value *JSONObject) {
|
||||
if v.mAllkeys[key] == JSON_VAL_TYPE_ARRAY {
|
||||
v.RemoveJSONArray(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_INT {
|
||||
v.RemoveInt(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_STRING {
|
||||
v.RemoveString(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_BOOL {
|
||||
v.RemoveBool(key)
|
||||
}
|
||||
v.mo[key] = value
|
||||
v.ctmo += 1
|
||||
v.hasVal = true
|
||||
|
||||
v.mAllkeys[key] = JSON_VAL_TYPE_OBJECT
|
||||
}
|
||||
|
||||
func (v *JSONObject) PutJSONArray(key string, value *JSONArray) {
|
||||
if v.mAllkeys[key] == JSON_VAL_TYPE_OBJECT {
|
||||
v.RemoveJSONObject(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_INT {
|
||||
v.RemoveInt(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_STRING {
|
||||
v.RemoveString(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_BOOL {
|
||||
v.RemoveBool(key)
|
||||
}
|
||||
v.marr[key] = value
|
||||
v.ctmarr += 1
|
||||
v.hasVal = true
|
||||
|
||||
v.mAllkeys[key] = JSON_VAL_TYPE_ARRAY
|
||||
}
|
||||
|
||||
func (v *JSONObject) PutInt(key string, value int) {
|
||||
if v.mAllkeys[key] == JSON_VAL_TYPE_OBJECT {
|
||||
v.RemoveJSONObject(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_ARRAY {
|
||||
v.RemoveJSONArray(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_STRING {
|
||||
v.RemoveString(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_BOOL {
|
||||
v.RemoveBool(key)
|
||||
}
|
||||
v.mn[key] = value
|
||||
v.ctmn += 1
|
||||
v.hasVal = true
|
||||
|
||||
v.mAllkeys[key] = JSON_VAL_TYPE_INT
|
||||
}
|
||||
|
||||
func (v *JSONObject) PutNumber(key string, value int) {
|
||||
v.PutInt(key, value)
|
||||
}
|
||||
|
||||
func (v *JSONObject) PutBool(key string, value bool) {
|
||||
if v.mAllkeys[key] == JSON_VAL_TYPE_OBJECT {
|
||||
v.RemoveJSONObject(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_ARRAY {
|
||||
v.RemoveJSONArray(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_STRING {
|
||||
v.RemoveString(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_INT {
|
||||
v.RemoveInt(key)
|
||||
}
|
||||
v.mbln[key] = value
|
||||
v.ctmbln += 1
|
||||
v.hasVal = true
|
||||
|
||||
v.mAllkeys[key] = JSON_VAL_TYPE_BOOL
|
||||
}
|
||||
|
||||
func (v *JSONObject) PutFloat(key string, value float64) {
|
||||
|
||||
if v.mAllkeys[key] == JSON_VAL_TYPE_OBJECT {
|
||||
v.RemoveJSONObject(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_ARRAY {
|
||||
v.RemoveJSONArray(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_STRING {
|
||||
v.RemoveString(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_INT {
|
||||
v.RemoveInt(key)
|
||||
} else if v.mAllkeys[key] == JSON_VAL_TYPE_BOOL {
|
||||
v.RemoveBool(key)
|
||||
}
|
||||
v.mflt64[key] = value
|
||||
v.ctmflt64 += 1
|
||||
v.hasVal = true
|
||||
|
||||
v.mAllkeys[key] = JSON_VAL_TYPE_FLOAT
|
||||
}
|
||||
|
||||
//---------- ACCUMULATE ----------//
|
||||
func (v *JSONObject) AccumulateJSONObject(key string, value *JSONObject) {
|
||||
|
||||
jsArr, err := v.GetJSONArray(key)
|
||||
if err != nil {
|
||||
v.RemoveString(key)
|
||||
v.RemoveJSONObject(key)
|
||||
|
||||
jsArr := NewJSONArray()
|
||||
jsArr.AddJSONObject(value)
|
||||
|
||||
v.PutJSONArray(key, jsArr)
|
||||
|
||||
} else {
|
||||
|
||||
jsArr.AddJSONObject(value)
|
||||
}
|
||||
}
|
||||
|
||||
//---------- GET ----------//
|
||||
func (v *JSONObject) GethasVal() bool {
|
||||
return v.hasVal
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetString(key string) (string, error) {
|
||||
if v.ctms > 0 {
|
||||
val, isContainsKey := v.ms[key]
|
||||
if isContainsKey {
|
||||
return val, nil
|
||||
}else{
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return "", errors.New("value not a string")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return "", errors.New("value not an string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetJSONObject(key string) (*JSONObject, error) {
|
||||
if v.ctmo > 0 {
|
||||
val, isContainsKey := v.mo[key]
|
||||
if isContainsKey {
|
||||
return val, nil
|
||||
}else{
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, errors.New("value not a JSONObject")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, errors.New("value not an JSONObject")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetJSONArray(key string) (*JSONArray, error) {
|
||||
if v.ctmarr > 0 {
|
||||
val, isContainsKey := v.marr[key]
|
||||
if isContainsKey {
|
||||
return val, nil
|
||||
}else{
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, errors.New("value not a JSONArray")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, errors.New("value not an JSONArray")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetInt(key string) (int, error) {
|
||||
if v.ctmn > 0 {
|
||||
val, isContainsKey := v.mn[key]
|
||||
if isContainsKey {
|
||||
return val, nil
|
||||
|
||||
}else{
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
} else {
|
||||
return -1, errors.New("value not an int")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
} else {
|
||||
return -1, errors.New("value not an int")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetNumber(key string) (int, error) {
|
||||
return v.GetInt(key)
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetBool(key string) (bool, error) {
|
||||
if v.ctmbln > 0 {
|
||||
val, isContainsKey := v.mbln[key]
|
||||
if isContainsKey {
|
||||
return val, nil
|
||||
}else{
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else {
|
||||
return false, errors.New("value not a bool")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else {
|
||||
return false, errors.New("value not a bool")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetFloat(key string) (float64, error) {
|
||||
if v.ctmflt64 > 0 {
|
||||
val, isContainsKey := v.mflt64[key]
|
||||
if isContainsKey {
|
||||
return val, nil
|
||||
}else{
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
} else {
|
||||
return -1, errors.New("value not a float")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
} else {
|
||||
return -1, errors.New("value not a float")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONObject) GetValType(key string) (string, error) {
|
||||
|
||||
if len(v.mAllkeys) > 0 {
|
||||
valType := v.mAllkeys[key]
|
||||
if len(valType) == 0 {
|
||||
return "", errors.New("key not found")
|
||||
} else {
|
||||
return valType, nil
|
||||
}
|
||||
} else {
|
||||
return "", errors.New("key not found")
|
||||
}
|
||||
}
|
||||
|
||||
//---------- func REMOVE ----------//
|
||||
func (v *JSONObject) RemoveString(key string) (error) {
|
||||
if v.ctms > 0 {
|
||||
_, isContainsKey := v.ms[key]
|
||||
if isContainsKey {
|
||||
delete(v.ms, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctms = len(v.ms)
|
||||
|
||||
}else{
|
||||
return v.genericRemove(key, "string")
|
||||
}
|
||||
} else {
|
||||
return v.genericRemove(key, "string")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) RemoveJSONObject(key string) (error) {
|
||||
if v.ctmo > 0 {
|
||||
_, isContainsKey := v.mo[key]
|
||||
if isContainsKey {
|
||||
delete(v.mo, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmo = len(v.mo)
|
||||
|
||||
}else{
|
||||
return v.genericRemove(key, "JSONObject")
|
||||
}
|
||||
} else {
|
||||
return v.genericRemove(key, "JSONObject")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) RemoveJSONArray(key string) (error) {
|
||||
if v.ctmarr > 0 {
|
||||
_, isContainsKey := v.marr[key]
|
||||
if isContainsKey {
|
||||
delete(v.marr, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmarr = len(v.marr)
|
||||
|
||||
}else{
|
||||
return v.genericRemove(key, "JSONArray")
|
||||
}
|
||||
} else {
|
||||
return v.genericRemove(key, "JSONArray")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) RemoveInt(key string) (error){
|
||||
if v.ctmn > 0 {
|
||||
_, isContainsKey := v.mn[key]
|
||||
if isContainsKey {
|
||||
delete(v.mn, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmn = len(v.mn)
|
||||
|
||||
}else{
|
||||
return v.genericRemove(key, "int")
|
||||
}
|
||||
} else {
|
||||
return v.genericRemove(key, "int")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) RemoveBool(key string) (error){
|
||||
if v.ctmbln > 0 {
|
||||
_, isContainsKey := v.mbln[key]
|
||||
if isContainsKey {
|
||||
delete(v.mbln, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmbln = len(v.mbln)
|
||||
|
||||
}else{
|
||||
return v.genericRemove(key, "bool")
|
||||
}
|
||||
} else {
|
||||
return v.genericRemove(key, "bool")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) RemoveFloat(key string) (error){
|
||||
if v.ctmflt64 > 0 {
|
||||
_, isContainsKey := v.mflt64[key]
|
||||
if isContainsKey {
|
||||
delete(v.mflt64, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmflt64 = len(v.mflt64)
|
||||
|
||||
}else{
|
||||
return v.genericRemove(key, "float")
|
||||
}
|
||||
} else {
|
||||
return v.genericRemove(key, "float")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) RemoveAny(key string) (error){
|
||||
_, isContainsKey := v.mAllkeys[key]
|
||||
if isContainsKey {
|
||||
valType, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
// delete appropriate collection
|
||||
switch valType {
|
||||
case JSON_VAL_TYPE_STRING:
|
||||
delete(v.ms, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctms = len(v.ms)
|
||||
case JSON_VAL_TYPE_BOOL:
|
||||
delete(v.mbln, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmbln = len(v.mbln)
|
||||
case JSON_VAL_TYPE_INT:
|
||||
delete(v.mn, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmn = len(v.mn)
|
||||
case JSON_VAL_TYPE_FLOAT:
|
||||
delete(v.mflt64, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmflt64 = len(v.mflt64)
|
||||
case JSON_VAL_TYPE_OBJECT:
|
||||
delete(v.mo, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmo = len(v.mo)
|
||||
case JSON_VAL_TYPE_ARRAY:
|
||||
delete(v.marr, key)
|
||||
delete(v.mAllkeys, key)
|
||||
v.ctmarr = len(v.marr)
|
||||
default:
|
||||
return errors.New("Invalid date type: " + valType)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return errors.New("key not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONObject) genericRemove(key string, msgSuffx string) (error){
|
||||
_, err := v.GetValType(key)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
return errors.New("value not a "+msgSuffx)
|
||||
}
|
||||
}
|
||||
|
||||
//---------- PRINT STRING----------//
|
||||
func (v *JSONObject) String() string {
|
||||
|
||||
var out string = "{"
|
||||
|
||||
if v.ctms > 0 {
|
||||
for keyms, _ := range v.ms {
|
||||
out += "\"" + keyms + "\":\"" + v.ms[keyms] + "\","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctmn > 0 {
|
||||
for keymn, _ := range v.mn {
|
||||
out += "\"" + keymn + "\":" + strconv.Itoa(v.mn[keymn]) + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctmo > 0 {
|
||||
for keymo, _ := range v.mo {
|
||||
jsObj := v.mo[keymo]
|
||||
out += "\"" + keymo + "\":" + jsObj.String() + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctmarr > 0 {
|
||||
for keymarr, _ := range v.marr {
|
||||
jsArr := v.marr[keymarr]
|
||||
out += "\"" + keymarr + "\":" + jsArr.String() + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctmbln > 0 {
|
||||
for keymbln, _ := range v.mbln {
|
||||
if v.mbln[keymbln] {
|
||||
out += "\"" + keymbln + "\":true,"
|
||||
}else{
|
||||
out += "\"" + keymbln + "\":false,"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctmflt64 > 0 {
|
||||
for keymflt64, _ := range v.mflt64 {
|
||||
out += "\"" + keymflt64 + "\":" + strconv.FormatFloat(v.mflt64[keymflt64], 'f', -1, 64 ) + ","
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasSuffix(out, ",") {
|
||||
out = out[0 : len(out)-1]
|
||||
}
|
||||
out += "}"
|
||||
return out
|
||||
}
|
||||
|
||||
func (v *JSONObject) StringJCS() string {
|
||||
|
||||
var out string = "{"
|
||||
var keys []string
|
||||
|
||||
keys = make([]string, 0, len(v.mAllkeys))
|
||||
for k := range v.mAllkeys {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
iLenKeys := len(keys)
|
||||
for idx := 0; idx < iLenKeys; idx++ {
|
||||
key := keys[idx]
|
||||
tmpVal := v.mAllkeys[key]
|
||||
|
||||
switch tmpVal {
|
||||
case JSON_VAL_TYPE_OBJECT:
|
||||
jsObj := v.mo[key]
|
||||
out += "\"" + key + "\":\"" + jsObj.StringJCS() + "\","
|
||||
case JSON_VAL_TYPE_ARRAY:
|
||||
jsArr := v.marr[key]
|
||||
out += "\"" + key + "\":" + jsArr.String() + ","
|
||||
case JSON_VAL_TYPE_BOOL:
|
||||
out += "\"" + key + "\":" + strconv.FormatBool(v.mbln[key]) + ","
|
||||
case JSON_VAL_TYPE_INT:
|
||||
out += "\"" + key + "\":" + strconv.Itoa(v.mn[key]) + ","
|
||||
case JSON_VAL_TYPE_FLOAT:
|
||||
out += "\"" + key + "\":" + strconv.FormatFloat(v.mflt64[key], 'f', -1, 64 ) + ","
|
||||
default:
|
||||
out += "\"" + key + "\":\"" + v.ms[key] + "\","
|
||||
}
|
||||
}
|
||||
if strings.HasSuffix(out, ",") {
|
||||
out = out[0 : len(out)-1]
|
||||
}
|
||||
out += "}"
|
||||
return out
|
||||
}
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
package jaeson
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type JSONArray struct {
|
||||
sarr []string
|
||||
oarr []*JSONObject
|
||||
aarr []*JSONArray
|
||||
narr []int
|
||||
blnarr []bool
|
||||
flt64arr []float64
|
||||
|
||||
ctsarr int
|
||||
ctoarr int
|
||||
ctaarr int
|
||||
ctnarr int
|
||||
ctblnarr int
|
||||
ctflt64arr int
|
||||
|
||||
hasVal bool
|
||||
}
|
||||
|
||||
func (v *JSONArray) Init() {
|
||||
v.ctsarr = 0
|
||||
v.ctoarr = 0
|
||||
v.ctaarr = 0
|
||||
v.ctnarr = 0
|
||||
v.ctblnarr = 0
|
||||
v.ctflt64arr = 0
|
||||
|
||||
v.sarr = make([]string, 0)
|
||||
v.oarr = make([]*JSONObject, 0)
|
||||
v.aarr = make([]*JSONArray, 0)
|
||||
v.narr = make([]int, 0)
|
||||
v.blnarr = make([]bool, 0)
|
||||
v.flt64arr = make([]float64, 0)
|
||||
|
||||
v.hasVal = false
|
||||
}
|
||||
|
||||
func (v *JSONArray) Size() int {
|
||||
return v.ctsarr + v.ctoarr + v.ctaarr + v.ctnarr
|
||||
}
|
||||
|
||||
//---------- ADD ----------//
|
||||
|
||||
func (v *JSONArray) AddString(value string) error {
|
||||
v.sarr = append(v.sarr, value)
|
||||
v.ctsarr += 1
|
||||
v.hasVal = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONArray) AddJSONObject(value *JSONObject) error {
|
||||
v.oarr = append(v.oarr, value)
|
||||
v.ctoarr += 1
|
||||
v.hasVal = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONArray) AddJSONArray(value *JSONArray) error {
|
||||
v.aarr = append(v.aarr, value)
|
||||
v.ctaarr += 1
|
||||
v.hasVal = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONArray) AddInt(value int) error {
|
||||
v.narr = append(v.narr, value)
|
||||
v.ctnarr += 1
|
||||
v.hasVal = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONArray) AddBool(value bool) error {
|
||||
v.blnarr = append(v.blnarr, value)
|
||||
v.ctblnarr += 1
|
||||
v.hasVal = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *JSONArray) AddFloat(value float64) error {
|
||||
v.flt64arr = append(v.flt64arr, value)
|
||||
v.ctflt64arr += 1
|
||||
v.hasVal = true
|
||||
return nil
|
||||
}
|
||||
|
||||
//---------- PUT ----------//
|
||||
|
||||
func (v *JSONArray) PutJSONObject(value *JSONObject) error {
|
||||
return v.AddJSONObject(value)
|
||||
}
|
||||
|
||||
func (v *JSONArray) PutString(value string) error {
|
||||
|
||||
return v.AddString(value)
|
||||
}
|
||||
|
||||
func (v *JSONArray) PutJSONArray(value *JSONArray) error {
|
||||
return v.AddJSONArray(value)
|
||||
}
|
||||
|
||||
func (v *JSONArray) PutInt(value int) error {
|
||||
|
||||
return v.AddInt(value)
|
||||
}
|
||||
|
||||
func (v *JSONArray) PutBool(value bool) error {
|
||||
|
||||
return v.AddBool(value)
|
||||
}
|
||||
|
||||
func (v *JSONArray) PutFloat(value float64) error {
|
||||
return v.AddFloat(value)
|
||||
}
|
||||
|
||||
//---------- GET ----------//
|
||||
|
||||
func (v *JSONArray) GethasVal() bool {
|
||||
return v.hasVal
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetString(index int) string {
|
||||
return v.sarr[index]
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetStringArray() []string {
|
||||
return v.sarr
|
||||
}
|
||||
|
||||
func (v *JSONArray) FromStringArray(pArr []string) {
|
||||
v.sarr = pArr
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetJSONObject(index int) (*JSONObject, error) {
|
||||
if index > -1 {
|
||||
if v.ctoarr > 0 {
|
||||
return v.oarr[index], nil
|
||||
} else {
|
||||
return nil, errors.New("index out of range: " + strconv.Itoa(index))
|
||||
}
|
||||
} else {
|
||||
return nil, errors.New("index out of range: " + strconv.Itoa(index))
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetJSONArray(index int) (*JSONArray, error) {
|
||||
if index > -1 {
|
||||
if v.ctaarr > 0 {
|
||||
return v.aarr[index], nil
|
||||
} else {
|
||||
return nil, errors.New("index out of range: " + strconv.Itoa(index))
|
||||
}
|
||||
} else {
|
||||
return nil, errors.New("index out of range: " + strconv.Itoa(index))
|
||||
}
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetInt(index int) int {
|
||||
return v.narr[index]
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetNumber(index int) int {
|
||||
return v.narr[index]
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetBool(index int) bool {
|
||||
return v.blnarr[index]
|
||||
}
|
||||
|
||||
func (v *JSONArray) GetFloat(index int) float64 {
|
||||
return v.flt64arr[index]
|
||||
}
|
||||
|
||||
func (v *JSONArray) RemoveLastElem() {
|
||||
if v.ctaarr > 0 {
|
||||
v.aarr = v.aarr[:len(v.aarr)-1]
|
||||
v.ctaarr -= 1
|
||||
|
||||
}else if v.ctoarr > 0 {
|
||||
v.oarr = v.oarr[:len(v.oarr)-1]
|
||||
v.ctoarr -= 1
|
||||
|
||||
}else if v.ctsarr > 0 {
|
||||
v.sarr = v.sarr[:len(v.sarr)-1]
|
||||
v.ctsarr -= 1
|
||||
|
||||
}else if v.ctnarr > 0 {
|
||||
v.narr = v.narr[:len(v.narr)-1]
|
||||
v.ctnarr -= 1
|
||||
}
|
||||
}
|
||||
|
||||
//---------- PRINT STRING----------//
|
||||
func (v *JSONArray) String() string {
|
||||
|
||||
var out string = "["
|
||||
|
||||
if v.ctsarr > 0 {
|
||||
for idx := range v.sarr {
|
||||
out += "\"" + v.sarr[idx] + "\","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctoarr > 0 {
|
||||
for idx, _ := range v.oarr {
|
||||
jsObj := v.oarr[idx]
|
||||
out += jsObj.String() + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctaarr > 0 {
|
||||
for idx, _ := range v.aarr {
|
||||
jsArr := v.aarr[idx]
|
||||
out += jsArr.String() + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctnarr > 0 {
|
||||
for idx, _ := range v.narr {
|
||||
out += strconv.Itoa(v.narr[idx]) + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctblnarr > 0 {
|
||||
for idx, _ := range v.blnarr {
|
||||
out += strconv.FormatBool(v.blnarr[idx]) + ","
|
||||
}
|
||||
}
|
||||
|
||||
if v.ctflt64arr > 0 {
|
||||
for idx, _ := range v.flt64arr {
|
||||
out += strconv.FormatFloat(v.flt64arr[idx], 'f', -1, 64 ) + ","
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasSuffix(out, ",") {
|
||||
out = out[0 : len(out)-1]
|
||||
}
|
||||
out += "]"
|
||||
return out
|
||||
}
|
||||
|
||||
//---------- PRINT STRING----------//
|
||||
// JSON Canonicalisation Scheme (JCS)
|
||||
func (v *JSONArray) StringJCS() string {
|
||||
var out string = "["
|
||||
|
||||
// TO BE IMPLEMENTED
|
||||
out += "]"
|
||||
return out
|
||||
}
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
package jaeson
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"gitea.cozeon.cloud/anand.ekka-ext/parser"
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
)
|
||||
|
||||
type stackElem struct {
|
||||
jsObj *JSONObject
|
||||
jsArr *JSONArray
|
||||
hasJsObj bool
|
||||
hasJsArr bool
|
||||
}
|
||||
|
||||
func (v *stackElem) Init() {
|
||||
v.hasJsObj = false
|
||||
v.hasJsArr = false
|
||||
}
|
||||
|
||||
func (v *stackElem) GetJsObj() *JSONObject {
|
||||
return v.jsObj
|
||||
}
|
||||
func (v *stackElem) GetJsArr() *JSONArray {
|
||||
return v.jsArr
|
||||
}
|
||||
|
||||
func (v *stackElem) GetHasJsObj() bool {
|
||||
return v.hasJsObj
|
||||
}
|
||||
func (v *stackElem) GetHasJsArr() bool {
|
||||
return v.hasJsArr
|
||||
}
|
||||
|
||||
func (v *stackElem) PutJSONObject(jsnObj *JSONObject) {
|
||||
v.hasJsObj = true
|
||||
v.hasJsArr = false
|
||||
v.jsObj = jsnObj
|
||||
}
|
||||
|
||||
func (v *stackElem) PutJSONArray(jsnArr *JSONArray) {
|
||||
v.hasJsObj = false
|
||||
v.hasJsArr = true
|
||||
v.jsArr = jsnArr
|
||||
}
|
||||
|
||||
type jsonListener struct {
|
||||
*parser.BaseJSONListener
|
||||
|
||||
topJsObj *JSONObject
|
||||
|
||||
currJsObj *JSONObject
|
||||
currJsArr *JSONArray
|
||||
currKey string
|
||||
|
||||
childJsObj *JSONObject
|
||||
childJsArr *JSONArray
|
||||
|
||||
foundKeyOfPair bool
|
||||
jsonStartFound bool
|
||||
topObjCreated bool
|
||||
arrStart bool
|
||||
|
||||
parentObjStack []*stackElem
|
||||
|
||||
stckElemPointer int
|
||||
|
||||
topJsArr *JSONArray
|
||||
topArrCreated bool
|
||||
}
|
||||
|
||||
func (s *jsonListener) GetLastElem() *stackElem {
|
||||
return s.parentObjStack[s.stckElemPointer-1]
|
||||
}
|
||||
|
||||
func (s *jsonListener) DeleteLastElem() {
|
||||
s.parentObjStack[s.stckElemPointer-1] = nil
|
||||
s.stckElemPointer -= 1
|
||||
}
|
||||
|
||||
func (s *jsonListener) AddJSONObjToStack(jsObj *JSONObject) {
|
||||
tmpStckElem := new(stackElem)
|
||||
tmpStckElem.Init()
|
||||
s.stckElemPointer += 1
|
||||
|
||||
if s.stckElemPointer > len(s.parentObjStack) {
|
||||
s.parentObjStack = append(s.parentObjStack, tmpStckElem)
|
||||
} else {
|
||||
s.parentObjStack[s.stckElemPointer-1] = tmpStckElem
|
||||
}
|
||||
|
||||
tmpStckElem.PutJSONObject(jsObj)
|
||||
}
|
||||
|
||||
func (s *jsonListener) AddJSONArrToStack(jsArr *JSONArray) {
|
||||
tmpStckElem := new(stackElem)
|
||||
tmpStckElem.Init()
|
||||
s.stckElemPointer += 1
|
||||
|
||||
if s.stckElemPointer > len(s.parentObjStack) {
|
||||
s.parentObjStack = append(s.parentObjStack, tmpStckElem)
|
||||
} else {
|
||||
s.parentObjStack[s.stckElemPointer-1] = tmpStckElem
|
||||
}
|
||||
|
||||
tmpStckElem.PutJSONArray(jsArr)
|
||||
}
|
||||
|
||||
//--------------- Json Enter-Exit ---------------//
|
||||
func (s *jsonListener) EnterJson(ctx *parser.JsonContext) {
|
||||
s.jsonStartFound = true
|
||||
s.topObjCreated = false
|
||||
s.stckElemPointer = 0
|
||||
}
|
||||
|
||||
func (s *jsonListener) ExitJson(ctx *parser.JsonContext) {
|
||||
// nothing needs to be implemented
|
||||
}
|
||||
|
||||
//--------------- Obj Enter-Exit ---------------//
|
||||
func (s *jsonListener) EnterObj(ctx *parser.ObjContext) {
|
||||
|
||||
if !s.topObjCreated && !s.topArrCreated {
|
||||
s.topJsObj = new(JSONObject)
|
||||
s.topJsObj.Init()
|
||||
s.currJsObj = s.topJsObj
|
||||
s.foundKeyOfPair = false
|
||||
|
||||
s.topObjCreated = true
|
||||
s.arrStart = false
|
||||
|
||||
//initialize stack
|
||||
s.parentObjStack = make([]*stackElem, 0)
|
||||
|
||||
//Add topJsObj to stack
|
||||
s.AddJSONObjToStack(s.topJsObj)
|
||||
|
||||
} else {
|
||||
|
||||
s.childJsObj = new(JSONObject)
|
||||
s.childJsObj.Init()
|
||||
|
||||
if s.arrStart {
|
||||
s.currJsArr.PutJSONObject(s.childJsObj)
|
||||
s.AddJSONArrToStack(s.currJsArr)
|
||||
s.currJsObj = s.childJsObj
|
||||
s.arrStart = false
|
||||
|
||||
} else {
|
||||
s.currJsObj.PutJSONObject(s.currKey, s.childJsObj)
|
||||
|
||||
// might need stack up or append curr object in a LIFO stack,
|
||||
// before takig on the new child object
|
||||
s.AddJSONObjToStack(s.currJsObj)
|
||||
|
||||
s.currJsObj = s.childJsObj
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *jsonListener) ExitObj(ctx *parser.ObjContext) {
|
||||
|
||||
tmpPrevStckElem := s.GetLastElem()
|
||||
|
||||
if tmpPrevStckElem != nil {
|
||||
if tmpPrevStckElem.GetHasJsObj() {
|
||||
s.currJsObj = tmpPrevStckElem.GetJsObj()
|
||||
s.arrStart = false
|
||||
|
||||
} else {
|
||||
s.currJsArr = tmpPrevStckElem.GetJsArr()
|
||||
s.arrStart = true
|
||||
}
|
||||
s.DeleteLastElem()
|
||||
|
||||
} //else {
|
||||
// nothing needs to be implemented
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
//--------------- Arr Enter-Exit ---------------//
|
||||
|
||||
// EnterArr is called when production arr is entered.
|
||||
func (s *jsonListener) EnterArr(ctx *parser.ArrContext) {
|
||||
|
||||
if !s.topObjCreated && !s.topArrCreated {
|
||||
|
||||
s.topJsArr = new(JSONArray)
|
||||
s.topJsArr.Init()
|
||||
s.currJsArr = s.topJsArr
|
||||
|
||||
s.topArrCreated = true
|
||||
s.arrStart = true
|
||||
|
||||
//initialize stack
|
||||
s.parentObjStack = make([]*stackElem, 0)
|
||||
|
||||
//Add topJsArr to stack
|
||||
s.AddJSONArrToStack(s.topJsArr)
|
||||
|
||||
} else {
|
||||
|
||||
if s.arrStart {
|
||||
|
||||
s.childJsArr = new(JSONArray)
|
||||
s.childJsArr.Init()
|
||||
|
||||
//add currJsArr to stack
|
||||
s.AddJSONArrToStack(s.currJsArr)
|
||||
s.currJsArr.PutJSONArray(s.childJsArr)
|
||||
s.currJsArr = s.childJsArr
|
||||
|
||||
} else {
|
||||
|
||||
s.currJsArr = new(JSONArray)
|
||||
s.currJsArr.Init()
|
||||
s.currJsObj.PutJSONArray(s.currKey, s.currJsArr)
|
||||
s.AddJSONObjToStack(s.currJsObj)
|
||||
}
|
||||
}
|
||||
s.arrStart = true
|
||||
}
|
||||
|
||||
// ExitArr is called when production arr is exited.
|
||||
func (s *jsonListener) ExitArr(ctx *parser.ArrContext) {
|
||||
s.arrStart = false
|
||||
|
||||
tmpPrevStckElem := s.GetLastElem()
|
||||
if tmpPrevStckElem.GetHasJsObj() {
|
||||
s.currJsObj = tmpPrevStckElem.GetJsObj()
|
||||
s.arrStart = false
|
||||
|
||||
} else {
|
||||
s.currJsArr = tmpPrevStckElem.GetJsArr()
|
||||
s.arrStart = true
|
||||
}
|
||||
s.DeleteLastElem()
|
||||
}
|
||||
|
||||
//--------------- Pair Enter-Exit ---------------//
|
||||
|
||||
func (s *jsonListener) EnterPair(ctx *parser.PairContext) {
|
||||
s.foundKeyOfPair = true
|
||||
s.currKey = ctx.STRING().GetSymbol().GetText()
|
||||
s.currKey = s.currKey[1 : len(s.currKey)-1]
|
||||
}
|
||||
|
||||
func (s *jsonListener) ExitPair(ctx *parser.PairContext) {
|
||||
s.foundKeyOfPair = false
|
||||
}
|
||||
|
||||
//--------------- Value Enter-Exit ---------------//
|
||||
|
||||
func (s *jsonListener) EnterValue(ctx *parser.ValueContext) {
|
||||
|
||||
if ctx.STRING() != nil {
|
||||
val0 := ctx.STRING().GetSymbol().GetText()
|
||||
val1 := val0[1 : len(val0)-1]
|
||||
|
||||
if s.arrStart {
|
||||
s.currJsArr.PutString(val1)
|
||||
} else {
|
||||
s.currJsObj.PutString(s.currKey, val1)
|
||||
}
|
||||
|
||||
}else if ctx.NUMBER() != nil {
|
||||
val0 := ctx.NUMBER().GetSymbol().GetText()
|
||||
vali, erri := strconv.ParseInt(val0, 10, 64)
|
||||
if erri != nil {
|
||||
valf, errf := strconv.ParseFloat(val0, 64)
|
||||
if errf == nil {
|
||||
s.currJsObj.PutFloat(s.currKey, valf)
|
||||
} else {
|
||||
// neither int nor float. then what is it ?
|
||||
}
|
||||
}else{
|
||||
s.currJsObj.PutInt(s.currKey, int(vali))
|
||||
}
|
||||
|
||||
//s.currJsObj.PutInt(s.currKey, val1)
|
||||
|
||||
}else if ctx.Obj() != nil {
|
||||
// nothing needs to be implemented
|
||||
|
||||
}else if ctx.BOOLEAN() != nil {
|
||||
|
||||
val0 := ctx.BOOLEAN().GetSymbol().GetText()
|
||||
val1, _ := strconv.ParseBool(val0)
|
||||
s.currJsObj.PutBool(s.currKey, val1)
|
||||
}
|
||||
s.foundKeyOfPair = false
|
||||
}
|
||||
|
||||
func (s *jsonListener) ExitValue(ctx *parser.ValueContext) {
|
||||
// nothing needs to be implemented
|
||||
}
|
||||
|
||||
func UnmarshalJSON(jsonstr string) (*JSONObject, *JSONArray) {
|
||||
|
||||
is := antlr.NewInputStream(jsonstr)
|
||||
|
||||
// Create the Lexer
|
||||
lexer := parser.NewJSONLexer(is)
|
||||
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||
|
||||
// Create the Parser
|
||||
p := parser.NewJSONParser(stream)
|
||||
|
||||
// Finally parse the expression
|
||||
var jsonLstnr *jsonListener = new(jsonListener)
|
||||
antlr.ParseTreeWalkerDefault.Walk(jsonLstnr, p.Json())
|
||||
|
||||
if jsonLstnr.topObjCreated {
|
||||
return jsonLstnr.topJsObj, nil
|
||||
|
||||
} else {
|
||||
return nil, jsonLstnr.topJsArr
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user