BlitzMax

BlitzMax

  • Downloads
  • Docs
  • API
  • Resources
  • About

›JConv

BlitzMax API

  • Introduction

BRL

    Audio

    • Introduction
    • TChannel
    • TSound

    AudioSample

    • Introduction
    • TAudioSample
    • TAudioSampleLoader

    Bank

    • Introduction
    • TBank

    BankStream

    • Introduction
    • TBankStream

    Base64

    • Introduction
    • TBase64

    Blitz

    • Introduction
    • TArrayBoundsException
    • TBlitzException
    • TNullFunctionException
    • TNullMethodException
    • TNullObjectException
    • TOutOfDataException
    • TRuntimeException
  • BRL.BMPLoader
  • Clipboard

    • Introduction
    • TClipboard
    • TClipboardOpts
    • TWin32ClipboardOpts
    • TX11ClipboardOpts
  • BRL.D3D7Max2D
  • BRL.D3D9Max2D
  • BRL.DirectSoundAudio
  • BRL.EndianStream
  • Event

    • Introduction
    • TEvent
  • BRL.EventQueue
  • BRL.FileSystem
  • BRL.FreeAudioAudio
  • BRL.GLGraphics
  • BRL.GLMax2D
  • BRL.GNet
  • BRL.Graphics
  • BRL.Hook
  • IO

    • Introduction
    • MaxIO
  • BRL.JPGLoader
  • BRL.KeyCodes
  • LinkedList

    • Introduction
    • TList
    • TListEnum
    • TLink

    Map

    • Introduction
    • TMap
    • TIntMap
    • TIntKey
    • TPtrMap
    • TPtrKey
    • TStringMap
  • BRL.Math
  • Matrix

    • Introduction
    • SMat2D
    • SMat2F
    • SMat2I
    • SMat3D
    • SMat3F
    • SMat3I
    • SMat4D
    • SMat4F
    • SMat4I

    Max2D

    • Introduction
    • TImage

    MaxLua

    • Introduction
    • TLuaClass
    • TLuaObject
  • BRL.OGGLoader
  • BRL.OpenALAudio
  • ObjectList

    • Introduction
    • TObjectList
    • TObjectListEnumerator
    • TObjectListReverseEnumerator

    Pixmap

    • Introduction
    • TPixmap
    • TPixmapLoader
  • BRL.PNGLoader
  • BRL.PolledInput
  • Quaternion

    • Introduction
    • SQuatD
    • SQuatF
    • SQuatI
  • BRL.RamStream
  • Random

    • Introduction
    • TRandom

    Reflection

    • Introduction
    • TTypeId
    • TMember
    • TConstant
    • TField
    • TGlobal
    • TFunction
    • TMethod
  • BRL.Retro
  • BRL.Socket
  • BRL.SocketStream
  • BRL.StandardIO
  • Stream

    • Introduction
    • TCStream
    • TIO
    • TStream
    • TStreamException
    • TStreamFactory
    • TStreamReadException
    • TStreamWrapper
    • TStreamWriteException

    StringBuilder

    • Introduction
    • TStringBuilder
    • TSplitBuffer
  • BRL.System
  • BRL.SystemDefault
  • BRL.TextStream
  • BRL.TGALoader
  • ThreadPool

    • Introduction
    • TRunnable
    • TThreadPoolExecutor

    Threads

    • Introduction
    • TThread
    • TThreadData
    • TMutex
    • TSemaphore
    • TCondVar

    Timer

    • Introduction
    • TChrono
  • BRL.TimerDefault
  • Vector

    • Introduction
    • SVec2D
    • SVec2F
    • SVec2I
    • SVec3D
    • SVec3F
    • SVec3I
    • SVec4D
    • SVec4F
    • SVec4I

    Volumes

    • Introduction
    • TVolume
  • BRL.WAVLoader

Text

    CSV

    • Introduction
    • TCsvParser
    • TCsvHeader
    • TCsvRow
    • TCsvOptions
    • SCsvColumn

    Format

    • Introduction
    • TFormatter

    Ini

    • Introduction
    • TIni
    • TIniProperty
    • TIniSection

    JConv

    • Introduction
    • TJConv
    • TJConvBuilder
    • TJConvSerializer

    Json

    • Introduction
    • TJSON
    • TJSONObject
    • TJSONString
    • TJSONInteger
    • TJSONReal
    • TJSONBool
    • TJSONArray
    • TJSONNull
    • TJSONError
    • TJSONNumber

    Regex

    • Introduction
    • TRegEx
    • TRegExMatch
    • TRegExOptions
    • TRegExException

    TOML

    • Introduction
    • ETomlNodeType
    • TToml
    • ITomlNode
    • STomlDate
    • STomlDateTime
    • STomlTime
    • TTomlArray
    • TTomlInteger
    • TTomlString
    • TTomlTable
    • TTomlBoolean

    Xml

    • Introduction
    • TxmlDoc
    • TxmlNode
    • TxmlAttribute

MaxGUI

  • MaxGUI.MaxGUI
  • MaxGUI.Drivers
  • MaxGUI.Localization
  • MaxGUI.ProxyGadgets
  • MaxGUI.CocoaMaxGUI
  • MaxGUI.Win32MaxGUIEx

PUB

  • Pub.FreeJoy
  • Pub.FreeProcess
  • Pub.Glad
  • Pub.Glew
  • Joystick

    • Introduction
    • TJoystickDriver
  • Pub.Lua
  • Pub.OpenAL
  • Pub.OpenGLES
  • Pub.xmmintrin
  • Pub.ZLib

Crypto

    Digest

    • Introduction
    • TMessageDigest
    • TDigestRegister
    • TNoSuchAlgorithmException

    Cipher

    • Introduction
    • TCipher
    • TCipherMode
    • Crypto.AESCipher
    • Crypto.AnubisCipher
    • Crypto.BlowfishCipher
    • Crypto.CamelliaCipher
    • Crypto.Cast5Cipher
    • Crypto.DESCipher
    • Crypto.IdeaCipher
    • Crypto.KasumiCipher
    • Crypto.KhazadCipher
    • Crypto.KSeedCipher
    • Crypto.NoekeonCipher
    • Crypto.SerpentCipher
    • Crypto.SkipjackCipher
    • Crypto.TwofishCipher
    • Crypto.XTeaCipher

    CBCMode

    • Introduction
    • TCBCCipherMode

    CFBMode

    • Introduction
    • TCFBCipherMode

    CTRMode

    • Introduction
    • TCTRCipherMode

    ECBMode

    • Introduction
    • TECBCipherMode

    F8Mode

    • Introduction
    • TF8CipherMode

    LRWMode

    • Introduction
    • TLRWCipherMode

    OFBMode

    • Introduction
    • TOFBCipherMode

    XTSMode

    • Introduction
    • TXTSCipherMode

    Blake2BDigest

    • Introduction
    • TBlake2B_512
    • TBlake2B_384
    • TBlake2B_256
    • TBlake2B_160

    CRC32

    • Introduction
    • TCRC32

    MD5Digest

    • Introduction
    • TMD5

    Ripemd320Digest

    • Introduction
    • TRipemd320

    Ripemd356Digest

    • Introduction
    • TRipemd256

    Ripemd160Digest

    • Introduction
    • TRipemd160

    Ripemd128Digest

    • Introduction
    • TRipemd128

    SHA1Digest

    • Introduction
    • TSHA1

    SHA256Digest

    • Introduction
    • TSHA256

    SHA512Digest

    • Introduction
    • TSHA512

    SHA3Digest

    • Introduction
    • TSHA3_512
    • TSHA3_384
    • TSHA3_256
    • TSHA3_224

    TigerDigest

    • Introduction
    • TTiger

    WhirlpoolDigest

    • Introduction
    • TWhirlpool

    Crypto

    • Introduction
    • TCryptoRandom
    • TCryptoSecretBox
    • TCryptoHash
    • TCryptoSign
    • TCryptoKeyExchange
    • TCryptoKey
    • TCryptoHashKey
    • TCryptoSecretBoxKey
    • TCryptoSignature
    • TCryptoExchangeKeyPair
    • TCryptoSessionKeyPair
    • TCryptoNPacket
    • TCryptoKK1Packet
    • TCryptoKK2Packet
    • TCryptoXX1Packet
    • TCryptoXX2Packet
    • TCryptoXX3Packet
    • TCryptoExchangeState
    • TCryptoPWHashMasterKey
    • TCryptoPWHashStoredKey
    • TCryptoPasswordHash

SDL

    SDL

    • Introduction
    • TSDLStream

    SDLSystem

    • Introduction
    • TSDLMultiGesture

    SDLVideo

    • Introduction
    • TSDLDisplay
    • TSDLDisplayMode
    • TSDLGLContext
    • TSDLWindow

    SDLRender

    • Introduction
    • TSDLRenderer
    • TSDLTexture

    SDLTimer

    • Introduction
    • TSDLTimer

    SDLHaptic

    • Introduction
    • TSDLHaptic
    • TSDLHapticCondition
    • TSDLHapticConstant
    • TSDLHapticCustom
    • TSDLHapticDirection
    • TSDLHapticEffect
    • TSDLHapticLeftRight
    • TSDLHapticPeriodic
    • TSDLHapticRamp

    SDLSensor

    • Introduction
    • TSDLSensor
  • SDL.SDLFreeAudio
  • SDL.GLSDLMax2D
  • SDL.GL2SDLMax2D
  • SDL.D3D9SDLMax2D
  • SDLVirtualJoystick

    • Introduction
    • TVirtualJoystick

Steam

    SteamSDK

    • Introduction
    • TSteamClient
    • TSteamUtils
    • TSteamUserStats
    • TSteamFriends
    • TSteamUGC
    • ISteamFriendsListener
    • ISteamUGCListener
    • ISteamUserStatsListener
    • ISteamUtilsListener
    • EItemPreviewType
    • EPersonaChange
    • EPersonaState
    • ERemoteStoragePublishedFileVisibility
    • EUGCMatchingUGCType
    • EUGCQuery
    • EUserRestriction
    • EUserUGCList
    • EWorkshopFileType
Edit

Text.JConv

Serialising with JConv

In the context of Text.JConv, serialisation is the mapping of BlitzMax objects to their JSON representation.

Take the following TUser type to start with :

Type TUser
    Field name:String
    Field email:String
    Field age:int
End Type

The TUser object has three Fields,

  • The user's name is a String
  • The user's email is a String
  • The user's age is an Int

An application needs to convert a 'TUser' into its JSON representation, so assuming the member names remained the same, we could expect a typical JSON representation to look like this :

{
  "name" : "bob",
  "email" : "bob@example.com",
  "age" : 30
}

To convert a TUser to JSON, we first construct an instance of one for the user Bob :

Local user:TUser = New TUser("bob", "bob@example.com", 30)

In order to do the serialisation, we need an instance of TJConv to do the conversion :

Local jconv:TJConv = New TJConvBuilder.Build()

The next step is to call the ToJson method of TJConv, passing the object we want to serialise :

Local json:String = jconv.ToJson(user)

The json String contains the following value :

{"name": "bob", "email": "bob@example.com", "age": 30}

Notice that Text.JConv respects the field types, wrapping Strings in quotes, but not so for numbers. Just a single method call is required to do the conversion of the entire object. This is useful when working with more complex object structures.

Here's the example in full :

SuperStrict

Framework BRL.StandardIO
Import Text.JConv

Local user:TUser = New TUser("bob", "bob@example.com", 30)

Local jconv:TJConv = New TJConvBuilder.Build()

Local json:String = jconv.ToJson(user)

Print json

Type TUser
    Field name:String
    Field email:String
    Field age:Int
    
    Method New(name:String, email:String, age:Int)
        Self.name = name
        Self.email = email
        Self.age = age
    End Method
End Type

Deserialising with JConv

We'll start by creating a String containing the JSON to convert :

Local json:String = "{~qname~q: ~qbob~q, ~qemail~q: ~qbob@example.com~q, ~qage~q: 30}"

Again, we'll build an instance of TJConv which will perform the conversion :

Local jconv:TJConv = New TJConvBuilder.Build()

Finally, we need to map the JSON to a BlitzMax Object with FromJson :

Local user:TUser = TUser(jconv.FromJson(json, "TUser"))

Note that the second argument specifies the name of the Type we want the String to map the JSON to. Without this hint, Text.JConv wouldn't know what Type to create from the text.

The user object returned from FromJson will have its fields populated accordingly.

Here's the example in full :

SuperStrict

Framework BRL.StandardIO
Import Text.JConv

Local json:String = "{~qname~q: ~qbob~q, ~qemail~q: ~qbob@example.com~q, ~qage~q: 30}"

Local jconv:TJConv = New TJConvBuilder.Build()

Local user:TUser = TUser(jconv.FromJson(json, "TUser"))

Print "name  = " + user.name
Print "email = " + user.email
Print "age   = " + user.age

Type TUser
    Field name:String
    Field email:String
    Field age:Int
    
    Method New(name:String, email:String, age:Int)
        Self.name = name
        Self.email = email
        Self.age = age
    End Method
End Type

Serialising Nested Objects

Text.JConv can also handle the conversion of more complex objects that include the nesting of other non-primitive objects. To demostrate this we will extend the TUser type to include an address, which will be represented by the TAddress Type :

Type TUser
    Field name:String
    Field email:String
    Field age:Int
    Field address:TAddress
End Type

Type TAddress
    Field line1:String
    Field city:String
    Field country:String
End Type

In BlitzMax the two models are cleanly separated by types, and the TAddress reference is held in the address Field of the user. In JSON however, the address must be nested directly within the user object, as we can see here :

{
  "name" : "bob",
  "email" : "bob@example.com",
  "age" : 30,
  "address" : {
    "line1" : "66 Some Street",
    "city" : "Someville",
    "country" : "Someland"
  }
}

We'll initially create the required BlitzMax objects :

Local address:TAddress = New TAddress("66 Some Street", "Someville", "Someland")
Local user:TUser = New TUser("bob", "bob@example.com", 30, address)

And then serialise the user with an instance of TJConv :

Local jconv:TJConv = New TJConvBuilder.Build()
Local json:String = jconv.ToJson(user)

The resulting conversion to JSON is :

{"name": "bob", "email": "bob@example.com", "age": 30, "address": {"line1": "66 Some Street", "city": "Someville", "country": "Someland"}}

As you can see, Text.JConv has correctly nested the address inside the user as a JSON object.

Deserialising Nested Objects

In the real world, the developer is often presented with a JSON API from which they need to construct the relevant BlitzMax Types in order to import the data.

As we have seen previously, the structure of a JSON object maps relatively well to a BlitzMax Object and its fields. In the next example, we'll start with a JSON object and construct a set of BlitzMax Types that we can use to deserialise the data in order to use it within our BlitzMax application.

In this particular example, we will be retrieving some airport information from an online flight information resource :

{
  "id": "BER",
  "code": "BER",
  "name": "Berlin Brandenburg",
  "slug": "berlin-brandenburg-berlin-germany",
  "timezone": "Europe/Berlin",
  "city": {
    "id": "berlin_de",
    "name": "Berlin",
    "code": "BER",
    "slug": "berlin-germany",
    "country": {
      "id": "DE",
      "name": "Germany",
      "slug": "germany",
      "code": "DE"
    },
    "region": {
      "id": "central-europe",
      "name": "Central Europe",
      "slug": "central-europe"
    },
    "continent": {
      "id": "europe",
      "name": "Europe",
      "slug": "europe",
      "code": "EU"
    }
  },
  "location": {
    "lat": 52.366667,
    "lon": 13.503333
  }
}

As you can see, there are several levels of nesting. The main airport object has a nested city, and within that country, region and continent objects. Also notice that many of the objects share a similar structure (id, name, slug, and code). We can use BlitzMax's Type polymorphism by creating a base Type and avoid a lot of duplication :

Type TBase
    Field id:String
    Field code:String
    Field name:String
    Field slug:String
End Type

Next, we'll define the BlitzMax types that will contain the more specific information :

Type TAirport Extends TBase
    Field timezone:String
    Field city:TCity
    Field location:TLocation
End Type

Type TCity Extends TBase
    Field country:TCountry
    Field region:TRegion
    Field continent:TContinent
End Type

Type TCountry Extends TBase
End Type

Type TRegion Extends TBase
End Type

Type TContinent Extends TBase
End Type

Type TLocation
    Field lat:Double
    Field lon:Double
End Type

Each Type represents a particular JSON object from original nested JSON. TCity contains fields for country, region and continent, each of which are types representing that particular piece of information.

Where the naming of your fields must match those of the JSON objects, how you name your types is not important for JSON mapping, but you'll generally give them a name that reflects the kind of information they contain.

Finally, we can use these types to de-serialise a matching JSON object, as shown in this complete example :

SuperStrict

Framework BRL.StandardIO
Import Text.JConv

Local data:String = "{~qid~q:~qBER~q,~qcode~q:~qBER~q,~qname~q:~qBerlin Brandenburg~q,~qslug~q:~qberlin-brandenburg-berlin-germany~q,~qtimezone~q:~qEurope/Berlin~q,~qcity~q:{~qid~q:~qberlin_de~q,~qname~q:~qBerlin~q,~qcode~q:~qBER~q,~qslug~q:~qberlin-germany~q,~qcountry~q:{~qid~q:~qDE~q,~qname~q:~qGermany~q,~qslug~q:~qgermany~q,~qcode~q:~qDE~q},~qregion~q:{~qid~q:~qcentral-europe~q,~qname~q:~qCentral Europe~q,~qslug~q:~qcentral-europe~q},~qcontinent~q:{~qid~q:~qeurope~q,~qname~q:~qEurope~q,~qslug~q:~qeurope~q,~qcode~q:~qEU~q}},~qlocation~q:{~qlat~q:52.366667,~qlon~q:13.503333}}"

Local jconv:TJConv = New TJConvBuilder.Build()
Local airport:TAirport = TAirport(jconv.FromJson(data, "TAirport"))

Print "Airport    : " + airport.name
Print "  City     : " + airport.city.name
Print "  Location : " + airport.location.lat + ", " + airport.location.lon

Type TBase
    Field id:String
    Field code:String
    Field name:String
    Field slug:String
End Type

Type TAirport Extends TBase
    Field timezone:String
    Field city:TCity
    Field location:TLocation
End Type

Type TCity Extends TBase
    Field country:TCountry
    Field region:TRegion
    Field continent:TContinent
End Type

Type TCountry Extends TBase
End Type

Type TRegion Extends TBase
End Type

Type TContinent Extends TBase
End Type

Type TLocation
    Field lat:Double
    Field lon:Double
End Type

Customising Field Names

Occasionally, a JSON object will use a key that has the same name as a reserved keyword in BlitzMax. In that case, you are unable create a field using the desired name. Fortunately, Text.JConv allows you use metadata to specify the serialised name of a given field using the serializedName metadata property.

Take the following JSON object as an example :

{
    "field" : "hello",
    "for" : "ever"
}

Neither field nor for are valid names for fields, but we can use the serializedName feature to create a valid BlitzMax Type that can deserialise this object :

Type TCustomFields
    Field field_:String { serializedName="field" }
    Field anotherField:String { serializedName = "for" }
End Type

As this example demonstrates, when using the serializedName metadata property, you can give any name to your fields and the data will still be mapped from the JSON object correctly.

Here the example in full :

SuperStrict

Framework BRL.StandardIO
Import Text.JConv

Local data:String = "{~qfield~q:~qhello~q,~qfor~q:~qever~q}"

Local jconv:TJConv = New TJConvBuilder.Build()
Local custom:TCustomFields = TCustomFields(jconv.FromJson(data, "TCustomFields"))

Print custom.field_
Print custom.anotherField

Type TCustomFields
    Field field_:String { serializedName="field" }
    Field anotherField:String { serializedName = "for" }
End Type

In addition to serializedName, another metadata property is available during deserialisation, alternateName. If you consider serializedName as being the default value, alternateName allows you to map other JSON keys to a particular field.

For example, given a TUser object where we are already mapping the JSON key full_name to the field name :

Type TUser
    Field name:String { serializedName = "full_name" }
    Field email:String
    Field age:int
End Type

We decide we also want ingest similar data from another system in our application. Instead of full_name, the other system uses username for this value. Using the alternateName metadata property we can add a comma-delimited list of other names, and our Type becomes :

Type TUser
    Field name:String { serializedName = "full_name", alternateName ="username" }
    Field email:String
    Field age:int
End Type

alternateName is only available during deserialisation. Text.JConv will use either the Field name or the serializedName when mapping a BlitzMax object to JSON.

The following two sets of JSON would map to a TUser object and set the name Field appropriately :

{
  "full_name" : "Bob",
  "email" : "bob@example.com"
}
{
  "username" : "userBob",
  "email" : "bob@example.com"
}

If there are multiple fields in the JSON that match, Text.JConv will apply the value that is processed last. So, in the following example, deserialising the JSON would result in the name Field containing the value userBob :

{
  "full_name" : "Bob",
  "username" : "userBob",
  "email" : "bob@example.com"
}

Ignoring Fields

If you don't want a field to be mapped to or from JSON there are some metadata properties that you can apply to your types in order to do so. The first, transient, completely disables field from mapping in either direction.

If you want more finer grained control, the metadata properties noSerialize and noDeserialize can be used instead. The noSerialize property instructs Text.JConv not to serialize a particular field to JSON, but it allows data from a JSON object to be deserialized into the Field. On the other hand, noDeserialize prevents data from a JSON object from deserializing into the Field, but does allow it to be serialized into a JSON object.

We'll apply some properties to the TUser object to demonstrate the options :

Type TUser
    Field name:String
    Field email:String { noSerialize }
    Field age:int { noDeserialize }
    Field passwordHash:String { transient }
End Type

Based on the above example, when serializing an instance of TUser, only the name and age fields would be mapped to JSON. Similarly, only the name and email fields would be mapped from a JSON object.

The following is a complete example of these properties in action :

SuperStrict

Framework BRL.StandardIO
Import Text.JConv

Local user:TUser = New TUser("bob", "bob@example.com", 30, "xxxx")

Local jconv:TJConv = New TJConvBuilder.Build()

Local json:String = jconv.ToJson(user)

Print "json  : " + json

json = "{~qname~q: ~qbob~q, ~qemail~q: ~qbob@example.com~q, ~qage~q: 30, ~qpasswordHash~q: ~qxxxx~q}"

user = TUser(jconv.FromJson(json, "TUser"))

Print "name  : " + user.name
Print "email : " + user.email
Print "age   : " + user.age
Print "hash  : " + user.passwordHash

Type TUser
    Field name:String
    Field email:String { noSerialize }
    Field age:Int { noDeserialize }
    Field passwordHash:String { transient }

    Method New(name:String, email:String, age:Int, ph:String)
        Self.name = name
        Self.email = email
        Self.age = age
        Self.passwordHash = ph
    End Method
End Type

Configuring TJConv with the Builder

You may have noticed, that by default Text.JConv serialises the JSON into a single line. You can change this behaviour with one ofthe builder's configurable options.

The builder uses what is known as a fluent interface, or method chaining design, where a sequence of method calls can be used to construct the TJConv instance.

For example, the following builder creates an instance of TJConv which will serialise objects to JSON with a decimal a precision of 2 places and compact objects :

Local jconv:TJConv = New TJConvBuilder.WithPrecision(2).WithCompact().Build()

WithIndent

The WithIndent method of TJConvBuilder specifies the number of spaces to use for indenting of nested objects. The default of 0 (zero) means not to use pretty-printing.

This is an example of TUser using the default options :

{"name": "Bob", "email": "bob@example.com", "age": 30}

And this is an example of building with WithIndent :

{
  "name": "Bob",
  "email": "bob@example.com",
  "age": 30
}

WithCompact

On the other hand, JSON can be compacted further using the WithCompact method, which works to remove extra spaces :

{"name":"Bob","email":"bob@example.com","age":30}

WithPrecision

The representation of decimal numbers can be controlled by the WithPrecision method, which specifies the maximum number of decimal places to used.

For example, the default representation of a Type TPoint :

Type TPoint
    Field x:Double
    Field y:Double
End Type

would normally result in the following JSON with fields of the values (10.565, 15.912) :

{"x": 10.565, "y": 15.912000000000001}

Using a maximum precision of 3 (WithPrecision(3)), the resulting JSON would become :

{"x": 10.565, "y": 15.912}

WithEmptyArrays

By default, Null/empty arrays are not serialised at all. That is, the field is not included in the JSON object. The WithEmptyArrays option can be enabled to generate an empty array ([]] instead.

WithBoxing

Primitive numbers, by their very nature in BlitzMax, have no concept of nullability. JSON, conversely, can represent any field as a null value, either by simply not including it in the object, or by having the value null.

To support this, Text.JConv provides an option to use "boxed" primitives in your types. A Boxed primitive is just an instance of a Type that has a value field of the appropriate numeric Type. Using a boxed primitive then allows a field to contain a value, or be Null.

This feature is enabled by using the WithBoxing option of the builder.

As an example, suppose there is a JSON object which has a numeric field failures. The schema specifies that this value can either be null or have a value greater than zero :

[
  {
    "jobId": "ABC123",
    "failures": 3,
    "lastError": "overflow"
  },
  {
    "jobId": "DEF456"
  }
]

Deserialising this wouldn't be a problem, as our TJob Type could represent no failures by the number zero :

Type TJob
    Field jobId:String
    Field failures:Int
    Field lastError:String
End Type

However, were we required to serialise our Type to JSON for use by the API, we'd potentially fail schema validation by passing zero as a value for the failures Field.

Utilising the boxing feature, we could instead define the failures Field as TInt :

Type TJob
    Field jobId:String
    Field failures:TInt
    Field lastError:String
End Type

Which would, for Null values, result in the features Field not being serialized to JSON.

Here's a full example highlighting the use of boxing :

SuperStrict

Framework BRL.StandardIO
Import Text.JConv

Local job1:TJob = New TJob("ABC123", 3, "overflow")
Local job2:TBoxedJob = New TBoxedJob("DEF456", 0, Null)

Local jconv:TJConv = New TJConvBuilder.WithBoxing().WithIndent(2).Build()

Print jconv.ToJson(job1)
Print jconv.ToJson(job2)

Type TJob
    Field jobId:String
    Field failures:Int
    Field lastError:String
    
    Method New(jobId:String, failures:Int, lastError:String)
        Self.jobId = jobId
        Self.failures = failures
        Self.lastError = lastError
    End Method
End Type

Type TBoxedJob
    Field jobId:String
    Field failures:TInt
    Field lastError:String

    Method New(jobId:String, failures:Int, lastError:String)
        Self.jobId = jobId
        If failures > 0 Then
            Self.failures = New TInt(failures)
        End If
        Self.lastError = lastError
    End Method
End Type

Running the above example would result in the following output :

{
  "jobId": "ABC123",
  "failures": 3,
  "lastError": "overflow"
}
{
  "jobId": "DEF456"
}

RegisterSerializer

Types

TypeDescription
TJConvBuilderCreates an instance of TJConv with custom settings.
TJConvSerialises or deserializes objects to and from JSON.
TJConvSerializerSerializes BlitzMax type to JSON.
← TIniSectionTJConv →
  • Serialising with JConv
  • Deserialising with JConv
  • Serialising Nested Objects
  • Deserialising Nested Objects
  • Customising Field Names
  • Ignoring Fields
  • Configuring TJConv with the Builder
    • WithIndent
    • WithCompact
    • WithPrecision
    • WithEmptyArrays
    • WithBoxing
    • RegisterSerializer
  • Types
BlitzMax
Docs
Getting StartedDownloadsAbout
Community
ResourcesSyntaxBomb Forums
More
GitHubStarChat on Discord
Copyright © 2023 Bruce A Henderson