1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/lutianming-ljson

Клонировать/Скачать
ljson.go 12 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
lutianming Отправлено 18.09.2022 08:10 4d086f9
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
/*
this is a json library like cjson, auhtor:lutianming date:2021-08-03
*/
package ljson
import (
"strconv"
)
const (
Json_Invalid = 0
Json_NIL = 1 << 0
Json_Bool = 1 << 1
Json_Number = 1 << 2
Json_String = 1 << 3
Json_Array = 1 << 4
Json_Object = 1 << 5
)
type Json struct {
next *Json
prev *Json
child *Json
Type int8
Valuebool bool
Valuestring string
Valuenumber int64
Valuefloat float64
Name string
}
type gbuffer struct {
str []byte
length int
offset int
}
func add_to_tail(node *Json, item *Json) {
if node.child == nil {
node.child = item
item.next = item
item.prev = item
return
}
head := node.child
prev := head.prev
item.next = head
item.prev = prev
prev.next = item
head.prev = item
}
func can_read(buffer *gbuffer, size int) bool {
return buffer.offset+size <= buffer.length
}
func buffer_get_pos(buffer *gbuffer, b byte) int {
for pos := buffer.offset; pos < buffer.length; pos++ {
if buffer.str[pos] == b {
return pos
}
}
return -1
}
func buffer_skip_whitespace(buffer *gbuffer) {
var pos int
for pos = buffer.offset; pos < buffer.length; pos++ {
chr := buffer.str[pos]
if chr > 32 {
break
}
}
buffer.offset = pos
}
func bytescmp(buffer *gbuffer, size int, a string) bool {
if can_read(buffer, size) == false {
return false
}
b := []byte(a)
for i := 0; i < size; i++ {
pos := buffer.offset + i
if buffer.str[pos] != b[i] {
return false
}
}
return true
}
func bytecmp(buffer *gbuffer, b byte) bool {
if can_read(buffer, 1) == false {
return false
}
pos := buffer.offset
if buffer.str[pos] == b {
return true
}
return false
}
func parse_nil(node *Json, buffer *gbuffer) bool {
node.Type = Json_NIL
buffer.offset += 4
return true
}
func parse_bool(node *Json, buffer *gbuffer, size int) bool {
node.Type = Json_Bool
if size == 4 {
node.Valuebool = true
} else {
node.Valuebool = false
}
buffer.offset += size
return true
}
func parse_string(node *Json, buffer *gbuffer) bool {
node.Type = Json_String
buffer.offset++
for pos := buffer.offset; pos < buffer.length; pos++ {
if buffer.str[pos] == '"' {
node.Valuestring = string(buffer.str[buffer.offset:pos])
buffer.offset = pos + 1
return true
}
}
return false
}
func parse_number(node *Json, buffer *gbuffer) bool {
node.Type = Json_Number
for pos := buffer.offset; pos < buffer.length; pos++ {
if buffer.str[pos] == ' ' || buffer.str[pos] == ',' || buffer.str[pos] == ']' || buffer.str[pos] == '}' {
number, _ := strconv.ParseInt(string(buffer.str[buffer.offset:pos]), 10, 64)
//numver_float, _ := strconv.ParseFloat(string(buffer.str[buffer.offset:pos]), 64)
node.Valuenumber = number
//node.Valuefloat = numver_float
buffer.offset = pos
return true
}
}
return false
}
func parse_array(node *Json, buffer *gbuffer) bool {
node.Type = Json_Array
buffer.offset++
buffer_skip_whitespace(buffer)
for {
if buffer.offset >= buffer.length {
return false
}
if bytecmp(buffer, ']') {
buffer.offset++
return true
} else {
item := new(Json)
if parse_value(item, buffer) == false {
return false
}
add_to_tail(node, item)
buffer_skip_whitespace(buffer)
if bytecmp(buffer, ',') {
buffer.offset++
buffer_skip_whitespace(buffer)
}
}
}
}
func parse_key(node *Json, buffer *gbuffer) bool {
pos := buffer_get_pos(buffer, '"')
if pos > buffer.offset {
node.Name = string(buffer.str[buffer.offset:pos])
buffer.offset = pos + 1
return true
}
return false
}
func parse_object(node *Json, buffer *gbuffer) bool {
node.Type = Json_Object
buffer.offset++
buffer_skip_whitespace(buffer)
for {
if buffer.offset >= buffer.length {
return false
}
if bytecmp(buffer, '}') {
buffer.offset++
return true
} else if bytecmp(buffer, '"') {
item := new(Json)
buffer.offset++
if parse_key(item, buffer) == false {
return false
}
pos := buffer_get_pos(buffer, ':')
if pos < 0 {
return false
}
buffer.offset = pos + 1
if parse_value(item, buffer) == false {
return false
}
add_to_tail(node, item)
buffer_skip_whitespace(buffer)
if bytecmp(buffer, ',') {
buffer.offset++
buffer_skip_whitespace(buffer)
}
} else {
return false
}
}
}
func parse_value(node *Json, buffer *gbuffer) bool {
buffer_skip_whitespace(buffer)
if bytecmp(buffer, '{') {
return parse_object(node, buffer)
} else if bytecmp(buffer, '[') {
return parse_array(node, buffer)
} else if (buffer.str[buffer.offset] >= '0' && buffer.str[buffer.offset] <= '9') || buffer.str[buffer.offset] == '-' {
return parse_number(node, buffer)
} else if bytecmp(buffer, '"') {
return parse_string(node, buffer)
} else if bytescmp(buffer, 4, "null") {
return parse_nil(node, buffer)
} else if bytescmp(buffer, 5, "false") {
return parse_bool(node, buffer, 5)
} else if bytescmp(buffer, 4, "true") {
return parse_bool(node, buffer, 4)
}
return false
}
func ParseString(str string) *Json {
buffer := new(gbuffer)
buffer.str = []byte(str)
buffer.length = len(str)
buffer.offset = 0
node := new(Json)
if parse_value(node, buffer) == false {
print("ljson error: offset[", buffer.offset, "]\tnear:", string(buffer.str[buffer.offset:]), "\n")
return nil
}
return node
}
func ParseBytes(bytes []byte, n int) *Json {
buffer := new(gbuffer)
buffer.str = bytes
buffer.length = n
buffer.offset = 0
node := new(Json)
if parse_value(node, buffer) == false {
print("ljson error: offset[", buffer.offset, "]\tnear:", string(buffer.str[buffer.offset:]), "\n")
return nil
}
return node
}
func print_need_buffer(buffer *gbuffer, count int) {
if buffer.length-buffer.offset < count {
newlen := buffer.length * 2
newbyte := make([]byte, newlen)
copy(newbyte, buffer.str)
buffer.str = newbyte
buffer.length = newlen
}
}
func print_nil(node *Json, buffer *gbuffer) {
print_need_buffer(buffer, 4)
value := []byte("null")
for i := 0; i < 4; i++ {
buffer.str[buffer.offset+i] = value[i]
}
buffer.offset += 4
}
func print_bool(node *Json, buffer *gbuffer) {
if node.Valuebool {
print_need_buffer(buffer, 4)
value := []byte("true")
for i := 0; i < 4; i++ {
buffer.str[buffer.offset+i] = value[i]
}
buffer.offset += 4
} else {
print_need_buffer(buffer, 5)
value := []byte("false")
for i := 0; i < 5; i++ {
buffer.str[buffer.offset+i] = value[i]
}
buffer.offset += 5
}
}
func print_string(node *Json, buffer *gbuffer) {
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '"'
buffer.offset++
value := []byte(node.Valuestring)
len := len(node.Valuestring)
print_need_buffer(buffer, len)
for i := 0; i < len; i++ {
buffer.str[buffer.offset+i] = value[i]
}
buffer.offset += len
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '"'
buffer.offset++
}
func print_number(node *Json, buffer *gbuffer) {
valuestr := strconv.FormatInt(node.Valuenumber, 10)
value := []byte(valuestr)
len := len(valuestr)
print_need_buffer(buffer, len)
for i := 0; i < len; i++ {
buffer.str[buffer.offset+i] = value[i]
}
buffer.offset += len
}
func print_key(node *Json, buffer *gbuffer) {
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '"'
buffer.offset++
value := []byte(node.Name)
len := len(node.Name)
print_need_buffer(buffer, len)
for i := 0; i < len; i++ {
buffer.str[buffer.offset+i] = value[i]
}
buffer.offset += len
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '"'
buffer.offset++
}
func print_array(node *Json, buffer *gbuffer) {
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '['
buffer.offset++
var head *Json = node.child
var item *Json = head
for {
if item == nil {
break
}
print_value(item, buffer)
if item.next != head {
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = ','
buffer.offset++
}
item = item.next
if item == head {
break
}
}
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = ']'
buffer.offset++
}
func print_object(node *Json, buffer *gbuffer) {
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '{'
buffer.offset++
var head *Json = node.child
var item *Json = head
for {
if item == nil {
break
}
print_key(item, buffer)
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = ':'
buffer.offset++
print_value(item, buffer)
if item.next != head {
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = ','
buffer.offset++
}
item = item.next
if item == head {
break
}
}
print_need_buffer(buffer, 1)
buffer.str[buffer.offset] = '}'
buffer.offset++
}
func print_value(node *Json, buffer *gbuffer) {
if node.Type == Json_NIL {
print_nil(node, buffer)
} else if node.Type == Json_Bool {
print_bool(node, buffer)
} else if node.Type == Json_String {
print_string(node, buffer)
} else if node.Type == Json_Number {
print_number(node, buffer)
} else if node.Type == Json_Array {
print_array(node, buffer)
} else if node.Type == Json_Object {
print_object(node, buffer)
}
}
func (node *Json) String() string {
buffer := new(gbuffer)
buffer.str = make([]byte, 5120)
buffer.length = 5120
buffer.offset = 0
print_value(node, buffer)
return string(buffer.str[:buffer.offset])
}
func (node *Json) Bytes() ([]byte, int) {
buffer := new(gbuffer)
buffer.str = make([]byte, 5120)
buffer.length = 5120
buffer.offset = 0
print_value(node, buffer)
return buffer.str, buffer.offset
}
func (node *Json) IsBool() bool {
if node.Type == Json_Bool {
return true
}
return false
}
func (node *Json) IsString() bool {
if node.Type == Json_String {
return true
}
return false
}
func (node *Json) IsNumber() bool {
if node.Type == Json_Number {
return true
}
return false
}
func (node *Json) IsArray() bool {
if node.Type == Json_Array {
return true
}
return false
}
func (node *Json) IsObject() bool {
if node.Type == Json_Object {
return true
}
return false
}
func CreateBoolObject(value bool) *Json {
node := new(Json)
node.Type = Json_Bool
node.Valuebool = value
return node
}
func CreateStringObject(value string) *Json {
node := new(Json)
node.Type = Json_String
node.Valuestring = value
return node
}
func CreateNumberObject(value int64) *Json {
node := new(Json)
node.Type = Json_Number
node.Valuenumber = value
return node
}
func CreateObject() *Json {
node := new(Json)
node.Type = Json_Object
return node
}
func CreateArray() *Json {
node := new(Json)
node.Type = Json_Array
return node
}
func (node *Json) ObjectAddBool(key string, value bool) {
item := CreateBoolObject(value)
item.Name = key
add_to_tail(node, item)
}
func (node *Json) ObjectAddString(key string, value string) {
item := CreateStringObject(value)
item.Name = key
add_to_tail(node, item)
}
func (node *Json) ObjectAddNumber(key string, value int64) {
item := CreateNumberObject(value)
item.Name = key
add_to_tail(node, item)
}
func (node *Json) ObjectAddItem(key string, item *Json) {
item.Name = key
add_to_tail(node, item)
}
func (node *Json) ArrayAddBool(value bool) {
item := CreateBoolObject(value)
add_to_tail(node, item)
}
func (node *Json) ArrayAddString(value string) {
item := CreateStringObject(value)
add_to_tail(node, item)
}
func (node *Json) ArrayAddNumber(value int64) {
item := CreateNumberObject(value)
add_to_tail(node, item)
}
func (node *Json) ArrayAddItem(item *Json) {
add_to_tail(node, item)
}
func (node *Json) GetSize() int {
size := 0
head := node.child
if head == nil {
return size
}
var item *Json = head
for {
size++
if item.next == head {
break
}
item = item.next
}
return size
}
func (node *Json) ArrayGetItem(index int) *Json {
head := node.child
if head == nil {
return nil
}
var item *Json = head
for i := 0; i < index; i++ {
item = item.next
}
return item
}
func (node *Json) ObjectGetItem(key string) *Json {
head := node.child
if head == nil {
return nil
}
var item *Json = head
for {
if item.Name == key {
return item
}
if item.next == head {
break
}
item = item.next
}
return nil
}
func (node *Json) ItemNext(iter *Json) *Json {
if iter == nil {
return node.child
}
if iter.next == node.child {
return nil
}
return iter.next
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/lutianming-ljson.git
git@api.gitlife.ru:oschina-mirror/lutianming-ljson.git
oschina-mirror
lutianming-ljson
lutianming-ljson
master