How to get QOpcUaNode type attribute for writing in a client - qt

How do I read the QOpcUaNode data type attribute correctly?
I would like to do this but am finding this does not work against our server.
opcUaNode->writeValueAttribute(variant);
I have found this to work but some of my variables are UInt16 and others are UInt32 and I'd like to get the node variable type from the node instance but am not sure how.
opcUaNode->writeValueAttribute(variant, QOpcUa::Types::UInt16);
I have found this is not the way to get the node data type.
QVariant dataType = opcUaNode->attribute(QOpcUa::NodeAttribute::DataType);
I believe the QOpcUaNode object should know what data type it is so I should not need to track it separately.
Our runtime is Qt 5.15.2 / 5.15.3

This is a workaround IMO but usable for now. Would love to hear of a cleaner approach.
// use attribute value type to resolve the datatype
QVariant::Type aValueType = opcUaNode->attribute(QOpcUa::NodeAttribute::Value).type();
QOpcUa::Types dataType;
switch (aValueType)
{
case QVariant::ULongLong:
dataType = QOpcUa::Types::UInt64;
break;
case QVariant::UInt:
dataType = QOpcUa::Types::UInt32;
break;
default:
// until support for QVariant::UShort is available
dataType = QOpcUa::Types::UInt16;
break;
}
QVariant valueVariant(value);
opcUaNode->writeValueAttribute(valueVariant, dataType);
Derived from:
Reading Datatype from Node Attribute

Related

How to handle the type Maybe a while de- or encoding from/to Json

I wonder what is the best/prefered way to de-/encode types that contain a field of the type Maybe a
Suppose we have the type
type alias SomeType =
{ someInt : Int
, someMaybe : Maybe Float
, someOtherInt : Int
}
The most obvious solution is to not include the field in the Json output at all when the value is Nothing. When decoding if the field is not present, set the field to Nothing.

How to switch on reflect.Type?

I have managed to do this, but it does not look efficient:
var t reflect.Type
switch t {
case reflect.TypeOf(([]uint8)(nil)):
// handle []uint8 array type
}
First question, are you sure you want to switch on reflect.Type and not use a type switch? Example:
switch x := y.(type) {
case []uint8:
// x is now a []uint8
}
Assuming that will not work for your situation, my recommendation is to make those package variables. Example:
var uint8SliceType = reflect.TypeOf(([]uint8)(nil))
func Foo() {
var t reflect.Type
switch t {
case uint8SliceType:
// handle []uint8 array type
}
}
you may not need reflect if you are just trying to detect type.
switch t := myVar.(type){
case []uint8:
// t is []uint8
case *Foo:
// t is *Foo
default:
panic("unknown type")
}
What are you actually trying to accomplish?
The answer to the initial question How to switch on reflect.Type? is: You can’t. However, you can do it with reflect.Value.
Given a variable v interface{} you can call reflect.TypeOf(v) and reflect.ValueOf(v), which return a reflect.Type or reflect.Value, resp.
If the type of v is not interface{} then these function calls will convert it to interface{}.
reflect.Type contains various run-time information about the type, but it does not contain anything usable to retrieve the type of v itself as needed in a type switch.
Hovewer, reflect.Value provides it through its Interface() method, which returns the underlying value as interface{}. This you can use in a type switch or type assertion.
import "fmt"
import "reflect"
var v int
var rt reflect.Type = reflect.TypeOf(v)
fmt.Println(rt.String(), " has awesome properties: Its alignment is",
rt.Align(), ", it has", rt.Size(), "bytes, is it even comparable?",
rt.Comparable())
// … but reflect.Type won’t tell us what the real type is :(
// Let’s see if reflect.Value can help us.
var rv reflect.Value = reflect.ValueOf(v)
// Here we go:
vi := rv.Interface()
switch vi.(type) {
// Mission accomplished.
}
Perhaps it helps to clarify a few points which may cause confusion about dynamic typing in Go. At least I was confused by this for quite some time.
reflect vs. interface{}
In Go there are two systems of run-time generics:
In the language: interface{}, useful for type switches/assertions,
In the library: The reflect package, useful for inspection of run-time generic types and values of such.
These two systems are separated worlds, and things that are possible with one are impossible with the other. For example, Given an interface{}, it is in plain Go (with safe code) impossible to, say, if the value is an array or slice, regardless of its element type, then get the value of the i-th element. One needs to use reflect in order to do that. Conversely, with reflect it is impossible to make a type switch or assertion: convert it to interface{}, then you can do that.
There are only very few points of an interface between these systems. In one direction it is the TypeOf() and ValueOf() functions which accept interface{} and return a reflect struct. In the other direction it is Value.Interface().
It is a bit counter-intuitive that one needs a Value, not a Type, to do a type switch. At least this is somewhat consistent with the fact that one needs a value construct a Type by calling TypeOf().
reflect.Kind
Both reflect.Type and reflect.Value have a Kind() method. Some suggest using the value these methods return, of type reflect.Kind, to imitate a type switch.
While this may be useful in certain situations, it is not a replacement for a type switch. For example, using Kind one cannot distinguish between int64 and time.Duration because the latter is defined as
type Duration int64
Kind is useful to tell if a type is any kind of struct, array, slice etc., regardless of the types it is composed of. This is not possible to find out with a type switch.
(Side note. I had the same question and found no answer here helpful so I went to figure it out myself. The repeated counter-question “why are you doing this?”, followed by unrelated answers did not help me either. I have a good reason why I want to do it precisely this way.)
This might work.
switch t := reflect.TypeOf(a).String() {
case "[]uint8":
default:
}
As others have said, it's not clear what you are trying to achieve by switching on reflect.Type However, I came across this question when probably trying to do something similar, so I will give you my solution in case it answers your question.
As captncraig said, a simple type switch could be done on a interface{} variable without needing to use reflect.
func TypeSwitch(val interface{}) {
switch val.(type) {
case int:
fmt.Println("int with value", val)
case string:
fmt.Println("string with value ", val)
case []uint8:
fmt.Println("Slice of uint8 with value", val)
default:
fmt.Println("Unhandled", "with value", val)
}
}
However, going beyond this, the usefulness of reflection in the context of the original question could be in a function that accepts a struct with arbitrarily typed fields, and then uses a type switch to process the field according to its type. It is not necessary to switch directly on reflect.Type, as the type can be extracted by reflect and then a standard type switch will work. For example:
type test struct {
I int
S string
Us []uint8
}
func (t *test) SetIndexedField(index int, value interface{}) {
e := reflect.ValueOf(t).Elem()
p := e.Field(index)
v := p.Interface()
typeOfF := e.Field(index).Type()
switch v.(type) {
case int:
p.SetInt(int64(value.(int)))
case string:
p.SetString(value.(string))
case []uint8:
p.SetBytes(value.([]uint8))
default:
fmt.Println("Unsupported", typeOfF, v, value)
}
}
The following examples demonstrate the use of this function:
var t = test{10, "test string", []uint8 {1, 2, 3, 4}}
fmt.Println(t)
(&t).SetIndexedField(0, 5)
(&t).SetIndexedField(1, "new string")
(&t).SetIndexedField(2, []uint8 {8, 9})
fmt.Println(t)
(A few points on reflection in go:
It is necessary to export the struct fields for reflect to be able to use them, hence the capitalisation of the field names
In order to modify the field values, it would be necessary to use a pointer to the struct as in this example function
Elem() is used to "dereference" the pointer in reflect
)
Well, I did this by first transfer it to interface and then use the.(type)
ty := reflect.TypeOf(*c)
vl := reflect.ValueOf(*c)
for i:=0;i<ty.NumField();i++{
switch vl.Field(i).Interface().(type) {
case string:
fmt.Printf("Type: %s Value: %s \n",ty.Field(i).Name,vl.Field(i).String())
case int:
fmt.Printf("Type: %s Value: %d \n",ty.Field(i).Name,vl.Field(i).Int())
}
}

Reflect on Time type in go

I am trying to write a csv parser using the example provided here. It works great for all native types but I am having trouble with any structs that contain a timestamp of type time.Time. It exits with an error of "cannot convert this type".
This is the code.
//For each field in a given struct...
//Get a field
val := sv.Field(i)
// this is necessary because Kind can't tell
// distinguish between a primitive type
// and a type derived from it. We're looking
// for a Value interface defined on
// the pointer to this value
_, ok := val.Addr().Interface().(Value)
if ok {
val = val.Addr()
kind = value_k
} else {
switch Kind {
case reflect.Int, reflect.Int16, reflect.Int8,
reflect.Int32, reflect.Int64:
kind = int_k
case reflect.Uint, reflect.Uint16, reflect.Uint8,
reflect.Uint32, reflect.Uint64:
kind = uint_k
case reflect.Float32, reflect.Float64:
kind = float_k
case reflect.String:
kind = string_k
default:
// Kind is Struct here
kind = value_k
_, ok := val.Interface().(Value)
if !ok {
err = os.NewError("cannot convert this type ")
this = nil
return
}
}
}
What this code does is take an interface and a reader. It attempts to match the field headers in the reader (csv file) with field names in the interface. It also reflects on the interface (struct) and collects positional a type information for later setting the fields in the iterator. It is this step that is failing for non-native types.
I've tried a few methods to work around this but the only thing that seems to work is changing the timestamp to a string. I am undoubtedly missing something and would greatly appreciate some guidance.

Pointers in ABAP (like this in java)

Could anyone tell me how to define a pointer in ABAP OO?
In Java I have no problems with it, eg. this.name or this.SomeMethod().
Probably you are asking about so called self reference.
In ABAP it is available by using keyword me.
Example in Java: this.someMethod();
Example in ABAP: me->someMethod( ).
ABAP uses field symbols. They are defined like:
FIELD-SYMBOLS:
, " TYPE any.
TYPE file_table.
If you want to dereference it, you need to do it using another field symbol like this:
ASSIGN str_mfrnr TO <str1>.
This Stores the value of str_mfrnr into the field symbol. If this is formatted as a work area like 'wa_itab-my_column', will now contain this string.
Next, assign the location to another FS:
ASSIGN (<str1>) TO <tmfrnr>.
now points to wa_itab-my_column. If you perform:
<tmfrnr> = some_value.
the location pointed to by now contains the value in some_value.
ABAP pointers are more like C pointers, you have to know whether you are referenceing the value or the location.
Here's a small report I wrote a while ago to wrap my head around it. I think this is how it works:
REPORT zpointers.
* Similar to C:
***************
* int *pointer;
* int value = 1.
* pointer = &value
* int deref = *pointer
*this is the variable
DATA int TYPE i VALUE 10.
*this is the pointer, or the reference to a memory address
DATA pointer_i TYPE REF TO i.
*this is the dereferenced value, or the var that points to the
*value stored in a particular memory address
FIELD-SYMBOLS <int> TYPE i.
*the memory address of variable 'int' is now assigned to
*variable 'pointer_i'.
GET REFERENCE OF int INTO pointer_i.
*you can access the pointer by dereferencing it to a field symbol.
ASSIGN pointer_i->* TO <int>.

Xtext typesystem multidimensional arrays support

I am currently writing a parser for a Domain Specific Language using Xtext. In order to check the validity of data types usage in expressions I also use Xtext typesystem Framework.
I want to include multidimensional arrays in my grammar, and I have done it as far as Xtext is concerned, but I have problems with the type system.
My grammar about arrays in Xtext is the following:
ArrayType:
{ArrayType}(basetype=BaseType (dim+=Dimensions)+)
;
BaseType:
PrimaryType | StructuredType
;
Dimensions:
{Dimensions}'['size=Expr ']'
;
An example of the above grammar is int[5] name; (well name actually isn't included in this part of the grammar).
Now, let's go to what I have done in the type system in order to declare ArrayTypes, according to this tutorial (type recursion features section).
public EObject type(ArrayType a_t, TypeCalculationTrace trace)
{
ArrayType arraytype= (ArrayType) Utils.create(lang.getArrayType());
EObject basetype = typeof(a_t.getBasetype(),trace);
arraytype.setBasetype((BaseType) basetype);
return arraytype;
}
declareTypeRecursionFeature(lang.getArrayType(), lang.getArrayType_Basetype());
So if I declare a variable int[5] k; the type returned is ArrayType(int).
What I want to do and I cant, is to include in the type the number of the array's dimensions. For example,
int[3][2] k; //this should be of type ArrayType(int)[][]
int[5] g; //this should be of type ArrayType(int)[]
k[3][1]=3; //must be right
k[3]=g; //must be right
k=g; //must be wrong
I am really sorry for the long message, but I dont know how else I could better explain that to you. I will appreciate any ideas!
Thank you in advance!
Kate

Resources