jsonbinpack
Version:
A space-efficient schema-driven binary JSON serialization format based on JSON Schema
78 lines (65 loc) • 2.08 kB
text/typescript
/*
* Copyright 2021 Juan Cruz Viotti
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
strict as assert
} from 'assert'
import ResizableBuffer from '../resizable-buffer'
import {
SchemasOptions
} from './options'
import {
EncodingContext
} from '../context'
import {
JSONValue
} from '../../json'
import {
validateSchema
} from '../../schema'
import {
FLOOR_MULTIPLE_ENUM_VARINT
} from '../integer/encode'
import {
encode
} from '../index'
export const ONEOF_CHOICE_INDEX_PREFIX = (
buffer: ResizableBuffer, offset: number, value: JSONValue,
options: SchemasOptions, context: EncodingContext
): number => {
assert(options.choices.length > 0)
// Find which of the choices is the one that applies
let choiceIndex: number = -1
for (const [ index, definition ] of options.choices.entries()) {
// TODO: By no means we should be doing full-blown JSON Schema validation
// here. We should instead be compiling the schema into something simpler
// that we can check and use that intead.
if (validateSchema(definition.schema, value)) {
choiceIndex = index
break
}
}
assert(choiceIndex >= 0)
// Record which of the choices was used
const indexBytes: number = FLOOR_MULTIPLE_ENUM_VARINT(buffer, offset, choiceIndex, {
minimum: 0,
multiplier: 1
}, context)
// Proceed with encoding against the given choice
const bytesWritten: number =
encode(buffer, offset + indexBytes,
options.choices[choiceIndex].encoding, value, context)
return indexBytes + bytesWritten
}