Sync with 5.4.0
[deliverable/titan.core.git] / core / Hexstring.cc
index 27c7e4af461d39b885580b44beb565f65a0d5967..c61c13f4cd692b5f4b3bebc6ffc3d88c2ab7ee91 100644 (file)
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2000-2014 Ericsson Telecom AB
+// Copyright (c) 2000-2015 Ericsson Telecom AB
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
 // which accompanies this distribution, and is available at
@@ -582,25 +582,62 @@ void HEXSTRING::decode_text(Text_Buf& text_buf)
 
 void HEXSTRING::set_param(Module_Param& param) {
   param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, "hexstring value");
-  if (param.get_type()!=Module_Param::MP_Hexstring) param.type_error("hexstring value");
-  switch (param.get_operation_type()) {
-  case Module_Param::OT_ASSIGN: {
-    clean_up();
-    int n_nibbles = param.get_string_size();
-    init_struct(n_nibbles);
-    memcpy(val_ptr->nibbles_ptr, param.get_string_data(), (n_nibbles + 1) / 2);
-    clear_unused_nibble();
-  } break;
-  case Module_Param::OT_CONCAT:
-    if (is_bound()) {
-      *this = *this + HEXSTRING(param.get_string_size(), (unsigned char*)param.get_string_data());
-    } else {
-      *this = HEXSTRING(param.get_string_size(), (unsigned char*)param.get_string_data());
+  Module_Param_Ptr mp = &param;
+  if (param.get_type() == Module_Param::MP_Reference) {
+    mp = param.get_referenced_param();
+  }
+  switch (mp->get_type()) {
+  case Module_Param::MP_Hexstring:
+    switch (param.get_operation_type()) {
+    case Module_Param::OT_ASSIGN: {
+      clean_up();
+      int n_nibbles = mp->get_string_size();
+      init_struct(n_nibbles);
+      memcpy(val_ptr->nibbles_ptr, mp->get_string_data(), (n_nibbles + 1) / 2);
+      clear_unused_nibble();
+    } break;
+    case Module_Param::OT_CONCAT:
+      if (is_bound()) {
+        *this = *this + HEXSTRING(mp->get_string_size(), (unsigned char*)mp->get_string_data());
+      } else {
+        *this = HEXSTRING(mp->get_string_size(), (unsigned char*)mp->get_string_data());
+      }
+      break;
+    default:
+      TTCN_error("Internal error: HEXSTRING::set_param()");
+    }
+    break;
+  case Module_Param::MP_Expression:
+    if (mp->get_expr_type() == Module_Param::EXPR_CONCATENATE) {
+      HEXSTRING operand1, operand2;
+      operand1.set_param(*mp->get_operand1());
+      operand2.set_param(*mp->get_operand2());
+      if (param.get_operation_type() == Module_Param::OT_CONCAT) {
+        *this = *this + operand1 + operand2;
+      }
+      else {
+        *this = operand1 + operand2;
+      }
+    }
+    else {
+      param.expr_type_error("a hexstring");
     }
     break;
   default:
-    TTCN_error("Internal error: HEXSTRING::set_param()");
-  }  
+    param.type_error("hexstring value");
+    break;
+  }
+}
+
+Module_Param* HEXSTRING::get_param(Module_Param_Name& /* param_name */) const
+{
+  if (!is_bound()) {
+    return new Module_Param_Unbound();
+  }
+  int n_bytes = (val_ptr->n_nibbles + 1) / 2;
+  unsigned char* val_cpy = (unsigned char *)Malloc(n_bytes);
+  memcpy(val_cpy, val_ptr->nibbles_ptr, n_bytes);
+  return new Module_Param_Hexstring(val_ptr->n_nibbles, val_cpy);
 }
 
 void HEXSTRING::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
@@ -1507,7 +1544,8 @@ const HEXSTRING_ELEMENT HEXSTRING_template::operator[](const INTEGER& index_valu
   return (*this)[(int)index_value];
 }
 
-boolean HEXSTRING_template::match(const HEXSTRING& other_value) const
+boolean HEXSTRING_template::match(const HEXSTRING& other_value,
+                                  boolean /* legacy */) const
 {
   if (!other_value.is_bound()) return FALSE;
   if (!match_length(other_value.val_ptr->n_nibbles)) return FALSE;
@@ -1658,7 +1696,8 @@ void HEXSTRING_template::log() const
   log_ifpresent();
 }
 
-void HEXSTRING_template::log_match(const HEXSTRING& match_value) const
+void HEXSTRING_template::log_match(const HEXSTRING& match_value,
+                                   boolean /* legacy */) const
 {
   if (TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()
     && TTCN_Logger::get_logmatch_buffer_len() != 0) {
@@ -1676,7 +1715,11 @@ void HEXSTRING_template::log_match(const HEXSTRING& match_value) const
 
 void HEXSTRING_template::set_param(Module_Param& param) {
   param.basic_check(Module_Param::BC_TEMPLATE|Module_Param::BC_LIST, "hexstring template");
-  switch (param.get_type()) {
+  Module_Param_Ptr mp = &param;
+  if (param.get_type() == Module_Param::MP_Reference) {
+    mp = param.get_referenced_param();
+  }
+  switch (mp->get_type()) {
   case Module_Param::MP_Omit:
     *this = OMIT_VALUE;
     break;
@@ -1687,23 +1730,88 @@ void HEXSTRING_template::set_param(Module_Param& param) {
     *this = ANY_OR_OMIT;
     break;
   case Module_Param::MP_List_Template:
-  case Module_Param::MP_ComplementList_Template:
-    set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
-    for (size_t i=0; i<param.get_size(); i++) {
-      list_item(i).set_param(*param.get_elem(i));
+  case Module_Param::MP_ComplementList_Template: {
+    HEXSTRING_template temp;
+    temp.set_type(mp->get_type() == Module_Param::MP_List_Template ?
+      VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());
+    for (size_t i=0; i<mp->get_size(); i++) {
+      temp.list_item(i).set_param(*mp->get_elem(i));
     }
-    break;
+    *this = temp;
+    break; }
   case Module_Param::MP_Hexstring:
-    *this = HEXSTRING(param.get_string_size(), (unsigned char*)param.get_string_data());
+    *this = HEXSTRING(mp->get_string_size(), (unsigned char*)mp->get_string_data());
     break;
   case Module_Param::MP_Hexstring_Template:
-    *this = HEXSTRING_template(param.get_string_size(), (unsigned char*)param.get_string_data());
+    *this = HEXSTRING_template(mp->get_string_size(), (unsigned char*)mp->get_string_data());
+    break;
+  case Module_Param::MP_Expression:
+    if (mp->get_expr_type() == Module_Param::EXPR_CONCATENATE) {
+      HEXSTRING operand1, operand2;
+      operand1.set_param(*mp->get_operand1());
+      operand2.set_param(*mp->get_operand2());
+      *this = operand1 + operand2;
+    }
+    else {
+      param.expr_type_error("a bitstring");
+    }
     break;
   default:
     param.type_error("hexstring template");
   }
-  is_ifpresent = param.get_ifpresent();
-  set_length_range(param);
+  is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();
+  if (param.get_length_restriction() != NULL) {
+    set_length_range(param);
+  }
+  else {
+    set_length_range(*mp);
+  }
+}
+
+Module_Param* HEXSTRING_template::get_param(Module_Param_Name& param_name) const
+{
+  Module_Param* mp = NULL;
+  switch (template_selection) {
+  case UNINITIALIZED_TEMPLATE:
+    mp = new Module_Param_Unbound();
+    break;
+  case OMIT_VALUE:
+    mp = new Module_Param_Omit();
+    break;
+  case ANY_VALUE:
+    mp = new Module_Param_Any();
+    break;
+  case ANY_OR_OMIT:
+    mp = new Module_Param_AnyOrNone();
+    break;
+  case SPECIFIC_VALUE:
+    mp = single_value.get_param(param_name);
+    break;
+  case VALUE_LIST:
+  case COMPLEMENTED_LIST: {
+    if (template_selection == VALUE_LIST) {
+      mp = new Module_Param_List_Template();
+    }
+    else {
+      mp = new Module_Param_ComplementList_Template();
+    }
+    for (size_t i = 0; i < value_list.n_values; ++i) {
+      mp->add_elem(value_list.list_value[i].get_param(param_name));
+    }
+    break; }
+  case STRING_PATTERN: {
+    unsigned char* val_cpy = (unsigned char*)Malloc(pattern_value->n_elements);
+    memcpy(val_cpy, pattern_value->elements_ptr, pattern_value->n_elements);
+    mp = new Module_Param_Hexstring_Template(pattern_value->n_elements, val_cpy);
+    break; }
+  default:
+    break;
+  }
+  if (is_ifpresent) {
+    mp->set_ifpresent();
+  }
+  mp->set_length_restriction(get_length_range());
+  return mp;
 }
 
 void HEXSTRING_template::encode_text(Text_Buf& text_buf) const
@@ -1767,13 +1875,13 @@ void HEXSTRING_template::decode_text(Text_Buf& text_buf)
   }
 }
 
-boolean HEXSTRING_template::is_present() const
+boolean HEXSTRING_template::is_present(boolean legacy /* = FALSE */) const
 {
   if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
-  return !match_omit();
+  return !match_omit(legacy);
 }
 
-boolean HEXSTRING_template::match_omit() const
+boolean HEXSTRING_template::match_omit(boolean legacy /* = FALSE */) const
 {
   if (is_ifpresent) return TRUE;
   switch (template_selection) {
@@ -1782,10 +1890,14 @@ boolean HEXSTRING_template::match_omit() const
     return TRUE;
   case VALUE_LIST:
   case COMPLEMENTED_LIST:
-    for (unsigned int i = 0; i < value_list.n_values; i++)
-      if (value_list.list_value[i].match_omit()) return template_selection
-        == VALUE_LIST;
-    return template_selection == COMPLEMENTED_LIST;
+    if (legacy) {
+      // legacy behavior: 'omit' can appear in the value/complement list
+      for (unsigned int i = 0; i < value_list.n_values; i++)
+        if (value_list.list_value[i].match_omit()) return template_selection
+          == VALUE_LIST;
+      return template_selection == COMPLEMENTED_LIST;
+    }
+    // else fall through
   default:
     return FALSE;
   }
@@ -1793,7 +1905,8 @@ boolean HEXSTRING_template::match_omit() const
 }
 
 #ifndef TITAN_RUNTIME_2
-void HEXSTRING_template::check_restriction(template_res t_res, const char* t_name) const
+void HEXSTRING_template::check_restriction(template_res t_res, const char* t_name,
+                                           boolean legacy /* = FALSE */) const
 {
   if (template_selection==UNINITIALIZED_TEMPLATE) return;
   switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
@@ -1805,7 +1918,7 @@ void HEXSTRING_template::check_restriction(template_res t_res, const char* t_nam
         template_selection==SPECIFIC_VALUE)) return;
     break;
   case TR_PRESENT:
-    if (!match_omit()) return;
+    if (!match_omit(legacy)) return;
     break;
   default:
     return;
This page took 0.04202 seconds and 5 git commands to generate.