mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 09:40:21 +00:00
142 lines
6.3 KiB
Forth
142 lines
6.3 KiB
Forth
namespace Nessos.FsPickler.Json
|
|
|
|
open System
|
|
open System.IO
|
|
open System.Collections.Generic
|
|
|
|
open Newtonsoft.Json
|
|
|
|
open Nessos.FsPickler
|
|
|
|
/// <summary>
|
|
/// Json format serializer.
|
|
/// </summary>
|
|
type internal JsonPickleWriter (jsonWriter : JsonWriter, omitHeader, indented, isTopLevelSequence, separator, leaveOpen) =
|
|
|
|
do
|
|
jsonWriter.Formatting <- if indented then Formatting.Indented else Formatting.None
|
|
jsonWriter.CloseOutput <- not leaveOpen
|
|
|
|
let isBsonWriter = match jsonWriter with :? Bson.BsonWriter -> true | _ -> false
|
|
|
|
let mutable depth = 0
|
|
let mutable isTopLevelSequenceHead = false
|
|
let mutable currentValueIsNull = false
|
|
|
|
let arrayStack = new Stack<int> ()
|
|
do arrayStack.Push Int32.MinValue
|
|
|
|
// do not write tag if omitting header or array element
|
|
let omitTag () = (omitHeader && depth = 0) || arrayStack.Peek() = depth - 1
|
|
|
|
interface IPickleFormatWriter with
|
|
|
|
member __.BeginWriteRoot (tag : string) =
|
|
if omitHeader then () else
|
|
|
|
jsonWriter.WriteStartObject()
|
|
writePrimitive jsonWriter false "FsPickler" jsonFormatVersion
|
|
writePrimitive jsonWriter false "type" tag
|
|
|
|
member __.EndWriteRoot () =
|
|
if not omitHeader then jsonWriter.WriteEnd()
|
|
|
|
member __.BeginWriteObject (tag : string) (flags : ObjectFlags) =
|
|
|
|
if not <| omitTag () then
|
|
jsonWriter.WritePropertyName tag
|
|
|
|
if flags.HasFlag ObjectFlags.IsNull then
|
|
currentValueIsNull <- true
|
|
jsonWriter.WriteNull()
|
|
|
|
elif flags.HasFlag ObjectFlags.IsSequenceHeader then
|
|
if isTopLevelSequence && depth = 0 then
|
|
isTopLevelSequenceHead <- true
|
|
else
|
|
jsonWriter.WriteStartArray()
|
|
|
|
arrayStack.Push depth
|
|
depth <- depth + 1
|
|
else
|
|
jsonWriter.WriteStartObject()
|
|
depth <- depth + 1
|
|
|
|
if flags = ObjectFlags.None then ()
|
|
else
|
|
let flagCsv = mkFlagCsv flags
|
|
writePrimitive jsonWriter false "_flags" flagCsv
|
|
|
|
member __.EndWriteObject () =
|
|
if currentValueIsNull then
|
|
currentValueIsNull <- false
|
|
else
|
|
depth <- depth - 1
|
|
if arrayStack.Peek () = depth then
|
|
if isTopLevelSequence && depth = 0 then ()
|
|
else
|
|
jsonWriter.WriteEndArray()
|
|
|
|
arrayStack.Pop () |> ignore
|
|
else
|
|
jsonWriter.WriteEndObject()
|
|
|
|
member __.SerializeUnionCaseNames = true
|
|
|
|
member __.PreferLengthPrefixInSequences = false
|
|
member __.WriteNextSequenceElement hasNext =
|
|
if isTopLevelSequence && depth = 1 then
|
|
if isTopLevelSequenceHead then
|
|
isTopLevelSequenceHead <- false
|
|
else
|
|
jsonWriter.WriteWhitespace separator
|
|
|
|
member __.WriteCachedObjectId id = writePrimitive jsonWriter false "id" id
|
|
|
|
member __.WriteBoolean (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteByte (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteSByte (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
|
|
member __.WriteInt16 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteInt32 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteInt64 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
|
|
member __.WriteUInt16 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteUInt32 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteUInt64 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
|
|
member __.WriteSingle (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteDouble (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteDecimal (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value)
|
|
|
|
member __.WriteChar (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteString (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteBigInteger (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value)
|
|
|
|
member __.WriteGuid (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
|
|
member __.WriteTimeSpan (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value)
|
|
|
|
// BSON spec mandates the use of Unix time;
|
|
// this has millisecond precision which results in loss of accuracy w.r.t. ticks
|
|
// since the goal of FsPickler is to offer faithful representations of .NET objects
|
|
// we choose to override the spec and serialize ticks outright.
|
|
// see also https://json.codeplex.com/discussions/212067
|
|
member __.WriteDate (tag : string) value =
|
|
if isBsonWriter then
|
|
writePrimitive jsonWriter (omitTag ()) tag value.Ticks
|
|
else
|
|
writePrimitive jsonWriter (omitTag ()) tag value
|
|
|
|
member __.WriteBytes (tag : string) (value : byte []) =
|
|
if not <| omitTag () then
|
|
jsonWriter.WritePropertyName tag
|
|
|
|
if obj.ReferenceEquals(value, null) then
|
|
jsonWriter.WriteNull()
|
|
else
|
|
jsonWriter.WriteValue value
|
|
|
|
member __.IsPrimitiveArraySerializationSupported = false
|
|
member __.WritePrimitiveArray _ _ = raise <| NotSupportedException()
|
|
|
|
member __.Dispose () = jsonWriter.Flush() |