Work with more than 2 different structures in ASN.1 (C++) with asn1c compiler.

huangapple go评论62阅读模式
英文:

Work with more than 2 different structures in ASN.1 (C++) with asn1c compiler

问题

我在ASN.1中有两种不同的结构:一个矩形和一个圆:

Mystructs DEFINITIONS ::= BEGIN

Rectangle ::= SEQUENCE {
    height INTEGER (0..255),
    width INTEGER (0..255)
}

Circle ::= SEQUENCE {
    radius INTEGER (0..255)
}

END

在编译后,我可以对这些结构进行编码(uper_encode())并发送矩形或圆。我的问题是,当我想解码这些结构(uper_decode())时,我应该预先知道我正在接收什么,但实际上我不知道。我只知道它可能是一个圆或一个矩形。

因此,我想在发送编码数据后添加一个标签(如标头),以便在解码之前可以处理它,以知道应该使用哪个模板来解码:矩形还是圆。

但是,我不知道如何做到这一点。

谢谢!

英文:

I have 2 different structures in ASN.1: a rectangle and a circle:

Mystructs DEFINITIONS ::= BEGIN

Rectangle ::= SEQUENCE {
	height INTEGER (0..255),
	width INTEGER (0..255)
}
  
Circle ::= SEQUENCE {
    radius INTEGER (0..255)
}

END

After the compilation, I can encode these structures (uper_encode()) and send either the rectangle or the circle. My problem is that when I want to decode the structures (uper_decode()), I should know a priori what I am receiving but actually I don't know. I only know that it could be a circle or a rectangle.

So I thought that I could add somehow a tag after sending the encoded data (like a header) that I can process before I decode to know which template should I use to decode: rectangle or circle.

However, I do not know how to do this.

Thanks!!!

答案1

得分: 1

如@Botje和@Kevin所回答的,您需要一个CHOICE。

但是,如果您将其添加到规范中,您需要标记这些替代项(因为它们都是未标记的SEQUENCE类型)。

Mystructs DEFINITIONS ::= BEGIN

CircleOrRectangle ::= CHOICE {
    circle [0] Circle,
    rectangle [1]  Rectangle
}

Rectangle ::= SEQUENCE {
    height INTEGER (0..255),
    width INTEGER (0..255)
}

Circle ::= SEQUENCE {
    radius INTEGER (0..255)
}

END

另一个选项,如果可以的话更好,是在DEFINITIONS级别添加AUTOMATIC TAGS。

Mystructs DEFINITIONS AUTOMATIC TAGS ::= BEGIN

CircleOrRectangle ::= CHOICE {
  circle Circle,
  rectangle  Rectangle
}

Rectangle ::= SEQUENCE {
    height INTEGER (0..255),
    width INTEGER (0..255)
}

Circle ::= SEQUENCE {
    radius INTEGER (0..255)
}

END

编辑...

使用https://github.com/vlm/asn1c,这个CHOICE将在CircleOrRectangle.h中定义。

/* 依赖项 */
typedef enum CircleOrRectangle_PR {
    CircleOrRectangle_PR_NOTHING,    /* 无组件 */
    CircleOrRectangle_PR_circle,
    CircleOrRectangle_PR_rectangle
} CircleOrRectangle_PR;

/* CircleOrRectangle */
typedef struct CircleOrRectangle {
    CircleOrRectangle_PR present;
    union CircleOrRectangle_u {
        Circle_t     circle;
        Rectangle_t  rectangle;
    } choice;

    /* 跨越缓冲区边界的解析上下文 */
    asn_struct_ctx_t _asn_ctx;
} CircleOrRectangle_t;

正如您所看到的,它被映射为一个包含枚举和联合的结构体。枚举将告诉您在联合中使用哪个成员。

英文:

As @Botje and @Kevin answered you need a CHOICE

However, if you add it to your specification, you need to tag the alternatives (because they are both untagged SEQUENCE types)

Mystructs DEFINITIONS ::= BEGIN


CircleOrRectangle ::= CHOICE {
    circle [0] Circle,
    rectangle [1]  Rectangle
}

Rectangle ::= SEQUENCE {
    height INTEGER (0..255),
    width INTEGER (0..255)
}
  
Circle ::= SEQUENCE {
    radius INTEGER (0..255)
}

END

Another option, which is better if you can, is to add AUTOMATIC TAGS at the DEFINITIONS level

Mystructs DEFINITIONS AUTOMATIC TAGS ::= BEGIN


CircleOrRectangle ::= CHOICE {
  circle Circle,
  rectangle  Rectangle
}

Rectangle ::= SEQUENCE {
    height INTEGER (0..255),
    width INTEGER (0..255)
}
  
Circle ::= SEQUENCE {
    radius INTEGER (0..255)
}

END

EDIT ...

Using https://github.com/vlm/asn1c, this choice will be defined in CircleOrRectangle.h

/* Dependencies */
typedef enum CircleOrRectangle_PR {
	CircleOrRectangle_PR_NOTHING,	/* No components present */
	CircleOrRectangle_PR_circle,
	CircleOrRectangle_PR_rectangle
} CircleOrRectangle_PR;

/* CircleOrRectangle */
typedef struct CircleOrRectangle {
	CircleOrRectangle_PR present;
	union CircleOrRectangle_u {
		Circle_t	 circle;
		Rectangle_t	 rectangle;
	} choice;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} CircleOrRectangle_t;

As you see, it is mapped as as a struct containing an enum and a union. The enum will tell you which member to use in the union.

答案2

得分: 0

CircleOrRectangle ::= CHOICE {
circle 圆形,
rectangle 矩形
}

编码将携带关于所做选择的信息。

英文:

I think you are looking for a CHOICE type.

CircleOrRectangle ::= CHOICE {
  circle Circle,
  rectangle Rectangle
}

The encoding will then carry information about which selection was made.

huangapple
  • 本文由 发表于 2023年6月19日 19:40:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506266.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定