Example #1
0
void readValueEmbeddedMap(ContentBuffer & reader, RecordParseListener & listener, OType mapType) {
    int64_t size = readVarint(reader);
    listener.startMap(size, mapType);
    int32_t lastCursor = 0;
    while (size-- > 0) {
        //Skipping because is everytime string
        reader.prepare(1);
        int key_size = readVarint(reader);
        reader.prepare(key_size);
        char * key_name = (char *) reader.content + reader.cursor;
        listener.mapKey(key_name, key_size);
        long position = readFlat32Integer(reader);
        reader.prepare(1);
        if (position == 0) {
            listener.nullValue();
        } else {
            OType type = (OType) reader.content[reader.cursor];
            int temp = reader.prepared;
            reader.force_cursor(position);
            readSimpleValue(reader, type, listener);
            lastCursor = reader.prepared;
            reader.force_cursor(temp);
        }
    }
    listener.endMap(mapType);
    if (lastCursor > reader.prepared)
        reader.force_cursor(lastCursor);
}
Example #2
0
void readValueLink(ContentBuffer & reader, RecordParseListener & listener) {
    Link link;
    link.cluster = readVarint(reader);
    link.position = readVarint(reader);
    if (link.cluster == -2 && link.position == -1)
        listener.nullValue();
    else
        listener.linkValue(link);
}
Example #3
0
void readValueLinkMap(ContentBuffer & reader, RecordParseListener & listener, OType mapType) {
    int64_t size = readVarint(reader);
    listener.startMap(size, mapType);
    while (size-- > 0) {
        //Skipping because is everytime string
        reader.prepare(1);
        int key_size = readVarint(reader);
        reader.prepare(key_size);
        char * key_name = (char *) reader.content + reader.cursor;
        listener.mapKey(key_name, key_size);
        readValueLink(reader, listener);
    }
    listener.endMap(mapType);
}
static inline char *readString(spSkeletonBinary *self)
{
    char *start, *end;
    _spStringBuffer *buffer = self->buffer;
    int byteCount = readVarint(self, true);
 
    if (byteCount == 0) {
        return NULL;
    }
    
    if (buffer == NULL || buffer->capacity - buffer->position < byteCount) {
        self->buffer = (_spStringBuffer *)malloc(sizeof(_spStringBuffer));
        self->buffer->position = 0;
        self->buffer->capacity = MAX(BUFSIZ * 2, byteCount);
        self->buffer->content = (char *)malloc(self->buffer->capacity);
        self->buffer->next = buffer;
        buffer = self->buffer;
    }
    
    start = buffer->content + buffer->position;
    end = start;
    while (--byteCount) {
        *end++ =(char)READ();
    }
    *end++ = '\0';
    buffer->position += (int)(end - start);
    
    return start;
}
static void readVertices(spSkeletonBinary *self, spVertexAttachment *attachment, int vertexCount)
{
    if (!readBoolean(self)) {
        attachment->vertices = readFloats(self, self->scale, vertexCount << 1);
        attachment->verticesCount = vertexCount << 1;
        attachment->bones = NULL;
        attachment->bonesCount = 0;
    } else {
        float *weights;
        int *bones;
        int weightCount = 0, boneCount = 0;
        int position = self->data->position;
        
        for (int i = 0; i < vertexCount; i++) {
            int nn = readVarint(self, true);
            boneCount++;
            for (int ii = 0; ii < nn; ii++) {
                readVarint(self, true);
                self->data->position += sizeof(float) * 3;
                weightCount += 3;
                boneCount++;
            }
        }
        
        self->data->position = position;
        
        attachment->bones = MALLOC(int, boneCount);
        attachment->bonesCount = boneCount;
        attachment->vertices = MALLOC(float, weightCount);
        attachment->verticesCount = weightCount;
        weights = attachment->vertices;
        bones = attachment->bones;
        
        for (int i = 0; i < vertexCount; i++) {
            int nn = readVarint(self, true);
            *bones++ = nn;
            for (int ii = 0; ii < nn; ii++) {
                *bones++ = readVarint(self, true);
                *weights++ = readFloat(self) * self->scale;
                *weights++ = readFloat(self) * self->scale;
                *weights++ = readFloat(self);
            }
        }
    }
}
Example #6
0
void readValueLinkCollection(ContentBuffer & reader, RecordParseListener & listener, OType type) {
    int size = readVarint(reader);
    listener.startCollection(size, type);
    while (size-- > 0) {
        //TODO: handle null
        readValueLink(reader, listener);
    }
    listener.endCollection(type);

}
static spSkin *readSkin(spSkeletonBinary *self, const char *skinName)
{
    spSkin *skin;
    int slotCount = readVarint(self, true);
    
    if (slotCount == 0) {
        return NULL;
    }
    
    skin = spSkin_create(skinName);
    for (int i = 0; i < slotCount; i++) {
        int slotIndex = readVarint(self, true);
        int nn = readVarint(self, true);
        for (int ii = 0; ii < nn; ii++) {
            char *name = readString(self);
            spAttachment *attachment = readAttachment(self, skin, slotIndex, name);
            spSkin_addAttachment(skin, slotIndex, name, attachment);
        }
    }
    
    return skin;
}
Example #8
0
void readDocument(ContentBuffer &reader, RecordParseListener & listener) {
    int64_t class_size = readVarint(reader);
    if (class_size != 0) {
        reader.prepare(class_size);
        char * class_name = (char *) reader.content + reader.cursor;
        listener.startDocument(class_name, class_size);
    } else
        listener.startDocument("", 0);
    int64_t size = 0;
    int32_t lastCursor = 0;
    while ((size = readVarint(reader)) != 0) {
        if (size > 0) {
            reader.prepare(size);
            char * field_name = (char *) reader.content + reader.cursor;
            int32_t position = readFlat32Integer(reader);
            reader.prepare(1);
            if (position == 0) {
                listener.startField(field_name, size, ANY);
                listener.nullValue();
            } else {
                OType type = (OType) reader.content[reader.cursor];
                listener.startField(field_name, size, type);
                int temp = reader.prepared;
                reader.force_cursor(position);
                readSimpleValue(reader, type, listener);
                lastCursor = reader.prepared;
                reader.force_cursor(temp);
            }
            listener.endField(field_name, size);
        } else {
            throw new parse_exception("property id not supported by network serialization");
        }
    }
    listener.endDocument();
    if (lastCursor > reader.prepared)
        reader.force_cursor(lastCursor);
}
bool BinaryInputStreamSerializer::operator()(std::string& value, Common::StringView name) {
  uint64_t size;
  readVarint(stream, size);

  if (size > 0) {
    std::vector<char> temp;
    temp.resize(size);
    checkedRead(&temp[0], size);
    value.reserve(size);
    value.assign(&temp[0], size);
  } else {
    value.clear();
  }

  return true;
}
ISerializer& BinaryInputStreamSerializer::operator()(std::string& value, const std::string& name) {
  uint64_t size;
  readVarint(stream, size);

  if (size > 0) {
    std::vector<char> temp;
    temp.resize(size);
    checkedRead(&temp[0], size);
    value.reserve(size);
    value.assign(&temp[0], size);
  } else {
    value.clear();
  }

  return *this;
}
Example #11
0
void readValueEmbeddedCollection(ContentBuffer & reader, RecordParseListener & listener, OType collType) {
    int size = readVarint(reader);
    listener.startCollection(size, collType);
    reader.prepare(1);
    OType type = (OType) reader.content[reader.cursor];
    if (ANY == type) {
        while (size-- > 0) {
            reader.prepare(1);
            OType entryType = (OType) reader.content[reader.cursor];
            if (ANY == entryType)
                listener.nullValue();
            else
                readSimpleValue(reader, entryType, listener);
        }
    }
    listener.endCollection(collType);
    //For now else is impossible
}
static spAnimation *readAnimation(spSkeletonBinary *self, const char *name)
{
    float scale = self->scale;
    float duration = 0;
    int drawOrderCount;
    int eventCount;
    
    spAnimation *animation;
    _spTimelineArray arr;
    arr.timelines = NULL;
    arr.capacity = 0;
    arr.count = 0;
    
    // slot timelines
    for (int i = 0, n = readVarint(self, true); i < n; i++) {
        int slotIndex = readVarint(self, true);
        for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) {
            int timelineType = readByte(self);
            int frameCount = readVarint(self, true);
            switch (timelineType) {
                case SLOT_COLOR: {
                    spColorTimeline *timeline = spColorTimeline_create(frameCount);
                    timeline->slotIndex = slotIndex;
                    for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                        float time = readFloat(self);
                        float r, g, b, a;
                        readColor(self, &r, &g, &b, &a);
                        spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a);
                        if (frameIndex < frameCount - 1) {
                            readCurve(self, SUPER(timeline), frameIndex);
                        }
                    }
                    duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]);
                    addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
                    break;
                }
                case SLOT_ATTACHMENT: {
                    spAttachmentTimeline *timeline = spAttachmentTimeline_create(frameCount);
                    timeline->slotIndex = slotIndex;
                    for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                        float time = readFloat(self);
                        char *name = readString(self);
                        spAttachmentTimeline_setFrame(timeline, frameIndex, time, name);
                    }
                    duration = MAX(duration, timeline->frames[frameCount - 1]);
                    addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
                    break;
                }
            }
        }
    }
    
    // bone timelines
    for (int i = 0, n = readVarint(self, true); i < n; i++) {
        int boneIndex = readVarint(self, true);
        for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) {
            int timelineType = readByte(self);
            int frameCount = readVarint(self, true);
            switch (timelineType) {
                case BONE_ROTATE: {
                    spRotateTimeline *timeline = spRotateTimeline_create(frameCount);
                    timeline->boneIndex = boneIndex;
                    for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                        float time = readFloat(self);
                        float angle = readFloat(self);
                        spRotateTimeline_setFrame(timeline, frameIndex, time, angle);
                        if (frameIndex < frameCount - 1) {
                            readCurve(self, SUPER(timeline), frameIndex);
                        }
                    }
                    
                    duration = MAX(duration, timeline->frames[(frameCount - 1) * ROTATE_ENTRIES]);
                    addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
                    break;
                }
                case BONE_TRANSLATE:
                case BONE_SCALE:
                case BONE_SHEAR: {
                    spTranslateTimeline *timeline;
                    float timelineScale = 1;
                    if (timelineType == BONE_SCALE) {
                        timeline = spScaleTimeline_create(frameCount);
                    }
                    else if (timelineType == BONE_SHEAR)
                        timeline = spShearTimeline_create(frameCount);
                    else {
                        timeline = spTranslateTimeline_create(frameCount);
                        timelineScale = scale;
                    }
                    timeline->boneIndex = boneIndex;
                    for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                        float time = readFloat(self);
                        float x = readFloat(self) * timelineScale;
                        float y = readFloat(self) * timelineScale;
                        spTranslateTimeline_setFrame(timeline, frameIndex, time, x, y);
                        if (frameIndex < frameCount - 1) {
                            readCurve(self, SUPER(timeline), frameIndex);
                        }
                    }
                    
                    duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSLATE_ENTRIES]);
                    addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
                    break;
                }
            }
        }
    }
    
    // ik constraint timelines
    for (int i = 0, n = readVarint(self, true); i < n; i++) {
        int index = readVarint(self, true);
        int frameCount = readVarint(self, true);
        spIkConstraintTimeline *timeline = spIkConstraintTimeline_create(frameCount);
        timeline->ikConstraintIndex = index;
        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
            float time = readFloat(self);
            float mix = readFloat(self);
            int blendPositive = readByte(self);
            spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, blendPositive);
            if (frameIndex < frameCount - 1) {
                readCurve(self, SUPER(timeline), frameIndex);
            }
        }
        duration = MAX(duration, timeline->frames[(frameCount - 1) * IKCONSTRAINT_ENTRIES]);
        addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
    }
    
    // transform constraint timelines
    for (int i = 0, n = readVarint(self, true); i < n; i++) {
        int index = readVarint(self, true);
        int frameCount = readVarint(self, true);
        spTransformConstraintTimeline *timeline = spTransformConstraintTimeline_create(frameCount);
        timeline->transformConstraintIndex = index;
        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
            float time = readFloat(self);
            float rotateMix = readFloat(self);
            float translateMix = readFloat(self);
            float scaleMix = readFloat(self);
            float shearMix = readFloat(self);
            spTransformConstraintTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix, scaleMix, shearMix);
            if (frameIndex < frameCount - 1) {
                readCurve(self, SUPER(timeline), frameIndex);
            }
        }
        
        duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSFORMCONSTRAINT_ENTRIES]);
        addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
    }
    
    // path constraint timelines
    for (int i = 0, n = readVarint(self, true); i < n; i++) {
        int index = readVarint(self, true);
        spPathConstraintData *data = self->skeletonData->pathConstraints[index];
        for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) {
            int timelineType = readByte(self);
            int frameCount = readVarint(self, true);
            switch (timelineType) {
                case PATH_POSITION:
                case PATH_SPACING: {
                    spPathConstraintPositionTimeline *timeline;
                    float timelineScale = 1;
                    if (timelineType == PATH_SPACING) {
                        timeline = (spPathConstraintPositionTimeline *)spPathConstraintSpacingTimeline_create(frameCount);
                        if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) {
                            timelineScale = scale;
                        }
                    } else {
                        timeline = spPathConstraintPositionTimeline_create(frameCount);
                        if (data->positionMode == SP_POSITION_MODE_FIXED) {
                            timelineScale = scale;
                        }
                    }
                    timeline->pathConstraintIndex = index;
                    for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                        float time = readFloat(self);
                        float value = readFloat(self);
                        spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, time, value);
                        if (frameIndex < frameCount - 1) {
                            readCurve(self, SUPER(timeline), frameIndex);
                        }
                    }
                    duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTPOSITION_ENTRIES]);
                    addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
                    break;
                }
                case PATH_MIX: {
                    spPathConstraintMixTimeline *timeline = spPathConstraintMixTimeline_create(frameCount);
                    timeline->pathConstraintIndex = index;
                    for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                        float time = readFloat(self);
                        float rotateMix = readFloat(self);
                        float translateMix = readFloat(self);
                        spPathConstraintMixTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix);
                        if (frameIndex < frameCount - 1) {
                            readCurve(self, SUPER(timeline), frameIndex);
                        }
                    }
                    duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTMIX_ENTRIES]);
                    addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
                    break;
                }
            }
        }
    }
    
    // deform timelines
    for (int i = 0, n = readVarint(self, true); i < n; i++) {
        spSkin *skin = self->skeletonData->skins[readVarint(self, true)];
        for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) {
            int slotIndex = readVarint(self, true);
            for (int iii = 0, nnn = readVarint(self, true); iii < nnn; iii++) {
                char *name = readString(self);
                spVertexAttachment *attachment = SUB_CAST(spVertexAttachment, spSkin_getAttachment(skin, slotIndex, name));
                bool weighted = attachment->bones != NULL;
                float *vertices = attachment->vertices;
                int deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
                
                int frameCount = readVarint(self, true);
                
                spDeformTimeline *timeline = spDeformTimeline_create(frameCount, deformLength);
                timeline->slotIndex = slotIndex;
                timeline->attachment = SUPER(attachment);
                
                for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                    float time = readFloat(self);
                    float *deform;
                    int end = readVarint(self, true);
                    if (end == 0)
                        deform = weighted ? CALLOC(float, deformLength) : vertices;
                    else {
                        deform = CALLOC(float, deformLength);
                        int start = readVarint(self, true);
                        end += start;
                        if (scale == 1) {
                            for (int v = start; v < end; v++)
                                deform[v] = readFloat(self);
                        } else {
                            for (int v = start; v < end; v++)
                                deform[v] = readFloat(self) * scale;
                        }
                        if (!weighted) {
                            for (int v = 0, vn = deformLength; v < vn; v++)
                                deform[v] += vertices[v];
                        }
                    }
                    spDeformTimeline_setFrame(timeline, frameIndex, time, deform);
                    if (frameIndex < frameCount - 1) {
                        readCurve(self, SUPER(timeline), frameIndex);
                    }
                }
                duration = MAX(duration, timeline->frames[frameCount - 1]);
                addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
            }
        }
    }
static spAttachment *readAttachment(spSkeletonBinary *self, spSkin *skin, int slotIndex, const char *attachmentName)
{
    spAttachment *attachment = NULL;
    float scale = self->scale;
    
    char *name = readString(self);
    if (name == NULL) name = (char *)attachmentName;
    
    switch ((spAttachmentType)readByte(self)) {
        case SP_ATTACHMENT_REGION: {
            spRegionAttachment *region;
            
            char *path = readString(self);
            if (path == NULL) path = name;
            
            attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, SP_ATTACHMENT_REGION, name, path);
            region = SUB_CAST(spRegionAttachment, attachment);
            if (path) {
                region->path = copyString(path);
            }
            
            region->rotation = readFloat(self);
            region->x = readFloat(self) * scale;
            region->y = readFloat(self) * scale;
            region->scaleX = readFloat(self);
            region->scaleY = readFloat(self);
            region->width = readFloat(self) * scale;
            region->height = readFloat(self) * scale;
            readColor(self, &region->r, &region->g, &region->b, &region->a);
            
            spRegionAttachment_updateOffset(region);
            spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
            break;
        }
        case SP_ATTACHMENT_BOUNDING_BOX: {
            spBoundingBoxAttachment *boundingBox;
            int vertexCount = readVarint(self, true);
            
            attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, SP_ATTACHMENT_BOUNDING_BOX, name, name);
            boundingBox = SUB_CAST(spBoundingBoxAttachment, attachment);
            readVertices(self, SUPER(boundingBox), vertexCount);
            SUPER(boundingBox)->worldVerticesLength = vertexCount << 1;
            
            spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
            
            break;
        }
        case SP_ATTACHMENT_MESH: {
            spMeshAttachment *mesh;
            int vertexCount;
            
            char *path = readString(self);
            if (path == NULL) path = name;
            
            attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, SP_ATTACHMENT_MESH, name, path);
            mesh = SUB_CAST(spMeshAttachment, attachment);
            if (path) {
                mesh->path = copyString(path);
            }
            
            readColor(self, &mesh->r, &mesh->g, &mesh->b, &mesh->a);
            vertexCount = readVarint(self, true);
            mesh->regionUVs = readFloats(self, 1, vertexCount << 1);
            mesh->trianglesCount = readVarint(self, true);
            mesh->triangles = readShorts(self, mesh->trianglesCount);
            readVertices(self, SUPER(mesh), vertexCount);
            SUPER(mesh)->worldVerticesLength = vertexCount << 1;
            mesh->hullLength = readVarint(self, true) << 1;
            
            spMeshAttachment_updateUVs(mesh);
            spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
            break;
        }
        case SP_ATTACHMENT_LINKED_MESH: {
            spMeshAttachment *mesh;
            
            char *parent;
            char *skinName;
            char *path = readString(self);
            if (path == NULL) path = name;
            
            attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, SP_ATTACHMENT_LINKED_MESH, name, path);
            mesh = SUB_CAST(spMeshAttachment, attachment);
            if (path) {
                mesh->path = copyString(path);
            }
            
            readColor(self, &mesh->r, &mesh->g, &mesh->b, &mesh->a);
            skinName = readString(self);
            parent = readString(self);
            mesh->inheritDeform = readBoolean(self);
            
            addLinkedMesh(self, mesh, skinName, slotIndex, parent);
            break;
        }
        case SP_ATTACHMENT_PATH: {
            spPathAttachment *path;
            int vertexCount;
            
            attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, SP_ATTACHMENT_PATH, name, NULL);
            path = SUB_CAST(spPathAttachment, attachment);
            
            path->closed = readBoolean(self);
            path->constantSpeed = readBoolean(self);
            vertexCount = readVarint(self, true);
            readVertices(self, SUPER(path), vertexCount);
            SUPER(path)->worldVerticesLength = vertexCount << 1;
            path->lengthsLength = vertexCount / 3;
            path->lengths = MALLOC(float, path->lengthsLength);
            for (int i = 0; i < path->lengthsLength; i++) {
                path->lengths[i] = readFloat(self) * self->scale;
            }
            
            break;
        }
    }
    
    return attachment;
}
Example #14
0
void readValueString(ContentBuffer & reader, RecordParseListener & listener) {
    int64_t value_size = readVarint(reader);
    reader.prepare(value_size);
    listener.stringValue((char *) reader.content + reader.cursor, value_size);
}
                             deform[v] += vertices[v];
                     }
                 }
                 spDeformTimeline_setFrame(timeline, frameIndex, time, deform);
                 if (frameIndex < frameCount - 1) {
                     readCurve(self, SUPER(timeline), frameIndex);
                 }
             }
             duration = MAX(duration, timeline->frames[frameCount - 1]);
             addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline));
         }
     }
 }
 
 // draw order timeline
 drawOrderCount = readVarint(self, true);
 if (drawOrderCount > 0) {
     int frameCount = drawOrderCount;
     int slotCount = self->skeletonData->slotsCount;
     spDrawOrderTimeline *timeline = spDrawOrderTimeline_create(frameCount, slotCount);
     for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
         float time = readFloat(self);
         int offsetCount = readVarint(self, true);
         int *drawOrder = CALLOC(int, slotCount);
         for (int ii = slotCount - 1; ii >= 0; ii--) {
             drawOrder[ii] = -1;
         }
         int *unchanged = CALLOC(int, slotCount - offsetCount);
         int originalIndex = 0, unchangedIndex = 0;
         for (int ii = 0; ii < offsetCount; ii++) {
             int slotIndex = readVarint(self, true);
Example #16
0
void readSimpleValue(ContentBuffer &reader, OType type, RecordParseListener & listener) {

    switch (type) {
    case STRING:
        readValueString(reader, listener);
        break;
    case INTEGER: {
        int64_t value = readVarint(reader);
        listener.intValue(value);
    }
    break;
    case LONG: {
        int64_t value = readVarint(reader);
        listener.longValue(value);
    }
    break;
    case SHORT: {
        int64_t value = readVarint(reader);
        listener.shortValue(value);
    }
    break;
    case BYTE: {
        reader.prepare(1);
        listener.byteValue(reader.content[reader.cursor]);
    }
    break;

    case BOOLEAN: {
        reader.prepare(1);
        listener.booleanValue(reader.content[reader.cursor] != 0);
    }
    break;
    case DATE: {
        int64_t read = readVarint(reader);
        read *= 86400000;
        listener.dateValue(read);
    }
    break;
    case FLOAT: {
        int32_t i_val = readFlat32Integer(reader);
        float fl;
        memcpy(&fl, &i_val, 4);
        listener.floatValue(fl);
    }
    break;
    case DOUBLE: {
        int64_t i_val;
        reader.prepare(8);
        memcpy(&i_val, reader.content + reader.cursor, 8);
        i_val = be64toh(i_val);
        double db;
        memcpy(&db, &i_val, 8);
        listener.doubleValue(db);
    }
    break;
    case DATETIME: {
        int64_t value = readVarint(reader);
        listener.dateTimeValue(value);
    }
    break;
    case LINK: {
        readValueLink(reader, listener);
    }
    break;
    case LINKSET:
    case LINKLIST: {
        readValueLinkCollection(reader, listener, type);
    }
    break;
    case BINARY: {
        int64_t value_size = readVarint(reader);
        reader.prepare(value_size);
        listener.binaryValue((char *) reader.content + reader.cursor, value_size);
    }
    break;
    case EMBEDDEDLIST:
    case EMBEDDEDSET: {
        readValueEmbeddedCollection(reader, listener, type);
    }
    break;
    case EMBEDDEDMAP: {
        readValueEmbeddedMap(reader, listener, type);
    }
    break;
    case LINKMAP: {
        readValueLinkMap(reader, listener, type);
    }
    break;
    case EMBEDDED: {
        readDocument(reader, listener);
    }
    break;
    case LINKBAG: {
        readValueRidbag(reader, listener);
    }
    break;
    default:
        break;
    }

}
bool BinaryInputStreamSerializer::operator()(uint64_t& value, Common::StringView name) {
  readVarint(stream, value);
  return true;
}
ISerializer& BinaryInputStreamSerializer::operator()(uint32_t& value, const std::string& name) {
  readVarint(stream, value);
  return *this;
}
bool parseTransactionExtra(const std::vector<uint8_t> &transactionExtra, std::vector<TransactionExtraField> &transactionExtraFields) {
  transactionExtraFields.clear();

  if (transactionExtra.empty())
    return true;

  try {
    MemoryInputStream iss(transactionExtra.data(), transactionExtra.size());
    BinaryInputStreamSerializer ar(iss);

    int c = 0;

    while (!iss.endOfStream()) {
      c = read<uint8_t>(iss);
      switch (c) {
      case TX_EXTRA_TAG_PADDING: {
        size_t size = 1;
        for (; !iss.endOfStream() && size <= TX_EXTRA_PADDING_MAX_COUNT; ++size) {
          if (read<uint8_t>(iss) != 0) {
            return false; // all bytes should be zero
          }
        }

        if (size > TX_EXTRA_PADDING_MAX_COUNT) {
          return false;
        }

        transactionExtraFields.push_back(TransactionExtraPadding{ size });
        break;
      }

      case TX_EXTRA_TAG_PUBKEY: {
        TransactionExtraPublicKey extraPk;
        ar(extraPk.publicKey, "public_key");
        transactionExtraFields.push_back(extraPk);
        break;
      }

      case TX_EXTRA_NONCE: {
        TransactionExtraNonce extraNonce;
        uint8_t size = read<uint8_t>(iss);
        if (size > 0) {
          extraNonce.nonce.resize(size);
          read(iss, extraNonce.nonce.data(), extraNonce.nonce.size());
        }

        transactionExtraFields.push_back(extraNonce);
        break;
      }

      case TX_EXTRA_MERGE_MINING_TAG: {
        TransactionExtraMergeMiningTag mmTag;
        ar(mmTag, "mm_tag");
        transactionExtraFields.push_back(mmTag);
        break;
      }

      case TX_EXTRA_MESSAGE_TAG: {
        tx_extra_message message;
        ar(message.data, "message");
        transactionExtraFields.push_back(message);
        break;
      }

      case TX_EXTRA_TTL: {
        uint8_t size;
        readVarint(iss, size);
        TransactionExtraTTL ttl;
        readVarint(iss, ttl.ttl);
        transactionExtraFields.push_back(ttl);
        break;
      }
      }
    }
  } catch (std::exception &) {
    return false;
  }

  return true;
}