Commit 963616f1 authored by Anett Jakab's avatar Anett Jakab
Browse files

BER TitanInteger


Signed-off-by: Anett Jakab's avatarAnett Jakab <jakabanett13@gmail.com>
parent 1882922f
......@@ -7,9 +7,13 @@
******************************************************************************/
package org.eclipse.titan.runtime.core;
import java.math.BigInteger;
import java.text.MessageFormat;
import org.eclipse.titan.runtime.core.BER.ASN_BER_TLV;
import org.eclipse.titan.runtime.core.BER.ASN_BERdescriptor;
import org.eclipse.titan.runtime.core.BER.ASN_Tag;
import org.eclipse.titan.runtime.core.BER.ASN_TagClass;
import org.eclipse.titan.runtime.core.JSON.TTCN_JSONdescriptor;
import org.eclipse.titan.runtime.core.JSON.json_string_escaping;
import org.eclipse.titan.runtime.core.Param_Types.Module_Param_Name;
......@@ -17,9 +21,12 @@ import org.eclipse.titan.runtime.core.Param_Types.Module_Parameter;
import org.eclipse.titan.runtime.core.RAW.RAW_Force_Omit;
import org.eclipse.titan.runtime.core.RAW.RAW_enc_tree;
import org.eclipse.titan.runtime.core.RAW.TTCN_RAWdescriptor;
import org.eclipse.titan.runtime.core.TTCN_EncDec.error_type;
import org.eclipse.titan.runtime.core.TTCN_EncDec.raw_order_t;
import org.eclipse.titan.runtime.core.TTCN_Logger.Severity;
import javafx.util.Pair;
/**
* The base class of all types.
*
......@@ -517,4 +524,230 @@ public abstract class Base_Type {
public final int JSON_decode(final TTCN_Typedescriptor p_td, final JSON_Tokenizer p_tok, final boolean p_silent, final boolean p_parent_is_map) {
return JSON_decode(p_td, p_tok, p_silent, p_parent_is_map, JSON.CHOSEN_FIELD_UNSET);
}
//native int
public ASN_BER_TLV BER_encode_TLV_Integer(final TTCN_Typedescriptor p_td, boolean nativeFlag, int p_int_val,
BigInteger p_openssl) {
if (nativeFlag) {
// Determine the number of octets to be used in the encoding.
// check if int_value is bigger than 0
// should be treated as unsigned int
int uVal = (p_int_val >= 0) ? p_int_val : ~p_int_val;
int Vlen = 1;
uVal >>>= 7; //shift the int value with 7 bits
while (uVal != 0) {
Vlen++;
uVal >>>= 8;
}
ASN_BER_TLV newTlv = new ASN_BER_TLV(Vlen, null); //create new tlv with only the V(value) part's length
uVal = (int) p_int_val;
byte[] Vstr = new byte[Vlen];
//create the V part from the int
for (int i = Vlen; i > 0; i--){
Vstr[i-1] = (byte) (uVal & 0xFF);
uVal >>>= 8;
}
newTlv.setVstr(Vstr); //set_V function needed in BER.java
return newTlv;
}
//bignum
BigInteger D = p_openssl;
if (D.equals(BigInteger.ZERO)) {
ASN_BER_TLV newTlv = new ASN_BER_TLV(1, null);
newTlv.Vstr = new byte[1];
newTlv.Vstr[0] = 0;
return newTlv;
}
byte[] bnAsBytes = D.toByteArray();
int numBytes = bnAsBytes.length;
ASN_BER_TLV newTlv = new ASN_BER_TLV(numBytes, null);
newTlv.Vstr = bnAsBytes;
return newTlv;
}
public void BER_encode_chk_coding(int p_coding) {
switch (p_coding) {
case BER.BER_ENCODE_CER:
break;
case BER.BER_ENCODE_DER:
break;
default: {
//warning
p_coding = BER.BER_ENCODE_DER;
break;
}
}
}
public static void BER_decode_chk_tag(ASN_Tag tag, ASN_BER_TLV tlv) {
if (tlv.isTagComplete && (tag.tagclass != tlv.tagclass || tag.tagnumber != tlv.tagnumber)) {
ASN_Tag recievedTag = new ASN_Tag(tag.tagclass, tag.tagnumber);
String recievedStr = recievedTag.print();
/*try {
}catch(...) {
throw();
}*/
}
}
public void BER_decode_str2TLV(TTCN_Buffer p_buf, ASN_BER_TLV p_tlv, int L_form) {
if (!p_tlv.ASN_BER_str2TLV(p_buf.get_read_len(), p_buf.get_read_data(), L_form)) {
throw new TtcnError("TLV is not complete.");
}
}
public boolean BER_decode_constdTLV_next(ASN_BER_TLV p_tlv, int V_pos, int L_form, ASN_BER_TLV p_target_tlv) {
if (p_tlv.Vlen <= V_pos) {
if (!p_tlv.isLenDefinite) {
//ttcn error
return false;
}
}
if (!p_target_tlv.ASN_BER_str2TLV(p_tlv.Vlen - V_pos, p_tlv.subArray(p_tlv.Vstr, V_pos, p_tlv.Vlen), L_form)) {
throw new TtcnError("Incomplete TLV in the constructed TLV.");
}
if (!p_tlv.isLenDefinite && p_target_tlv.tagnumber == 0 && p_target_tlv.tagclass == ASN_TagClass.ASN_TAG_UNIV) {
return false;
}
V_pos += p_target_tlv.Tlen + p_target_tlv.Llen + p_target_tlv.Vlen;
return true;
}
public void BER_decode_constdTLV_end(ASN_BER_TLV p_tlv, int V_pos, int L_form, ASN_BER_TLV p_target_tlv,
boolean tlv_present) {
if (tlv_present || BER_decode_constdTLV_next(p_tlv, V_pos, L_form, p_target_tlv)) {
throw new TtcnError("Superfluous TLV(s) at the end of constructed TLV.");
}
}
public ASN_BER_TLV BER_decode_strip_tags(ASN_BERdescriptor p_ber, ASN_BER_TLV p_tlv, int L_form, ASN_BER_TLV stripped_tlv) {
int i = p_ber.number_of_tags;
if (i == 0) {
stripped_tlv = p_tlv;
return stripped_tlv;
}
//String expectedStr = p_ber.printTags();
if (i == 1) {
BER_decode_chk_tag(p_ber.tags[0], p_tlv);
stripped_tlv = p_tlv;
return stripped_tlv;
}
ASN_BER_TLV currentTlv = p_tlv;
boolean doIt = true;
i--;
while (doIt) {
BER_decode_chk_tag(p_ber.tags[i], currentTlv);
if (i != 0) { // not the innermost tag
if(!currentTlv.isConstructed) {
TTCN_EncDec_ErrorContext.error(error_type.ET_TAG, "The other (innermost %lu) tag(s) are missing.", i);
doIt = false;
stripped_tlv=currentTlv;
} else { // O.K., is constructed
int Vpos=0;
BER_decode_constdTLV_next(currentTlv, Vpos, L_form, stripped_tlv);
// if superfluous...?
ASN_BER_TLV endchecker_tlv = new ASN_BER_TLV();
BER_decode_constdTLV_end(currentTlv, Vpos, L_form, endchecker_tlv, false);
currentTlv=stripped_tlv;
i--;
} // is constructed
} else { // innermost tag
doIt = false;
}
}
return stripped_tlv;
}
public Pair<Boolean, TitanInteger> BER_decode_TLV_Integer(ASN_BER_TLV p_tlv, int p_unsigned, TitanInteger p_int_val) {
p_tlv.chk_constructedFlag(false);
if(!p_tlv.isComplete) {
return new Pair<Boolean, TitanInteger> (false, p_int_val);
}
if(p_tlv.Vlen == 0) {
TTCN_EncDec_ErrorContext.error(error_type.ET_INVAL_MSG, "Length of V-part is 0.");
return new Pair<Boolean, TitanInteger> (false, p_int_val);
}
int Vlen = p_tlv.Vlen;
//bignum
if(Vlen >= Integer.BYTES) {
BigInteger D = new BigInteger(p_tlv.Vstr);
return new Pair<Boolean, TitanInteger> (true, new TitanInteger(D));
}
//Native int
byte[] Vstr = p_tlv.Vstr;
int intVal = 0;
if ((Vstr[0] & 0x80) < 0) {
for (int i = 0; i < Integer.BYTES - Vlen; i++) {
intVal |= 0xFF;
intVal <<= 8;
}
}
intVal |= p_tlv.Vstr[0];
for (int i = 1; i < Vlen; i++) {
intVal <<= 8;
intVal |= p_tlv.Vstr[i];
}
p_int_val = new TitanInteger(intVal);
return new Pair<Boolean, TitanInteger> (true, p_int_val);
}
public ASN_BER_TLV BER_encode_chk_bound(boolean p_isbound) {
if (!p_isbound) {
ASN_BER_TLV newTlv = new ASN_BER_TLV(0, null);
return newTlv;
}
return null;
}
}
......@@ -12,6 +12,7 @@ import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.titan.runtime.core.BER.ASN_BER_TLV;
import org.eclipse.titan.runtime.core.BER.ASN_BERdescriptor;
import org.eclipse.titan.runtime.core.BER.ASN_Tag;
import org.eclipse.titan.runtime.core.BER.ASN_TagClass;
......@@ -36,6 +37,8 @@ import org.eclipse.titan.runtime.core.TTCN_EncDec.error_type;
import org.eclipse.titan.runtime.core.TTCN_EncDec.raw_order_t;
import org.eclipse.titan.runtime.core.TitanCharString.CharCoding;
import javafx.util.Pair;
/**
* TTCN-3 integer
......@@ -45,10 +48,10 @@ import org.eclipse.titan.runtime.core.TitanCharString.CharCoding;
*/
public class TitanInteger extends Base_Type {
private static final ASN_Tag TitanInteger_tag_[] = new ASN_Tag[] {new ASN_Tag(ASN_TagClass.ASN_TAG_UNIV, 2)};
public static final ASN_BERdescriptor TitanInteger_Ber_ = new ASN_BERdescriptor(1, TitanInteger_tag_);
public static final ASN_BERdescriptor TitanInteger_ber_ = new ASN_BERdescriptor(1, TitanInteger_tag_);
public static final TTCN_RAWdescriptor TitanInteger_raw_ = new TTCN_RAWdescriptor(8, raw_sign_t.SG_NO, raw_order_t.ORDER_LSB, raw_order_t.ORDER_LSB, raw_order_t.ORDER_LSB, raw_order_t.ORDER_LSB, ext_bit_t.EXT_BIT_NO, raw_order_t.ORDER_LSB, raw_order_t.ORDER_LSB, top_bit_order_t.TOP_BIT_INHERITED, 0, 0, 0, 8, 0, null, -1, CharCoding.UNKNOWN, null, false);
public static final TTCN_JSONdescriptor TitanInteger_json_ = new TTCN_JSONdescriptor(false, null, false, null, false, false, false, 0, null, false, json_string_escaping.ESCAPE_AS_SHORT);
public static final TTCN_Typedescriptor TitanInteger_descr_ = new TTCN_Typedescriptor("INTEGER", TitanInteger_Ber_, TitanInteger_raw_, TitanInteger_json_, null);
public static final TTCN_Typedescriptor TitanInteger_descr_ = new TTCN_Typedescriptor("INTEGER", TitanInteger_ber_, TitanInteger_raw_, TitanInteger_json_, null);
private boolean boundFlag;
......@@ -1273,6 +1276,20 @@ public class TitanInteger extends Base_Type {
}
break;
}
case CT_BER: {
final TTCN_EncDec_ErrorContext errorContext = new TTCN_EncDec_ErrorContext("While BER-encoding type '%s': ", p_td.name);
try {
if (p_td.ber == null) {
TTCN_EncDec_ErrorContext.error_internal("No BER descriptor available for type '%s'.", p_td.name);
}
final ASN_BER_TLV tlv = BER_encode_TLV(p_td, flavour);
tlv.put_to_buf(p_buf);
} finally {
errorContext.leave_context();
}
break;
}
default:
throw new TtcnError(MessageFormat.format("Unknown coding method requested to encode type `{0}''", p_td.name));
}
......@@ -1321,6 +1338,27 @@ public class TitanInteger extends Base_Type {
}
break;
}
case CT_BER: {
final TTCN_EncDec_ErrorContext errorContext = new TTCN_EncDec_ErrorContext(
"While BER-decoding type '%s': ", p_td.name);
try {
if (p_td.ber == null) {
TTCN_EncDec_ErrorContext.error_internal("No BER descriptor available for type '%s'.", p_td.name);
}
//int L_form = flavour;
ASN_BER_TLV tlv = new ASN_BER_TLV();
BER_decode_str2TLV(p_buf, tlv, flavour);
BER_decode_TLV(p_td, tlv, flavour);
if(tlv.isComplete) p_buf.increase_pos(tlv.getTlen() + tlv.getLlen() + tlv.getVlen());
} finally {
errorContext.leave_context();
}
break;
}
default:
throw new TtcnError(MessageFormat.format("Unknown coding method requested to decode type `{0}''", p_td.name));
}
......@@ -2305,4 +2343,65 @@ public class TitanInteger extends Base_Type {
}
return new Module_Param_Integer(this);
}
public ASN_BER_TLV BER_encode_chk_bound(boolean isBound) {
if (!isBound) {
//error fix me
ASN_BER_TLV newTlv = new ASN_BER_TLV(0, null);
return newTlv;
}
else return null;
}
public ASN_BER_TLV BER_encode_TLV (final TTCN_Typedescriptor p_td, int coding) {
ASN_BER_TLV newTlv = BER_encode_chk_bound(is_bound());
if (newTlv == null) {
if (nativeFlag) {
newTlv = BER_encode_TLV_Integer(p_td, nativeFlag, nativeInt, null);
} else {
newTlv = BER_encode_TLV_Integer(p_td, nativeFlag, 0, openSSL);
}
}
newTlv = newTlv.ASN_BER_V2TLV(p_td, coding);
return newTlv;
}
public boolean BER_decode_TLV (TTCN_Typedescriptor p_td, ASN_BER_TLV p_tlv, int L_form) {
boundFlag = false;
ASN_BER_TLV strippedTlv = new ASN_BER_TLV();
strippedTlv = BER_decode_strip_tags(p_td.ber, p_tlv, L_form, strippedTlv);
TitanInteger tmp = new TitanInteger();
Pair <Boolean, TitanInteger> p = BER_decode_TLV_Integer(strippedTlv, L_form, tmp);
boolean returnVal = p.getKey();
tmp = p.getValue();
if (tmp.is_native()) {
nativeFlag = true;
if(strippedTlv.getVstr()[0] >= 0 && tmp.nativeInt < 0) {
nativeInt = -tmp.nativeInt;
} else {
nativeInt = tmp.nativeInt;
}
} else {
nativeFlag = false;
if(strippedTlv.getVstr()[0] < 0 && tmp.openSSL.compareTo(BigInteger.ZERO) < 0) {
openSSL = tmp.openSSL.negate();
}
openSSL = tmp.openSSL;
}
if (returnVal) {
boundFlag = true;
}
return returnVal;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment