JSON - an approximation of inheritance?

Share your advanced PureBasic knowledge/code with the community.
User avatar
the.weavster
Addict
Addict
Posts: 1537
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

JSON - an approximation of inheritance?

Post by the.weavster »

First an include file (ezjson.pb) that contains some wrappers that (imo) make creating and adding to JSON objects easier:

Code: Select all

;-ezjson.pb
;-Just some wrappers for creating json members
;-
Procedure.i json_NewRoot()
  Static nRef
  nRef + 1
  CreateJSON(nRef)
  ProcedureReturn nRef
EndProcedure

Procedure json_FreeItem(jsr)
  If IsJSON(jsr) : FreeJSON(jsr) : EndIf
EndProcedure

Procedure.s json_PrettyPrint(jsr)
  ProcedureReturn ComposeJSON(jsr,#PB_JSON_PrettyPrint)
EndProcedure

Procedure.i json_Member(jso,key$)
  nJM = jso
  If key$ = ""
    ; we've been passed the member directly so just pass through
  Else
    ; we've been passed the parent, use the key to find/create the child
    nJM = GetJSONMember(jso,key$)
    If Not nJM
      nJM = AddJSONMember(jso,key$)
    EndIf
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Array(jso,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONArray(nJM)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Boolean(jso,bval,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONBoolean(nJM,bval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Double(jso,dval.d,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONDouble(nJM,dval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Float(jso,fval.f,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONFloat(nJM,fval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Integer(jso,ival,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONInteger(nJM,ival)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Null(jso,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONNull(nJM)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Object(jso,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONObject(nJM)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_Quad(jso,qval.q,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONQuad(nJM,qval)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure.i json_String(jso,sval$,key$="")
  nJM = json_Member(jso,key$)
  If nJM
    SetJSONString(nJM,sval$)
  EndIf
  ProcedureReturn nJM
EndProcedure

Procedure json_Clone(jso,jSrc,key$="")
  jDest = json_Member(jso,key$)
  Select JSONType(jSrc)
    Case #PB_JSON_Null:   
      SetJSONNull(jDest)
    Case #PB_JSON_String: 
      SetJSONString(jDest,GetJSONString(jSrc))
    Case #PB_JSON_Number:
      SetJSONDouble(jDest,GetJSONDouble(jSrc))
    Case #PB_JSON_Boolean:
      SetJSONBoolean(jDest,GetJSONBoolean(jSrc))
    Case #PB_JSON_Array:
      len = JSONArraySize(jSrc)
      SetJSONArray(jDest)
      For i = 0 To (len - 1)
        ja = GetJSONElement(jSrc,i)
        ca = AddJSONElement(jDest)
        json_Clone(ca,ja)
      Next
    Case #PB_JSON_Object:
      SetJSONObject(jDest)
      If ExamineJSONMembers(jSrc)
        While NextJSONMember(jSrc)
          k$ = JSONMemberKey(jSrc)
          jo = JSONMemberValue(jSrc)
          co = AddJSONMember(jDest,k$)
          json_Clone(co,jo)
        Wend
      EndIf
 EndSelect
EndProcedure
And an example showing how JSON's ability to morph can be fun:

Code: Select all

XIncludeFile "ezjson.pb"

;-
;-Person methods
;-
Procedure.i Person_New(jsr,first$,last$)
  jso = json_Object(JSONValue(jsr))
  json_String(jso,first$,"firstname")
  json_String(jso,last$,"lastname")
  json_Array(jso,"offspring")
  ProcedureReturn jso
EndProcedure

Procedure Person_AddChild(pjso,cjso,takeControl=-1)
  nE = AddJSONElement(json_Member(pjso,"offspring"))
  nO = json_Object(nE)
  json_Clone(nO,cjso)
  If takeControl <> -1
    json_FreeItem(takeControl)
  EndIf
  ProcedureReturn nO
EndProcedure

Procedure.s Person_GetName(jso)
  fn$ = GetJSONString(json_Member(jso,"firstname"))
  ln$ = GetJSONString(json_Member(jso,"lastname"))
  ProcedureReturn fn$ + " " + ln$
EndProcedure

Procedure Person_SetName(jso,first$,last$)
  json_String(jso,first$,"firstname")
  json_String(jso,last$,"lastname")
EndProcedure

;-
;-Teacher methods
;-
Procedure.i Teacher_New(jsr,first$,last$,subject$)
  ; start by creating a new person
  jso = Person_New(jsr,first$,last$)
  ; and then add more members
  json_String(jso,subject$,"subject")
  ProcedureReturn jso
EndProcedure

Procedure.s Teacher_GetDetails(jso)
  ; get the Person name
  nm$ = Person_GetName(jso)
  ; and add the additional Teacher data
  sn$ = GetJSONString(json_Member(jso,"subject"))
  ProcedureReturn nm$ + ", " + sn$
EndProcedure

;-
;-And a demo of usage
;-
AbeRef = json_NewRoot()
HomerRef = json_NewRoot()
BartRef = json_NewRoot()

AbeObj = Person_New(AbeRef,"Abe","Simpson")
HomerObj = Person_New(HomerRef,"Homer","Simpson")
BartObj = Person_New(BartRef,"Bart","Simpson")

HomerObj = Person_AddChild(AbeObj,HomerObj,HomerRef) ; HomerObj now points to a sub object of AbeObj and HomerRef is freed
BartObj = Person_AddChild(HomerObj,BartObj,BartRef) ; BartObj now points to a sub object of HomerObj and BartRef is freed
Debug json_PrettyPrint(AbeRef)
Debug ""

; show we can edit the child object
Person_SetName(BartObj,"Maggie","Simpson")
Debug Person_GetName(BartObj)
Debug ""
Debug json_PrettyPrint(AbeRef)
Debug ""

; create an instance of Teacher
EdnaRef = json_NewRoot()
EdnaObj = Teacher_New(EdnaRef,"Edna","Krabappel","English")
Debug Teacher_GetDetails(EdnaObj)

; because a Teacher is based on a Person
; we can pass a Teacher instance to Person methods
Debug Person_GetName(EdnaObj)

json_FreeItem(AbeRef)
json_FreeItem(EdnaRef)