Sources/sdk-core-swift/objectmodel/XyoObjectStructure.swift
//
// XyoObjectStructure.swift
// sdk-objectmodel-swift
//
// Created by Carter Harrison on 1/21/19.
// Copyright © 2019 XYO Network. All rights reserved.
//
import Foundation
open class XyoObjectStructure {
private let typedSchema: XyoObjectSchema?
var value: XyoBuffer
public init (value: XyoBuffer) {
self.typedSchema = nil
self.value = value
}
public init (value: XyoBuffer, schema: XyoObjectSchema) {
self.typedSchema = schema
self.value = XyoBuffer().put(schema: schema).put(buffer: value)
}
public func getBuffer () -> XyoBuffer {
return value
}
public func getSchema () throws -> XyoObjectSchema {
return typedSchema ?? value.getSchema(offset: 0)
}
public func getValueCopy () throws -> XyoBuffer {
let startIndex = 2 + (try getSchema()).getSizeIdentifier().rawValue + value.allowedOffset
let endIndex = startIndex + (try getSize()) - (try getSchema()).getSizeIdentifier().rawValue
try checkIndex(index: endIndex - value.allowedOffset)
return XyoBuffer(data: value, allowedOffset: startIndex, lastOffset: endIndex)
}
public func getSize () throws -> Int {
let sizeOfSize = Int(try getSchema().getSizeIdentifier().rawValue)
try checkIndex(index: sizeOfSize + 2)
return readSizeOfObject(sizeIdentifier: (try getSchema()).getSizeIdentifier(), offset: 2)
}
internal func checkIndex (index: Int) throws {
if index > value.getSize() {
throw XyoObjectError.OUTOFINDEX
}
}
func readSizeOfObject (sizeIdentifier: XyoObjectSize, offset: Int) -> Int {
switch sizeIdentifier {
case XyoObjectSize.ONE:
return Int(value.getUInt8(offset: offset))
case XyoObjectSize.TWO:
return Int(value.getUInt16(offset: offset))
case XyoObjectSize.FOUR:
return Int(value.getUInt32(offset: offset))
case XyoObjectSize.EIGHT:
return Int(value.getUInt64(offset: offset))
}
}
public static func newInstance (schema: XyoObjectSchema, bytes: XyoBuffer) -> XyoObjectStructure {
return XyoObjectStructure(value: encode(schema: schema, bytes: bytes))
}
static func encode (schema: XyoObjectSchema, bytes: XyoBuffer) -> XyoBuffer {
let buffer = XyoBuffer()
let size = bytes.toByteArray().count
let typeOfSize = XyoByteUtil.getBestSize(size: size)
buffer.put(schema: XyoObjectSchema.create(id: schema.id,
isIterable: schema.getIsIterable(),
isTypedIterable: schema.getIsTypedIterable(),
sizeIdentifier: typeOfSize))
switch typeOfSize {
case XyoObjectSize.ONE:
buffer.put(bits: UInt8(size + 1))
case XyoObjectSize.TWO:
buffer.put(bits: UInt16(size + 2))
case XyoObjectSize.FOUR:
buffer.put(bits: UInt32(size + 4))
case XyoObjectSize.EIGHT:
buffer.put(bits: UInt64(size + 8))
}
return buffer.put(bytes: bytes.toByteArray())
}
}