Files
handleaiuinew/env/LMI/include/kApi/Io/kSerializer.cpp
T
2024-05-18 23:53:26 +08:00

966 lines
24 KiB
C++

/**
* @file kSerializer.cpp
*
* @internal
* Copyright (C) 2005-2021 by LMI Technologies Inc.
* Licensed under the MIT License.
* Redistributed files must retain the above copyright notice.
*/
#include <kApi/Io/kSerializer.h>
#include <kApi/Io/kDat6Serializer.h>
#include <kApi/Io/kFile.h>
#include <kApi/Data/kArrayList.h>
#include <kApi/Data/kMap.h>
/*
* kCompressor interaface
*/
kBeginInterfaceEx(k, kCompressor)
//interface methods
kAddPrivateVMethod(kCompressor, kCompressor, VCompressionType)
kAddPrivateVMethod(kCompressor, kCompressor, VRequiredVersion)
kAddPrivateVMethod(kCompressor, kCompressor, VConstruct)
kAddPrivateVMethod(kCompressor, kCompressor, VFinishWrite)
kAddPrivateVMethod(kCompressor, kCompressor, VFinishRead)
kEndInterfaceEx()
/*
* kSerializer class
*/
kBeginValueEx(k, xkSerializerWriteSection)
kAddField(xkSerializerWriteSection, kPointer, buffer)
kAddField(xkSerializerWriteSection, kSize, start)
kAddField(xkSerializerWriteSection, kType, type)
kAddField(xkSerializerWriteSection, kBool, includeSize)
kEndValueEx()
kBeginClassEx(k, kSerializer)
kAddVMethod(kSerializer, kObject, VRelease)
kAddVMethod(kSerializer, kSerializer, VInit)
kAddVMethod(kSerializer, kSerializer, VCanAutoFlush)
kAddVMethod(kSerializer, kSerializer, VSetSizeEncoding)
kAddVMethod(kSerializer, kSerializer, VReset)
kAddVMethod(kSerializer, kSerializer, VWriteObject)
kAddVMethod(kSerializer, kSerializer, VReadObject)
kAddVMethod(kSerializer, kSerializer, VCanWriteType)
kAddVMethod(kSerializer, kSerializer, VWriteType)
kAddVMethod(kSerializer, kSerializer, VReadType)
kEndClassEx()
kFx(kStatus) kSerializer_Construct(kSerializer* serializer, kStream stream, kType serializerType, kAlloc allocator)
{
kAlloc alloc = kAlloc_Fallback(allocator);
kType type = kIsNull(serializerType) ? kTypeOf(kSerializer) : serializerType;
kStatus status;
kCheck(kAlloc_GetObject(alloc, type, serializer));
if (!kSuccess(status = kType_VTableT(type, kSerializer)->VInit(*serializer, type, stream, alloc)))
{
kAlloc_FreeRef(alloc, serializer);
}
return status;
}
kFx(kStatus) kSerializer_LoadObject(kObject* object, kType serializerType, const kChar* filePath, kAlloc readAlloc)
{
kFile stream = kNULL;
kSerializer reader = kNULL;
kCheckArgs(!kIsNull(serializerType));
kTry
{
kTest(kFile_Construct(&stream, filePath, kFILE_MODE_READ, kNULL));
kTest(kFile_SetReadBuffer(stream, xkSERIALIZER_DEFAULT_BUFFER_SIZE));
kTest(kSerializer_Construct(&reader, stream, serializerType, kNULL));
kTest(kSerializer_ReadObject(reader, object, readAlloc));
}
kFinally
{
kCheck(kObject_Destroy(reader));
kCheck(kObject_Destroy(stream));
kEndFinally();
}
return kOK;
}
kFx(kStatus) kSerializer_SaveObject(kObject object, kType serializerType, const kChar* filePath)
{
kSerializer writer = kNULL;
kFile stream = kNULL;
kCheckArgs(!kIsNull(serializerType));
kTry
{
kTest(kFile_Construct(&stream, filePath, kFILE_MODE_WRITE, kNULL));
kTest(kSerializer_Construct(&writer, stream, serializerType, kNULL));
kTest(kSerializer_WriteObject(writer, object));
kTest(kSerializer_Flush(writer));
}
kFinally
{
kCheck(kObject_Destroy(writer));
kCheck(kObject_Destroy(stream));
kEndFinally();
}
return kOK;
}
kFx(kStatus) kSerializer_VInit(kSerializer serializer, kType type, kStream stream, kAlloc allocator)
{
kObjR(kSerializer, serializer);
kStatus status;
kCheck(kObject_Init(serializer, type, allocator));
obj->stream = stream;
obj->readStream = stream;
obj->writeStream = stream;
obj->readAlloc = kNULL;
obj->endianness = kENDIANNESS_LITTLE;
obj->swap = kEndianness_ShouldReverse(obj->endianness);
obj->sizeEncoding = 4;
obj->format[0] = 0;
obj->formatVersion = k32U_NULL;
obj->assemblyVersions = kNULL;
obj->activeBuffers = kNULL;
obj->currentBuffer = kNULL;
obj->freeBuffers = kNULL;
obj->bufferSize = xkSERIALIZER_DEFAULT_BUFFER_SIZE;
obj->writeSections = kNULL;
obj->readSections = kNULL;
kTry
{
kTest(kMap_Construct(&obj->assemblyVersions, kTypeOf(kAssembly), kTypeOf(kVersion), 16, allocator));
kTest(kArrayList_Construct(&obj->writeSections, kTypeOf(xkSerializerWriteSection), 16, allocator));
kTest(kArrayList_Construct(&obj->readSections, kTypeOf(k64u), 16, allocator));
kTest(xkSerializer_AddBuffer(serializer));
}
kCatch(&status)
{
kSerializer_VRelease(serializer);
kEndCatch(status);
}
return kOK;
}
kFx(kStatus) kSerializer_VRelease(kSerializer serializer)
{
kObj(kSerializer, serializer);
xkSerializerBuffer* buffer = kNULL;
kCheck(xkSerializer_ClearBuffers(serializer));
buffer = obj->freeBuffers;
while (!kIsNull(buffer))
{
xkSerializerBuffer* next = buffer->next;
kCheck(kObject_FreeMem(serializer, buffer));
buffer = next;
}
kCheck(kObject_Destroy(obj->assemblyVersions));
kCheck(kObject_Destroy(obj->readSections));
kCheck(kObject_Destroy(obj->writeSections));
kCheck(kObject_VRelease(serializer));
return kOK;
}
kFx(kStatus) xkSerializer_FlushEx(kSerializer serializer, kBool flushStream)
{
kObj(kSerializer, serializer);
kCheck(xkSerializer_FlushBuffers(serializer));
kCheck(xkSerializer_AddBuffer(serializer));
if (flushStream)
{
kCheck(kStream_Flush(obj->writeStream));
}
return kOK;
}
kFx(kStatus) kSerializer_VReset(kSerializer serializer)
{
kObj(kSerializer, serializer);
kCheck(xkSerializer_ClearBuffers(serializer));
kCheck(xkSerializer_AddBuffer(serializer));
kCheck(kArrayList_Clear(obj->readSections));
kCheck(kArrayList_Clear(obj->writeSections));
return kOK;
}
kFx(kStatus) xkSerializer_DeserializeObject(kSerializer serializer, kType type, kTypeVersion version, kObject* object, kAlloc alloc)
{
kObject output = kNULL;
kStatus exception;
kTry
{
//FSS-1148: Update object deserialization to support C++ constructors
if (kType_VersionHasLegacyDeserializer(type, version))
{
kSerializerObjectDeserializeFx deserializeFx = (kSerializerObjectDeserializeFx) kType_VersionDeserializeFx(type, version);
kStatus status;
kTest(kAlloc_GetObject(alloc, type, &output));
if (!kSuccess(status = deserializeFx(output, serializer, alloc)))
{
kAlloc_FreeRef(alloc, &output);
kThrow(status);
}
}
else
{
kSerializerObjectDeserializeExFx deserializeFx = (kSerializerObjectDeserializeExFx) kType_VersionDeserializeFx(type, version);
kTest(kType_FrameworkConstructor(type)(&output, alloc));
kTest(deserializeFx(output, serializer));
}
*object = output;
}
kCatch(&exception)
{
kObject_Dispose(output);
kEndCatch(exception);
}
return kOK;
}
kFx(kStatus) kSerializer_WriteItems(kSerializer serializer, kType type, kTypeVersion version, const void* items, kSize count)
{
kObj(kSerializer, serializer);
if (kType_IsReference(type))
{
kSize i;
for (i = 0; i < count; ++i)
{
kCheck(kSerializer_WriteObject(obj, ((kObject*)items)[i]));
}
}
else
{
kCheck(kSerializer_InvokeValueSerializer(serializer, type, version, items, count));
}
return kOK;
}
kFx(kStatus) kSerializer_ReadItems(kSerializer serializer, kType type, kTypeVersion version, void* items, kSize count)
{
kObj(kSerializer, serializer);
if (kType_IsReference(type))
{
kSize i;
for (i = 0; i < count; ++i)
{
kCheck(kSerializer_ReadObject(serializer, &((kObject*)items)[i], obj->readAlloc));
}
}
else
{
kCheck(kSerializer_InvokeValueDeserializer(serializer, type, version, items, count));
}
return kOK;
}
kFx(kStatus) kSerializer_BeginWrite(kSerializer serializer, kType sizeType, kBool includeSize)
{
kObj(kSerializer, serializer);
xkSerializerWriteSection* section = kNULL;
if (sizeType == kTypeOf(k8u)) kCheck(kSerializer_Write8u(serializer, 0));
else if (sizeType == kTypeOf(k16u)) kCheck(kSerializer_Write16u(serializer, 0));
else if (sizeType == kTypeOf(k32u)) kCheck(kSerializer_Write32u(serializer, 0));
else if (sizeType == kTypeOf(k64u)) kCheck(kSerializer_Write64u(serializer, 0));
else return kERROR_PARAMETER;
kCheck(kArrayList_AddCount(obj->writeSections, 1));
section = (xkSerializerWriteSection*) kArrayList_Last(obj->writeSections);
section->buffer = obj->currentBuffer;
section->start = obj->currentBuffer->written - kType_Size(sizeType);
section->type = sizeType;
section->includeSize = includeSize;
return kOK;
}
kFx(kStatus) kSerializer_EndWrite(kSerializer serializer)
{
kObj(kSerializer, serializer);
kCheckState(kArrayList_Count(obj->writeSections) > 0);
xkSerializerWriteSection* section = (xkSerializerWriteSection*) kArrayList_Last(obj->writeSections);
kByte* writeAddress = (kByte*) kPointer_ByteOffset(section->buffer->data, (kSSize)section->start);
xkSerializerBuffer* buffer = kNULL;
kSize size = 0;
buffer = section->buffer;
size = (section->buffer->written - section->start);
buffer = buffer->next;
while (buffer != obj->currentBuffer->next)
{
size += buffer->written;
buffer = buffer->next;
}
if (!section->includeSize)
{
size -= kType_Size(section->type);
}
if (section->type == kTypeOf(k8u))
{
k8u sizeField = (k8u)(size);
kCheckState(size <= k8U_MAX);
*(k8u*) writeAddress = sizeField;
}
else if (section->type == kTypeOf(k16u))
{
k16u sizeField = (k16u) size;
kCheckState(size <= k16U_MAX);
xkSerializer_ReorderCopyPrimitive(serializer, writeAddress, &sizeField, 2);
}
else if (section->type == kTypeOf(k32u))
{
k32u sizeField = (k32u) size;
kCheckState(size <= k32U_MAX);
xkSerializer_ReorderCopyPrimitive(serializer, writeAddress, &sizeField, 4);
}
else if (section->type == kTypeOf(k64u))
{
k64u sizeField = (k64u) size;
xkSerializer_ReorderCopyPrimitive(serializer, writeAddress, &sizeField, 8);
}
else
{
return kERROR_FORMAT;
}
kCheck(kArrayList_RemoveCount(obj->writeSections, 1));
return kOK;
}
kFx(kStatus) kSerializer_BeginRead(kSerializer serializer, kType sizeType, kBool includeSize)
{
kObj(kSerializer, serializer);
k64u readSize = 0;
k64u readEnd = 0;
if (sizeType == kTypeOf(k8u))
{
k8u sizeField;
kCheck(kSerializer_Read8u(serializer, &sizeField));
readSize = sizeField;
}
else if (sizeType == kTypeOf(k16u))
{
k16u sizeField;
kCheck(kSerializer_Read16u(serializer, &sizeField));
readSize = sizeField;
}
else if (sizeType == kTypeOf(k32u))
{
k32u sizeField;
kCheck(kSerializer_Read32u(serializer, &sizeField));
readSize = sizeField;
}
else if (sizeType == kTypeOf(k64u))
{
k64u sizeField;
kCheck(kSerializer_Read64u(serializer, &sizeField));
readSize = sizeField;
}
else
{
return kERROR_PARAMETER;
}
if (includeSize)
{
readSize -= kType_Size(sizeType);
}
readEnd = kStream_BytesRead(obj->readStream) + readSize;
kCheck(kArrayList_AddCount(obj->readSections, 1));
*(k64u*) kArrayList_Last(obj->readSections) = readEnd;
return kOK;
}
kFx(kStatus) kSerializer_EndRead(kSerializer serializer)
{
kObj(kSerializer, serializer);
k64u readLocation = kStream_BytesRead(obj->readStream);
k64u readSection;
kSize advance = 0;
kAssert(kArrayList_Count(obj->readSections) > 0);
kCheckState(kArrayList_Count(obj->readSections) > 0);
readSection = kPointer_ReadAs(kArrayList_Last(obj->readSections), k64u);
kCheck(kArrayList_RemoveCount(obj->readSections, 1));
kCheckState(readSection >= readLocation);
advance = (kSize) (readSection - readLocation);
if (advance > 0)
{
kCheck(kSerializer_AdvanceRead(serializer, advance));
}
return kOK;
}
kFx(kStatus) xkSerializer_AdvanceReadImpl(kSerializer serializer, kSize offset)
{
kObj(kSerializer, serializer);
kByte bitBucket[128];
kSize remaining = offset;
while (remaining > 0)
{
kSize readAmount = kMin_(remaining, sizeof(bitBucket));
kCheck(kStream_Read(obj->readStream, bitBucket, readAmount));
remaining -= readAmount;
}
return kOK;
}
kFx(kStatus) kSerializer_SetVersion(kSerializer serializer, kAssembly assembly, kVersion version)
{
kObj(kSerializer, serializer);
if (kIsNull(assembly))
{
obj->formatVersion = version;
}
else
{
kCheck(kMap_ReplaceT(obj->assemblyVersions, &assembly, &version));
}
return kOK;
}
kFx(kStatus) xkSerializer_AddBuffer(kSerializer serializer)
{
kObj(kSerializer, serializer);
xkSerializerBuffer* next = kNULL;
if (kIsNull(obj->freeBuffers))
{
kCheck(xkSerializer_AllocateBuffer(serializer));
}
if (kIsNull(obj->activeBuffers))
{
obj->activeBuffers = obj->freeBuffers;
}
else
{
next = obj->currentBuffer->next;
obj->currentBuffer->next = obj->freeBuffers;
}
obj->currentBuffer = obj->freeBuffers;
obj->freeBuffers = obj->freeBuffers->next;
obj->currentBuffer->next = next;
obj->currentBuffer->written = 0;
return kOK;
}
kFx(kStatus) xkSerializer_AllocateBuffer(kSerializer serializer)
{
kObj(kSerializer, serializer);
kSize headerSize = sizeof(xkSerializerBuffer);
kSize dataOffset = kSize_Align(headerSize, kALIGN_ANY);
kSize size = dataOffset + obj->bufferSize;
xkSerializerBuffer* buffer = kNULL;
kCheck(kObject_GetMem(serializer, size, &buffer));
buffer->capacity = obj->bufferSize;
buffer->written = 0;
buffer->data = ((kByte*)buffer) + dataOffset;
buffer->next = obj->freeBuffers;
obj->freeBuffers = buffer;
return kOK;
}
kFx(kStatus) xkSerializer_InsertHeader(kSerializer serializer)
{
kObj(kSerializer, serializer);
xkSerializerBuffer* next = obj->activeBuffers;
if (kIsNull(obj->freeBuffers))
{
kCheck(xkSerializer_AllocateBuffer(serializer));
}
obj->activeBuffers = obj->freeBuffers;
obj->freeBuffers = obj->freeBuffers->next;
obj->activeBuffers->next = next;
obj->currentBuffer = obj->activeBuffers;
obj->currentBuffer->written = 0;
return kOK;
}
kFx(kStatus) xkSerializer_ClearBuffers(kSerializer serializer)
{
kObj(kSerializer, serializer);
while (!kIsNull(obj->activeBuffers))
{
xkSerializerBuffer* next = obj->activeBuffers->next;
obj->activeBuffers->next = obj->freeBuffers;
obj->freeBuffers = obj->activeBuffers;
obj->activeBuffers = next;
}
obj->currentBuffer = kNULL;
return kOK;
}
kFx(kStatus) xkSerializer_FlushBuffers(kSerializer serializer)
{
kObj(kSerializer, serializer);
while (!kIsNull(obj->activeBuffers))
{
xkSerializerBuffer* next = obj->activeBuffers->next;
kCheck(kStream_Write(obj->writeStream, obj->activeBuffers->data, obj->activeBuffers->written));
obj->activeBuffers->next = obj->freeBuffers;
obj->freeBuffers = obj->activeBuffers;
obj->activeBuffers = next;
}
obj->currentBuffer = kNULL;
return kOK;
}
kFx(kVersion) kSerializer_FindRequestedMinVersion(kSerializer serializer, kType type)
{
kObj(kSerializer, serializer);
kAssembly assembly = kType_Assembly(type);
kVersion requestedVersion = k32U_NULL;
if (obj->formatVersion != k32U_NULL)
{
requestedVersion = obj->formatVersion;
}
else if (!kSuccess(kMap_FindT(obj->assemblyVersions, &assembly, &requestedVersion)))
{
requestedVersion = k32U_NULL; //use the highest available version
}
return requestedVersion;
}
kFx(kStatus) kSerializer_FindCompatibleVersion(kSerializer serializer, kType type, kTypeVersion* version)
{
kObj(kSerializer, serializer);
kAssembly assembly = kType_Assembly(type);
kVersion requestedVersion;
kSSize versionCount = (kSSize) kType_VersionCount(type);
kSSize i = 0;
if (obj->formatVersion != k32U_NULL)
{
requestedVersion = obj->formatVersion;
}
else if (!kSuccess(kMap_FindT(obj->assemblyVersions, &assembly, &requestedVersion)))
{
requestedVersion = k32U_NULL; //use the highest available version
}
//type versions are stored by increasing format version;
//can start at end of list and work backwards to find a compatible match.
for (i = versionCount-1; i >= 0; --i)
{
kTypeVersion typeVer = kType_VersionAt(type, (kSize)i);
if (kStrEquals(obj->format, kType_VersionFormat(type, typeVer)) && (kType_VersionFormatVersion(type, typeVer) <= requestedVersion))
{
*version = typeVer;
return kOK;
}
}
return kERROR_NOT_FOUND;
}
kFx(kStatus) xkSerializer_WritePrimitives(kSerializer serializer, const void* items, kSize count, xkSerializerPrimative primitive)
{
kObj(kSerializer, serializer);
k32u itemSize = 1u << primitive;
kBool autoFlush = xkSerializer_CanAutoFlush(serializer);
kSize remaining = count;
if (autoFlush && !obj->swap && (count > xkSERIALIZER_MAX_BUFFERED_WRITE_SIZE))
{
kCheck(xkSerializer_FlushBuffers(serializer));
kCheck(kStream_Write(obj->writeStream, items, itemSize * count));
kCheck(xkSerializer_AddBuffer(serializer));
}
else
{
while (remaining > 0)
{
kSize maxItems = (obj->currentBuffer->capacity - obj->currentBuffer->written) >> primitive;
kSize itemCount = kMin_(maxItems, remaining);
const kByte* src = kCast(kByte*, items) + (itemSize * (count - remaining));
kByte* dest = kCast(kByte*, obj->currentBuffer->data) + obj->currentBuffer->written;
kSize dataSize = itemSize * itemCount;
if (!obj->swap || (itemSize == 1))
{
kMemCopy(dest, src, dataSize);
}
else
{
kByte* destEnd = dest + dataSize;
while (dest != destEnd)
{
kMemReverseCopy(dest, src, itemSize);
dest += itemSize;
src += itemSize;
}
}
obj->currentBuffer->written += itemSize * itemCount;
remaining -= itemCount;
if (remaining > 0)
{
if (autoFlush)
{
kCheck(xkSerializer_FlushBuffers(serializer));
}
kCheck(xkSerializer_AddBuffer(serializer));
}
}
}
return kOK;
}
kFx(kStatus) xkSerializer_ReadPrimitives(kSerializer serializer, void* items, kSize count, xkSerializerPrimative primitive)
{
kObj(kSerializer, serializer);
k32u itemSize = 1u << primitive;
kSize dataSize = itemSize*count;
kCheck(kStream_Read(obj->readStream, items, dataSize));
if (obj->swap)
{
kByte* dataIt = (kByte*) items;
kByte* dataEnd = dataIt + dataSize;
while (dataIt != dataEnd)
{
kMemReverse(dataIt, itemSize);
dataIt += itemSize;
}
}
return kOK;
}
kFx(kStatus) kSerializer_WriteText(kSerializer serializer, const kChar* data)
{
kChar chr = 0;
do
{
chr = *data++;
kCheck(kSerializer_WriteChar(serializer, chr));
}
while (chr != 0);
return kOK;
}
kFx(kStatus) kSerializer_ReadText(kSerializer serializer, kChar* data, kSize capacity)
{
kChar* end = data + capacity;
kChar chr = 0;
kCheckArgs(capacity > 0);
do
{
kCheck(kSerializer_ReadChar(serializer, &chr));
*data++ = chr;
}
while ((chr != 0) && (data != end));
return (chr == 0) ? kOK : kERROR_INCOMPLETE;
}
#if (K_POINTER_SIZE == 4)
kFx(kStatus) kSerializer_WriteSizeArray(kSerializer serializer, const kSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 4)
{
kCheck(kSerializer_Write32uArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
kCheck(kSerializer_Write64u(serializer, data[i]));
}
}
return kOK;
}
kFx(kStatus) kSerializer_ReadSizeArray(kSerializer serializer, kSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 4)
{
kCheck(kSerializer_Read32uArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
k64u value;
kCheck(kSerializer_Read64u(serializer, &value));
kCheckTrue(value <= k32U_MAX, kERROR_FORMAT);
data[i] = (kSize) value;
}
}
return kOK;
}
kFx(kStatus) kSerializer_WriteSSizeArray(kSerializer serializer, const kSSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 4)
{
kCheck(kSerializer_Write32sArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
kCheck(kSerializer_Write64s(serializer, data[i]));
}
}
return kOK;
}
kFx(kStatus) kSerializer_ReadSSizeArray(kSerializer serializer, kSSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 4)
{
kCheck(kSerializer_Read32sArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
k64s value;
kCheck(kSerializer_Read64s(serializer, &value));
kCheckTrue((value >= k32S_MIN) && (value <= k32S_MAX), kERROR_FORMAT);
data[i] = (k32s) value;
}
}
return kOK;
}
#elif (K_POINTER_SIZE == 8)
kFx(kStatus) kSerializer_WriteSizeArray(kSerializer serializer, const kSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 8)
{
kCheck(kSerializer_Write64uArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
kCheckArgs(data[i] <= k32U_MAX);
kCheck(kSerializer_Write32u(serializer, (k32u) data[i]));
}
}
return kOK;
}
kFx(kStatus) kSerializer_ReadSizeArray(kSerializer serializer, kSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 8)
{
kCheck(kSerializer_Read64uArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
k32u value;
kCheck(kSerializer_Read32u(serializer, &value));
data[i] = value;
}
}
return kOK;
}
kFx(kStatus) kSerializer_WriteSSizeArray(kSerializer serializer, const kSSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 8)
{
kCheck(kSerializer_Write64sArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
kCheckArgs((data[i] >= k32S_MIN) && (data[i] <= k32S_MAX));
kCheck(kSerializer_Write32s(serializer, (k32s) data[i]));
}
}
return kOK;
}
kFx(kStatus) kSerializer_ReadSSizeArray(kSerializer serializer, kSSize* data, kSize count)
{
kObj(kSerializer, serializer);
kSize i = 0;
if (obj->sizeEncoding == 8)
{
kCheck(kSerializer_Read64sArray(serializer, data, count));
}
else
{
for (i = 0; i < count; ++i)
{
k32s value;
kCheck(kSerializer_Read32s(serializer, &value));
data[i] = value;
}
}
return kOK;
}
#endif