more PER support
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1245 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c
index 55bb664..01b606b 100644
--- a/skeletons/GeneralString.c
+++ b/skeletons/GeneralString.c
@@ -22,7 +22,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index f864d83..982cca5 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -147,6 +147,11 @@
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static asn_per_constraints_t asn_DEF_GeneralizedTime_constraints = {
+ { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ 0, 0
+};
asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
"GeneralizedTime",
"GeneralizedTime",
@@ -157,7 +162,8 @@
GeneralizedTime_encode_der,
OCTET_STRING_decode_xer_utf8,
GeneralizedTime_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
@@ -165,7 +171,7 @@
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
/ sizeof(asn_DEF_GeneralizedTime_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_GeneralizedTime_constraints,
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c
index 135cd73..7d59d52 100644
--- a/skeletons/GraphicString.c
+++ b/skeletons/GraphicString.c
@@ -22,7 +22,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
- 0, 0,
+ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c
index 5c000b0..8d81e44 100644
--- a/skeletons/IA5String.c
+++ b/skeletons/IA5String.c
@@ -12,6 +12,11 @@
(ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), /* [UNIVERSAL 22] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static asn_per_constraints_t asn_DEF_IA5String_constraints = {
+ { APC_CONSTRAINED, 7, 7, 0, 0x7f }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ 0, 0
+};
asn_TYPE_descriptor_t asn_DEF_IA5String = {
"IA5String",
"IA5String",
@@ -22,7 +27,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
@@ -30,7 +36,7 @@
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
/ sizeof(asn_DEF_IA5String_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_IA5String_constraints,
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c
index d164aa7..d6ded0e 100644
--- a/skeletons/ISO646String.c
+++ b/skeletons/ISO646String.c
@@ -12,6 +12,11 @@
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static asn_per_constraints_t asn_DEF_ISO646String_constraints = {
+ { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ 0, 0
+};
asn_TYPE_descriptor_t asn_DEF_ISO646String = {
"ISO646String",
"ISO646String",
@@ -22,7 +27,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
@@ -30,8 +36,7 @@
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
/ sizeof(asn_DEF_ISO646String_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_ISO646String_constraints,
0, 0, /* No members */
0 /* No specifics */
};
-
diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c
index 2b8ec16..a1ff91e 100644
--- a/skeletons/NativeReal.c
+++ b/skeletons/NativeReal.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
/*
@@ -12,6 +12,7 @@
#include <asn_internal.h>
#include <NativeReal.h>
#include <REAL.h>
+#include <OCTET_STRING.h>
/*
* NativeReal basic type description.
@@ -29,7 +30,8 @@
NativeReal_encode_der,
NativeReal_decode_xer,
NativeReal_encode_xer,
- 0, 0,
+ NativeReal_decode_uper,
+ NativeReal_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeReal_tags,
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
@@ -157,7 +159,74 @@
return erval;
}
+/*
+ * Decode REAL type using PER.
+ */
+asn_dec_rval_t
+NativeReal_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
+ void **dbl_ptr, asn_per_data_t *pd) {
+ double *Dbl = (double *)*dbl_ptr;
+ asn_dec_rval_t rval;
+ REAL_t tmp;
+ void *ptmp = &tmp;
+ int ret;
+ (void)constraints;
+
+ /*
+ * If the structure is not there, allocate it.
+ */
+ if(Dbl == NULL) {
+ *dbl_ptr = CALLOC(1, sizeof(*Dbl));
+ Dbl = (double *)*dbl_ptr;
+ if(Dbl == NULL)
+ _ASN_DECODE_FAILED;
+ }
+
+ memset(&tmp, 0, sizeof(tmp));
+ rval = OCTET_STRING_decode_uper(opt_codec_ctx, td, NULL,
+ &ptmp, pd);
+ if(rval.code != RC_OK) {
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
+ return rval;
+ }
+
+ ret = asn_REAL2double(&tmp, Dbl);
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
+ if(ret) _ASN_DECODE_FAILED;
+
+ return rval;
+}
+
+/*
+ * Encode the NativeReal using the OCTET STRING PER encoder.
+ */
+asn_enc_rval_t
+NativeReal_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ double Dbl = *(const double *)sptr;
+ asn_enc_rval_t erval;
+ REAL_t tmp;
+
+ (void)constraints;
+
+ /* Prepare a temporary clean structure */
+ memset(&tmp, 0, sizeof(tmp));
+
+ if(asn_double2REAL(&tmp, Dbl))
+ _ASN_ENCODE_FAILED;
+
+ /* Encode a DER REAL */
+ erval = OCTET_STRING_encode_uper(td, NULL, &tmp, po);
+ if(erval.encoded == -1)
+ erval.structure_ptr = sptr;
+
+ /* Free possibly allocated members of the temporary structure */
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
+
+ return erval;
+}
/*
* Decode the chunk of XML text encoding REAL.
diff --git a/skeletons/NativeReal.h b/skeletons/NativeReal.h
index 1f5266c..68a81d9 100644
--- a/skeletons/NativeReal.h
+++ b/skeletons/NativeReal.h
@@ -6,7 +6,7 @@
* This type differs from the standard REAL in that it is modelled using
* the fixed machine type (double), so it can hold only values of
* limited precision. There is no explicit type (i.e., NativeReal_t).
- * Use of this type is normally enabled by -fnative-integers.
+ * Use of this type is normally enabled by -fnative-types.
*/
#ifndef ASN_TYPE_NativeReal_H
#define ASN_TYPE_NativeReal_H
@@ -25,6 +25,8 @@
der_type_encoder_f NativeReal_encode_der;
xer_type_decoder_f NativeReal_decode_xer;
xer_type_encoder_f NativeReal_encode_xer;
+per_type_decoder_f NativeReal_decode_uper;
+per_type_encoder_f NativeReal_encode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c
index cef64ea..7c4cc95 100644
--- a/skeletons/NumericString.c
+++ b/skeletons/NumericString.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -12,6 +12,31 @@
(ASN_TAG_CLASS_UNIVERSAL | (18 << 2)), /* [UNIVERSAL 18] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static int asn_DEF_NumericString_v2c(unsigned int value) {
+ switch(value) {
+ case 0x20: return 0;
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
+ return value - (0x30 - 1);
+ }
+ return -1;
+}
+static int asn_DEF_NumericString_c2v(unsigned int code) {
+ if(code > 0) {
+ if(code <= 10)
+ return code + (0x30 - 1);
+ else
+ return -1;
+ } else {
+ return 0x20;
+ }
+}
+static asn_per_constraints_t asn_DEF_NumericString_constraints = {
+ { APC_CONSTRAINED, 4, 4, 0x20, 0x39 }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ asn_DEF_NumericString_v2c,
+ asn_DEF_NumericString_c2v
+};
asn_TYPE_descriptor_t asn_DEF_NumericString = {
"NumericString",
"NumericString",
@@ -22,7 +47,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_NumericString_tags,
sizeof(asn_DEF_NumericString_tags)
@@ -30,7 +56,7 @@
asn_DEF_NumericString_tags,
sizeof(asn_DEF_NumericString_tags)
/ sizeof(asn_DEF_NumericString_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_NumericString_constraints,
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index b1666dc..9f6402e 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -4,6 +4,7 @@
*/
#include <asn_internal.h>
#include <OBJECT_IDENTIFIER.h>
+#include <OCTET_STRING.h>
#include <limits.h> /* for CHAR_BIT */
#include <errno.h>
@@ -23,7 +24,8 @@
der_encode_primitive,
OBJECT_IDENTIFIER_decode_xer,
OBJECT_IDENTIFIER_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_OBJECT_IDENTIFIER_tags,
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 3a83bd9..a9747c4 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -1197,6 +1197,93 @@
OCTET_STRING__convert_entrefs);
}
+static int
+OCTET_STRING_per_get_expanded(asn_per_data_t *po, uint8_t *buf,
+ size_t size, long lb, long ub, int (*code2value)(unsigned int),
+ int unit_bits) {
+ uint8_t *end = buf + size;
+
+ ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
+ (int)size, lb, ub, unit_bits);
+
+ /* X.691: 27.5.4 */
+ if(ub <= (2 << (unit_bits - 1))) {
+ /* Decode without translation */
+ lb = 0;
+ } else if(code2value) {
+ for(; buf < end; buf++) {
+ int code = per_get_few_bits(po, unit_bits);
+ int value;
+ if(code < 0) return -1; /* WMORE */
+ value = code2value(code);
+ if(value < 0) {
+ ASN_DEBUG("Code %d (0x%02x) is"
+ " not in map (%ld..%ld)",
+ code, code, lb, ub);
+ return 1; /* FATAL */
+ }
+ *buf = value;
+ }
+ return 0;
+ }
+
+ for(; buf < end; buf++) {
+ int code = per_get_few_bits(po, unit_bits);
+ int ch = code + lb;
+ if(code < 0) return -1; /* WMORE */
+ if(ch > ub) {
+ ASN_DEBUG("Code %d is out of range (%ld..%ld)",
+ ch, lb, ub);
+ return 1; /* FATAL */
+ }
+ *buf = ch;
+ }
+
+ return 0;
+}
+
+static int
+OCTET_STRING_per_put_squeezed(asn_per_outp_t *po, const uint8_t *buf,
+ size_t size, long lb, long ub, int (*value2code)(unsigned int),
+ int unit_bits) {
+ const uint8_t *end = buf + size;
+
+ ASN_DEBUG("Squeezing %d bytes into (%ld..%ld):%d",
+ (int)size, lb, ub, unit_bits);
+
+ /* X.691: 27.5.4 */
+ if(ub <= (2 << (unit_bits - 1))) {
+ /* Encode as is */
+ lb = 0;
+ } else if(value2code) {
+ for(; buf < end; buf++) {
+ int code = value2code(*buf);
+ if(code < 0) {
+ ASN_DEBUG("Character %d (0x%02x) is"
+ " not in map (%ld..%ld)",
+ *buf, *buf, lb, ub);
+ return -1;
+ }
+ if(per_put_few_bits(po, code, unit_bits))
+ return -1;
+ }
+ }
+
+ for(ub -= lb; buf < end; buf++) {
+ int ch = *buf - lb;
+ if(ch < 0 || ch > ub) {
+ ASN_DEBUG("Character %d (0x%02x)"
+ " is out of range (%ld..%ld)",
+ *buf, *buf, lb, ub + lb);
+ return -1;
+ }
+ if(per_put_few_bits(po, ch, unit_bits))
+ return -1;
+ }
+
+ return 0;
+}
+
asn_dec_rval_t
OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
@@ -1205,15 +1292,17 @@
asn_OCTET_STRING_specifics_t *specs = td->specifics
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_DEF_OCTET_STRING_specs;
- asn_per_constraint_t *ct = constraints ? &constraints->size
- : (td->per_constraints
- ? &td->per_constraints->size
- : &asn_DEF_OCTET_STRING_constraint);
+ asn_per_constraints_t *pc = constraints ? constraints
+ : td->per_constraints;
+ asn_per_constraint_t *cv = pc ? &pc->value : 0;
+ asn_per_constraint_t *ct = pc ? &pc->size
+ : &asn_DEF_OCTET_STRING_constraint;
asn_dec_rval_t rval = { RC_OK, 0 };
BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
ssize_t consumed_myself = 0;
int repeat;
int unit_bits = (specs->subvariant != 1) * 7 + 1;
+ int expand = 0;
(void)opt_codec_ctx;
@@ -1225,8 +1314,13 @@
if(!st) RETURN(RC_FAIL);
}
- ASN_DEBUG("PER Decoding %s %ld .. %ld bits %d",
- ct->flags & APC_EXTENSIBLE ? "extensible" : "fixed",
+ if(cv && (cv->flags & APC_CONSTRAINED)) {
+ unit_bits = cv->range_bits;
+ if(unit_bits != 8) expand = 1;
+ }
+
+ ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
+ ct->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
ct->lower_bound, ct->upper_bound, ct->effective_bits);
if(ct->flags & APC_EXTENSIBLE) {
@@ -1252,8 +1346,17 @@
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
if(ct->effective_bits == 0) {
- int ret = per_get_many_bits(pd, st->buf, 0,
+ int ret;
+ if(expand) {
+ ret = OCTET_STRING_per_get_expanded(pd, st->buf,
+ cv->upper_bound,
+ cv->lower_bound, cv->upper_bound,
+ pc->code2value, unit_bits);
+ if(ret > 0) RETURN(RC_FAIL);
+ } else {
+ ret = per_get_many_bits(pd, st->buf, 0,
unit_bits * ct->upper_bound);
+ }
if(ret < 0) RETURN(RC_WMORE);
consumed_myself += unit_bits * ct->upper_bound;
st->buf[st->size] = 0;
@@ -1277,7 +1380,7 @@
ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
(long)ct->effective_bits, (long)len_bits,
repeat ? "repeat" : "once", td->name);
- if(unit_bits == 1) {
+ if(unit_bits == 1 && !expand) {
len_bytes = (len_bits + 7) >> 3;
if(len_bits & 0x7)
st->bits_unused = 8 - (len_bits & 0x7);
@@ -1290,7 +1393,16 @@
if(!p) RETURN(RC_FAIL);
st->buf = (uint8_t *)p;
- ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
+ if(expand) {
+ ret = OCTET_STRING_per_get_expanded(pd,
+ &st->buf[st->size], len_bytes,
+ cv->lower_bound, cv->upper_bound,
+ pc->code2value, unit_bits);
+ if(ret > 0) RETURN(RC_FAIL);
+ } else {
+ ret = per_get_many_bits(pd, &st->buf[st->size],
+ 0, len_bits);
+ }
if(ret < 0) RETURN(RC_WMORE);
st->size += len_bytes;
} while(repeat);
@@ -1306,17 +1418,19 @@
asn_OCTET_STRING_specifics_t *specs = td->specifics
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_DEF_OCTET_STRING_specs;
- asn_per_constraint_t *ct = constraints ? &constraints->size
- : (td->per_constraints
- ? &td->per_constraints->size
- : &asn_DEF_OCTET_STRING_constraint);
+ asn_per_constraints_t *pc = constraints ? constraints
+ : td->per_constraints;
+ asn_per_constraint_t *cv = pc ? &pc->value : 0;
+ asn_per_constraint_t *ct = pc ? &pc->size
+ : &asn_DEF_OCTET_STRING_constraint;
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
- int unit_bits = (specs->subvariant != 1) * 7 + 1;
asn_enc_rval_t er;
int ct_extensible = ct->flags & APC_EXTENSIBLE;
int inext = 0; /* Lies not within extension root */
+ int unit_bits = (specs->subvariant != 1) * 7 + 1;
int sizeinunits = st->size;
const uint8_t *buf;
+ int squeeze = 0;
int ret;
if(!st || !st->buf)
@@ -1328,13 +1442,18 @@
sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
}
+ if(cv && (cv->flags & APC_CONSTRAINED)) {
+ unit_bits = cv->range_bits;
+ if(unit_bits != 8) squeeze = 1;
+ }
+
ASN_DEBUG("Encoding %s into %d units of %d bits"
- " (%d..%d, effective %d)%s",
+ " (%ld..%ld, effective %d)%s",
td->name, sizeinunits, unit_bits,
ct->lower_bound, ct->upper_bound,
ct->effective_bits, ct_extensible ? " EXT" : "");
- /* Figure out wheter size lies within PER visible consrtaint */
+ /* Figure out wheter size lies within PER visible constraint */
if(ct->effective_bits >= 0) {
if(sizeinunits < ct->lower_bound
@@ -1365,7 +1484,14 @@
ret = per_put_few_bits(po, sizeinunits - ct->lower_bound,
ct->effective_bits);
if(ret) _ASN_ENCODE_FAILED;
- ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits);
+ if(squeeze) {
+ ret = OCTET_STRING_per_put_squeezed(po, st->buf,
+ sizeinunits, cv->lower_bound, cv->upper_bound,
+ pc->value2code, unit_bits);
+ } else {
+ ret = per_put_many_bits(po, st->buf,
+ sizeinunits * unit_bits);
+ }
if(ret) _ASN_ENCODE_FAILED;
_ASN_ENCODED_OK(er);
}
@@ -1385,10 +1511,16 @@
ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
- ret = per_put_many_bits(po, buf, maySave * unit_bits);
+ if(squeeze) {
+ ret = OCTET_STRING_per_put_squeezed(po, buf,
+ maySave, cv->lower_bound, cv->upper_bound,
+ pc->value2code, unit_bits);
+ } else {
+ ret = per_put_many_bits(po, buf, maySave * unit_bits);
+ }
if(ret) _ASN_ENCODE_FAILED;
- if(unit_bits == 1)
+ if(unit_bits == 1 && !squeeze)
buf += maySave >> 3;
else
buf += maySave;
diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c
index 44cb5f6..cd8e8a3 100644
--- a/skeletons/ObjectDescriptor.c
+++ b/skeletons/ObjectDescriptor.c
@@ -22,7 +22,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_ObjectDescriptor_tags,
sizeof(asn_DEF_ObjectDescriptor_tags)
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index f588083..318bff1 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -1,17 +1,52 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <PrintableString.h>
/*
+ * ASN.1:1984 (X.409)
+ */
+static int _PrintableString_alphabet[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
+ 1, 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 5, 6, 7, 8, 9, /* . '() +,-./ */
+10,11,12,13,14,15,16,17,18,19,20, 0, 0,21, 0,22, /* 0123456789: = ? */
+ 0,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, /* ABCDEFGHIJKLMNO */
+38,39,40,41,42,43,44,45,46,47,48, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ */
+ 0,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, /* abcdefghijklmno */
+64,65,66,67,68,69,70,71,72,73,74, 0, 0, 0, 0, 0, /* pqrstuvwxyz */
+};
+static int _PrintableString_code2value[74] = {
+32,39,40,41,43,44,45,46,47,48,49,50,51,52,53,54,
+55,56,57,58,61,63,65,66,67,68,69,70,71,72,73,74,
+75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,
+97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
+113,114,115,116,117,118,119,120,121,122};
+
+/*
* PrintableString basic type description.
*/
static ber_tlv_tag_t asn_DEF_PrintableString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (19 << 2)), /* [UNIVERSAL 19] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static int asn_DEF_PrintableString_v2c(unsigned int value) {
+ return _PrintableString_alphabet[value > 255 ? 0 : value] - 1;
+}
+static int asn_DEF_PrintableString_c2v(unsigned int code) {
+ if(code < 74)
+ return _PrintableString_code2value[code];
+ return -1;
+}
+static asn_per_constraints_t asn_DEF_PrintableString_constraints = {
+ { APC_CONSTRAINED, 4, 4, 0x20, 0x39 }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ asn_DEF_PrintableString_v2c,
+ asn_DEF_PrintableString_c2v
+};
asn_TYPE_descriptor_t asn_DEF_PrintableString = {
"PrintableString",
"PrintableString",
@@ -22,7 +57,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_PrintableString_tags,
sizeof(asn_DEF_PrintableString_tags)
@@ -30,34 +66,12 @@
asn_DEF_PrintableString_tags,
sizeof(asn_DEF_PrintableString_tags)
/ sizeof(asn_DEF_PrintableString_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_PrintableString_constraints,
0, 0, /* No members */
0 /* No specifics */
};
-/*
- * ASN.1:1984 (X.409)
- */
-static int _PrintableString_alphabet[256] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* ' */
-0x41, 0x42, 0x00, 0x43, 0x44, 0x45, 0x46, 0x47, /* ( ) + , - . / */
-0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, /* 0 1 2 3 4 5 6 7 */
-0x3d, 0x3e, 0x48, 0x00, 0x00, 0x49, 0x00, 0x4a, /* 8 9 : = ? */
-0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A B C D E F G */
-0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* H I J K L M N O */
-0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* P Q R S T U V W */
-0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, /* X Y Z */
-0x00, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, /* a b c d e f g */
-0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, /* h i j k l m n o */
-0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, /* p q r s t u v w */
-0x32, 0x33, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, /* x y z */
-};
-
int
PrintableString_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index 51098c0..32f9221 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#if defined(__alpha)
@@ -12,6 +12,7 @@
#include <math.h>
#include <errno.h>
#include <REAL.h>
+#include <OCTET_STRING.h>
#undef INT_MAX
#define INT_MAX ((int)(((unsigned int)-1) >> 1))
@@ -42,7 +43,8 @@
der_encode_primitive,
REAL_decode_xer,
REAL_encode_xer,
- 0, 0,
+ REAL_decode_uper,
+ REAL_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_REAL_tags,
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
@@ -341,6 +343,20 @@
buf_ptr, size, REAL__xer_body_decode);
}
+asn_dec_rval_t
+REAL_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
+ void **sptr, asn_per_data_t *pd) {
+ (void)constraints; /* No PER visible constraints */
+ return OCTET_STRING_decode_uper(opt_codec_ctx, td, 0, sptr, pd);
+}
+
+asn_enc_rval_t
+REAL_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ (void)constraints; /* No PER visible constraints */
+ return OCTET_STRING_encode_uper(td, 0, sptr, po);
+}
int
asn_REAL2double(const REAL_t *st, double *dbl_value) {
diff --git a/skeletons/REAL.h b/skeletons/REAL.h
index 28ccf28..af3e84c 100644
--- a/skeletons/REAL.h
+++ b/skeletons/REAL.h
@@ -19,6 +19,8 @@
asn_struct_print_f REAL_print;
xer_type_decoder_f REAL_decode_xer;
xer_type_encoder_f REAL_encode_xer;
+per_type_decoder_f REAL_decode_uper;
+per_type_encoder_f REAL_encode_uper;
/***********************************
* Some handy conversion routines. *
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 0181434..983fc09 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -5,6 +5,7 @@
*/
#include <asn_internal.h>
#include <RELATIVE-OID.h>
+#include <OCTET_STRING.h>
#include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
#include <limits.h> /* for CHAR_BIT */
#include <errno.h>
@@ -25,7 +26,8 @@
der_encode_primitive,
RELATIVE_OID_decode_xer,
RELATIVE_OID_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_RELATIVE_OID_tags,
sizeof(asn_DEF_RELATIVE_OID_tags)
diff --git a/skeletons/T61String.c b/skeletons/T61String.c
index 25d887a..98461bb 100644
--- a/skeletons/T61String.c
+++ b/skeletons/T61String.c
@@ -22,7 +22,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_T61String_tags,
sizeof(asn_DEF_T61String_tags)
diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c
index b96cb3b..81e646b 100644
--- a/skeletons/TeletexString.c
+++ b/skeletons/TeletexString.c
@@ -22,7 +22,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_TeletexString_tags,
sizeof(asn_DEF_TeletexString_tags)
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index 2a27718..41a31dd 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -23,6 +23,11 @@
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static asn_per_constraints_t asn_DEF_UTCTime_constraints = {
+ { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ 0, 0
+};
asn_TYPE_descriptor_t asn_DEF_UTCTime = {
"UTCTime",
"UTCTime",
@@ -33,7 +38,8 @@
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
OCTET_STRING_decode_xer_utf8,
UTCTime_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_UTCTime_tags,
sizeof(asn_DEF_UTCTime_tags)
@@ -41,7 +47,7 @@
asn_DEF_UTCTime_tags,
sizeof(asn_DEF_UTCTime_tags)
/ sizeof(asn_DEF_UTCTime_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_UTCTime_constraints,
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
index e3f7388..1e84815 100644
--- a/skeletons/UTF8String.c
+++ b/skeletons/UTF8String.c
@@ -23,7 +23,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_UTF8String_tags,
sizeof(asn_DEF_UTF8String_tags)
diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c
index 5f5f33d..df7233e 100644
--- a/skeletons/VideotexString.c
+++ b/skeletons/VideotexString.c
@@ -22,7 +22,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
- 0, 0,
+ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_VideotexString_tags,
sizeof(asn_DEF_VideotexString_tags)
diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c
index 8796582..49a94c1 100644
--- a/skeletons/VisibleString.c
+++ b/skeletons/VisibleString.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -12,6 +12,11 @@
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
+static asn_per_constraints_t asn_DEF_VisibleString_constraints = {
+ { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */
+ { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
+ 0, 0
+};
asn_TYPE_descriptor_t asn_DEF_VisibleString = {
"VisibleString",
"VisibleString",
@@ -22,7 +27,8 @@
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
- 0, 0,
+ OCTET_STRING_decode_uper,
+ OCTET_STRING_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_VisibleString_tags,
sizeof(asn_DEF_VisibleString_tags)
@@ -30,7 +36,7 @@
asn_DEF_VisibleString_tags,
sizeof(asn_DEF_VisibleString_tags)
/ sizeof(asn_DEF_VisibleString_tags[0]),
- 0, /* No PER visible constraints */
+ &asn_DEF_VisibleString_constraints,
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index 09f27db..96d2ae8 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -921,7 +921,7 @@
ASN_DEBUG("Failed to add element into %s",
td->name);
/* Fall through */
- rv.code == RC_FAIL;
+ rv.code = RC_FAIL;
} else {
ASN_DEBUG("Failed decoding %s of %s (SET OF)",
elm->type->name, td->name);
diff --git a/skeletons/per_support.h b/skeletons/per_support.h
index 420bb83..2708724 100644
--- a/skeletons/per_support.h
+++ b/skeletons/per_support.h
@@ -29,6 +29,8 @@
typedef struct asn_per_constraints_s {
asn_per_constraint_t value;
asn_per_constraint_t size;
+ int (*value2code)(unsigned int value);
+ int (*code2value)(unsigned int code);
} asn_per_constraints_t;
/*
diff --git a/skeletons/tests/check-OIDs.c b/skeletons/tests/check-OIDs.c
index 4d4c9b5..b7fafe0 100644
--- a/skeletons/tests/check-OIDs.c
+++ b/skeletons/tests/check-OIDs.c
@@ -442,3 +442,7 @@
return 0;
}
+
+asn_dec_rval_t OCTET_STRING_decode_uper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; }
+
+asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; }
diff --git a/skeletons/tests/check-REAL.c b/skeletons/tests/check-REAL.c
index 641da2d..3a868aa 100644
--- a/skeletons/tests/check-REAL.c
+++ b/skeletons/tests/check-REAL.c
@@ -286,3 +286,7 @@
return 0;
}
+
+asn_dec_rval_t OCTET_STRING_decode_uper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; }
+
+asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; }