g_signal_connect on proxy handler results in callback GVariant * data uninitialized - glib

I'm pretty much following the example on https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GDBusProxy.html in order to set up Connman signal callbacks on dbus, however in my callback function:
g_signal_connect(
this->manager_proxy,
"property-changed",
G_CALLBACK(on_manager_properties_changed),
this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
this->manager_proxy,
"technology-added",
G_CALLBACK(on_manager_tech_added),
this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
this->manager_proxy,
"technology-removed",
G_CALLBACK(on_manager_tech_removed),
this); //Pass in pointer to self so static function can operate on object
void
CM_InterfaceController::on_manager_properties_changed (
GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties,
gpointer user_data)
{
if(!user_data){CM_ERR("NO THIS * on_manager_properties_changed");return;}
CM_InterfaceController * ths = static_cast<CM_InterfaceController *>(user_data);
std::cout<<"on_manager_properties_changed"<<std::endl;
if(changed_properties){
std::cout<<"children: "<<g_variant_n_children(changed_properties)<<std::endl;
}
}
The number of children I am told the GVariant * object contains is completely wrong. For instance, my feedback:
Calling Extraction
Service List Size: 1
Identified Ethernet Link:
Path: /net/connman/service/ethernet_0800277d326e_cable
Type: ethernet
Sate: ready
Favorite: 0
Auto Connect: 0
Name: Wired
Net Mode: manual
Iface: eth0
Mac: 08:00:27:7D:32:6E
IP Address: 10.0.2.15
Net Mask: 255.255.255.0
on_manager_properties_changed
children: 139764141513856
on_manager_properties_changed
children: 145
on_manager_properties_changed
children: 139764141513856
on_manager_properties_changed
children: 145
Both of those values are way out of the ballpark, one more significantly than the other. Even more, if I try to parsed the values out of the GVariant object, I end up seg faulting even just by trying to call g_variant_get_type_string. Why on earth is my callback returning with a garbage data pointer? Seems like if it has nothing it should at least return a null pointer.
edit: Source Code https://drive.google.com/file/d/1E0Kg9JKW54gghUHbVyBJ0ysBIdqBlpVA/view?usp=sharing
And some of the dbus-monitor --system output:
signal time=1549641357.679460 sender=:1.3 -> destination=(null destination) serial=488 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "State"
variant string "ready"
signal time=1549641357.680844 sender=:1.3 -> destination=(null destination) serial=489 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Nameservers"
variant array [
string "10.0.2.3"
]
signal time=1549641357.681186 sender=:1.3 -> destination=(null destination) serial=490 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Domains"
variant array [
]
signal time=1549641357.681601 sender=:1.3 -> destination=(null destination) serial=491 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Proxy"
variant array [
dict entry(
string "Method"
variant string "direct"
)
]
signal time=1549641357.681780 sender=:1.3 -> destination=(null destination) serial=492 path=/net/connman/technology/ethernet; interface=net.connman.Technology; member=PropertyChanged
string "Connected"
variant boolean true
signal time=1549641357.682210 sender=:1.3 -> destination=(null destination) serial=493 path=/; interface=net.connman.Manager; member=PropertyChanged
string "State"
variant string "ready"
signal time=1549641357.696004 sender=:1.3 -> destination=(null destination) serial=494 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
]
signal time=1549641357.696227 sender=:1.3 -> destination=(null destination) serial=495 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
dict entry(
string "Address"
variant string "10.0.2.15"
)
dict entry(
string "Netmask"
variant string "255.255.255.0"
)
]
signal time=1549641357.696454 sender=:1.3 -> destination=(null destination) serial=496 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
dict entry(
string "Address"
variant string "10.0.2.15"
)
dict entry(
string "Netmask"
variant string "255.255.255.0"
)
dict entry(
string "Gateway"
variant string "10.0.2.2"
)
]

FIGURED IT OUT!
In my XML file the signal I am watching for is:
<signal name="PropertyChanged">
<arg name="name" type="s" />
<arg name="value" type="v" />
</signal>
And as much as I am trying to figure out why the example callback function on freedesktop.org is in reverse I had to modify the following:
static void on_manager_properties_changed (
GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties,
gpointer user_data);
to:
static void on_manager_properties_changed (
GDBusProxy *proxy,
const gchar* const *invalidated_properties, //(name)
GVariant *changed_properties, //(value)
gpointer user_data);
So that the type='s' came before the type='v' in the callback function. After that, everything was good. I think maybe whatever signal freedesktop's example was watching, might have been a different element of information than what I was going for.

Related

Explict generic type in function by default replace this type to dynamic inside

Why explict generic type in function by default replace this type to dynamic inside?
example:
class Boo {
void displayType<int>() {
print('type int to string: $int');
print('type string to string: $String');
}
}
main() {
final boo = Boo();
boo.displayType();
}
output:
type int to string: dynamic
type string to string: String
its bug?
name of generic can be existing type. So if tell any type in function, inside int can be any another type
main() {
final boo = Boo();
boo.displayType<Boo>();
}
type int to string: Boo
type string to string: String
Here <int> is not an int data type but a name of generic datatype to be passed into function.
void displayType<int>() {
print('type int to string: $int');
print('type string to string: $String');
}
Compliler builds priorities from global to local. That means - it will prioritize local variables, arguments, generic types more than global ones. For example:
int number = 2;
void someFunc(){
//local variables are in higher priorities inside their closures
int number = 3;
//will print 3
print(number);
}
You definded generic type as <int> - compiler takes it as a priority in assgning and usage operations above the actual data type named int. Knowing this - do not be confused and make generic types consisting of 1 letter as usually it is done in many documentations.
void displayType<T>() {
//now it prints int
print('type int to string: $int');
//will print dynamic
print('type generic to string: $T');
print('type string to string: $String');
}
main() {
final boo = Boo();
boo.displayType();
}
You function declaration
void displayType<int>() {
print('type int to string: $int');
print('type string to string: $String');
}
introduces a generic function with a type parameter named int.
It's exactly the same as
void displayType<T>() {
print('type int to string: $T');
print('type string to string: $String');
}
except that the type parameter is named int, which also shadows the declaration of int normally imported from dart:core.
When you then call that method without a type argument, as
boo.displayType();
the type argument T/int (name doesn't matter) is inferred by using the bound of the type parameter (because there are no method arguments to infer a type from either). It has no bound given, so it defaults to dynamic.
It's not at all clear what you are trying to do.
If you wanted a type parameter bounded by int, you can write
void displayType<T extends int>() {
print('type T to string: $T');
print('type int to string: $int');
print('type string to string: $String');
}
If you are trying to override a superclass method which is also generic, to not be generic, you can't do that. The override must have the same type parameters with the same bounds as the superclass, otherwise the override is invalid.

How can I use a map as a type in F#?

I have the following:
Map [
"A", new Dictionary<int64, int64 * float>()
"B", new Dictionary<int64, int64 * float>()
]
and I would like a dictionary of those, something like:
let a =
new Dictionary<
string,
Map [
"A", new Dictionary<int64, int64 * float>()
"B", new Dictionary<int64, int64 * float>()
]>()
How to I get the type for the map to create the dictionary?
It is not entirely clear whether your question is how to write the type of the dictionary you want or whether you are asking how to construct a value of this type. Map is a generic type Map<'K, 'V>, much like the type of the Dictionary, so to write the type you'd use:
Dictionary<string, Map<string, Dictionary<int64, int64 * float>>>
To create a value, you can write the full type, or you can use the fact that F# can often infer the type arguments for you and so you can replace them with _. For example:
let map =
Map [
"A", new Dictionary<int64, int64 * float>()
"B", new Dictionary<int64, int64 * float>()
]
let a = new Dictionary<_, _>(dict ["first", map])
I would also add that dictionary of maps of dictionaries is a pretty incomprehensible type. It would probably be a good idea to extract some of those into simple named classes that convey some idea about the meaning of the type.

Dart: How to json decode '0' as double

I have a service that is sending me a list of values and after parsing with the 'dart:convert json.decode' I get a List < dynamic > json as such:
(values) [ 0.23, 0.2, 0, 0.43 ]
When I try to parse the values to 'double', I get a parsing error
double value = values[2] // error
Because if we check the .runtimeType of each element we can see that we have the following
[double, double, int, double]
So, how can I avoid '0' being interpreted as int?
I would like to avoid using a function like this:
double jsonToDouble(dynamic value) {
if(value.runtimeType == int) {
return (value as int).toDouble();
}
return value;
}
You can add some special logic to the JSON decoding by constructing your own codec with a reviver. This callback will be invoked for every property in a map or item in a List.
final myJsonCodec = new JsonCodec.withReviver((dynamic key, dynamic value) {
if (value is int) return value.toDouble();
return value;
});
However, you will always get a List<dynamic> from dart:covert, whether or not all of your number types are doubles or ints. Depending on what version of dart you are on you may be able to use List.cast to convert to a List<double>.
List<double> values = oldValues.cast<double>();
If that isn't available, you can create a new List<double> and add your values to it so that the runtime type is correctly set.
Doubles have a toDouble() method. So, you can use that in both cases (double and int).
double jsonToDouble(dynamic value) {
return value.toDouble();
}
This works only if the value is a double or an int, though. If the value is a string, an exception occurs.

How to pass multiple data objects to HTML templates in Golang

I am returing all rows of a table as json to the variable pdata and unmarshaling it into an interface object.
I have an instance of the user struct which I would like to pass along with the unmarshalled json data to the render function and access it using field arguments {{.fieldname}} in the html template.
if uuid != "" {
pdata, err := getProduct()
if err != nil {
fmt.Println(err)
}
type Prdata struct {
Puid string `json:"puid"`
Pname string `json:"pname"`
Quantity string `json:"quantity"`
Price string `json:"price"`
Image string `json:"image"`
}
// Obj:= make(map[Prdata]string)
var Pr Prdata
err = json.Unmarshal(pdata , &Pr)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(pdata))
fmt.Println(Pr)
fmt.Println(u)
render(w, "internal", Pr)
}
fmt.Println(string(pdata)) gives this output
[{"image":"1Appleiphone7.jpeg","pname":"iphone7","price":"70000","puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2","quantity":"100"}]
I have only been successful to unmarshal the data into an interface{} object. Trying to make maps with keys of the type interface{} and values of type string but it throws the error:
"json: cannot unmarshal array into Go value of type map[interface {}]string"
The render function takes an argument of the type interface{}
func render(w http.ResponseWriter, name string, data interface{})
fmt.Println(Pr) gives this output:
[map[quantity:100 image:1Appleiphone7.jpeg pname:iphone7 price:70000 puid:d6742e4e-2ad6-43c5-97f4-e8a7b00684e2]]
u is an instance of struct User
var u = &User{}
type User struct {
Uuid string
Username string
Password string
Fname string
Email string
}
I can see the output on the html page using the pipeline {{.}}. However I am not able to access any data using the fieldname.
There must be a way of doing this. But I am not sure how?
When I pass of a json of the type below, I am able to pass it to the struct type and reference it by the key values using pipelines in my template.
str := `{
"image": "1Appleiphone7.jpeg",
"pname": "iphone7",
"price": "70000",
"puid": "d6742e4e-2ad6-43c5-97f4-e8a7b00684e2",
"quantity": "100"
}`
unmarshal function
err = json.Unmarshal([]byte(str), &Pr)
The difference in the json data of the DB record pdata and the one above str is in the use of backticks "`". It seems that though the json data shows key value pairs, it is actually a json array and not a json object. Is there a way to get around this?
You don't need a map[interface{}]string to unmarshal the json obj. Your json is equivalent to slice of maps:
[
{
"image":"1Appleiphone7.jpeg",
"pname":"iphone7",
"price":"70000",
"puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2",
"quantity":"100"
}
]
The object to unmarshal should be a slice of maps with string keys and values:
var Pr []map[string]string
Playground
BTW, I believe misunderstanding is hidden there:
The render function takes an argument of the type interface{}
I means not that you must pass a variable of interface{} type there but it means you CAN pass a variable of any type to render function.
I am posting a working example of unmarshalling json as bytes into a struct type which then can be referenced using the {{.}} in the template.
package main
import (
"encoding/json"
"fmt"
)
type Usrdata struct {
Uuid string
Fname string
}
type Prdata struct {
Puid string `json:"puid"`
Pname string `json:"pname"`
Quantity string `json:"quantity"`
Price string `json:"price"`
Image string `json:"image"`
}
type Data struct {
U Usrdata
P []Prdata
}
func main() {
Ur := Usrdata{Uuid: "xyz", Fname: "Somename"}
Pr := make([]Prdata, 0)
var Dt Data
Dt.U = Ur
pdata := `[{"image":"1Appleiphone7.jpeg","pname":"iphone7","price":"70000","puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2","quantity":"100"}]`
err := json.Unmarshal([]byte(pdata), &Pr)
if err != nil {
fmt.Println(err)
}
Dt.P = Pr
fmt.Println(Pr[0].Pname)
fmt.Println(Pr)
fmt.Println(Dt)
}

Swift: how add offset to memcpy(...)

How to add offset for array for memcpy(...) invocation?
I have array of String :
var source = ["a","b","c","d"]
var dest = [String](count:n, repeatedValue: "")
memcpy(&dest, source, UInt(2 * sizeof(String))
This copy ["a","b"] to dest. I'ts obvious.
How can i copy ["b", "c"] ?
Do not use memcpy or other low-level "C" operators on objects. That will not work for many reasons.
Use the slice operator:
var source = ["a","b","c","d"]
var dest = Array(source[1...2])
println("dest: \(dest)")
output:
dest: [b, c]
Unicode is handled correctly:
var source = ["🇪🇸", "😂", "a","b","c","d"]
var dest = Array(source[1...2])
println("dest: \(dest)")
output:
dest: [😂, a]
I'm still new to Swift, and use of methods with "Unsafe" in the name still worries me, but I'm fairly sure this is a usable technique for calling memcpy() and specifying an offset for the destination and/or source address. But this only works for byte arrays, i.e., [UInt8]. Definitely not for strings, as explained by #zaph.
public class SystemMisc {
/// Wrapper for the memcpy() method that allows specification of an offset for the destination
/// and/or the source addresses.
///
/// This version for when destination is a normal Swift byte array.
///
/// - Parameters:
/// - destPointer: Address for destination byte array, typically Swift [UInt8].
/// - destOffset: Offset to be added to the destination address, may be zero.
/// - sourcePointer: Address for source byte array, typically Swift [UInt8].
/// - sourceOffset: Offset to be added to the source address, may be zero.
/// - byteLength: Number of bytes to be copied.
public static func memoryCopy(_ destPointer : UnsafeRawPointer, _ destOffset : Int,
_ sourcePointer : UnsafeRawPointer, _ sourceOffset : Int,
_ byteLength : Int) {
memoryCopy(UnsafeMutableRawPointer(mutating: destPointer), destOffset,
sourcePointer, sourceOffset, byteLength)
}
/// Wrapper for the memcpy() method that allows specification of an offset for the destination
/// and/or the source addresses.
///
/// This version for when destination address is already available as an UnsafeMutableRawPointer,
/// for example if caller has used UnsafeMutableRawPointer() to create it or is working with
/// unmanaged memory. The destPointer argument may also be a converted pointer, as done by the
/// above wrapper method.
///
/// - Parameters:
/// - destPointer: Address for destination byte array, see above notes.
/// - destOffset: Offset to be added to the destination address, may be zero.
/// - sourcePointer: Address for source byte array, typically Swift [UInt8].
/// - sourceOffset: Offset to be added to the source address, may be zero.
/// - byteLength: Number of bytes to be copied.
public static func memoryCopy(_ destPointer : UnsafeMutableRawPointer, _ destOffset : Int,
_ sourcePointer : UnsafeRawPointer, _ sourceOffset : Int,
_ byteLength : Int) {
memcpy(destPointer.advanced(by: destOffset),
sourcePointer.advanced(by: sourceOffset),
byteLength)
}
}
And here's some test code:
// Test the memoryCopy() method, using extra UnsafeMutableRawPointer conversion
let destArray1 : [UInt8] = [ 0, 1, 2, 3 ] // Note - doesn't need to be var
let sourceArray1 : [UInt8] = [ 42, 43, 44, 45 ]
SystemMisc.memoryCopy(destArray1, 1, sourceArray1, 1, 2)
assert(destArray1[0] == 0 && destArray1[1] == 43 && destArray1[2] == 44 && destArray1[3] == 3)
// Test the memoryCopy() method, providing UnsafeMutableRawPointer for destination
var destArray2 : [UInt8] = [ 0, 1, 2, 3 ]
let sourceArray2 : [UInt8] = [ 42, 43, 44, 45 ]
let destArray2Pointer = UnsafeMutableRawPointer(&destArray2)
SystemMisc.memoryCopy(destArray2Pointer, 1, sourceArray2, 1, 2)
assert(destArray2[0] == 0 && destArray2[1] == 43 && destArray2[2] == 44 && destArray2[3] == 3)
First of all, there's something none of the writers seem to have understood: an array of object (here String instances) do not store the content but a reference to this object. Therefore UTF-8, UTF-16, whatever has nothing to do with it. What the backing array actually contains is pointers (ie addresses == unsigned integers). Aside from that, unless an array in swift is an actual array in memory, you shouldn't use memcpy on it, even more so if it is backed by an NSArray!
Nonetheless, to answer the original question that seems to be working perfectly and makes me think that in this case the Swift Array is a contiguous zone of memory here is what you should do:
source and dest are pointers to contiguous memory zones: the first object being at the base address, the second #+sizeof(type), the nth element at #+(n-1)*sizeof(type).
All you have to do is specify the write offset for dest, in your particular case 0, and the offset in source, in your case 1.

Resources