Data bytes to sockaddr conversion in Swift 3.1 - swift3

I am converting Data bytes to sockaddr for getting sa_family_t
In ObjC, it is as below:
NSData * hostAddress;
- (sa_family_t)hostAddressFamily {
sa_family_t result;
result = AF_UNSPEC;
if ( (self.hostAddress != nil) && (self.hostAddress.length >= sizeof(struct sockaddr)) ) {
result = ((const struct sockaddr *) self.hostAddress.bytes)->sa_family;
}
return result;
}
In swift I am trying to convert it as below:
var hostAddress:Data?
private func hostAddressFamily() -> sa_family_t{
var result: sa_family_t = sa_family_t(AF_UNSPEC)
if (hostAddress != nil) && ((hostAddress?.count ?? 0) >= MemoryLayout<sockaddr>.size) {
// Generic parameter 'ContentType' could not be inferred
self.hostAddress!.withUnsafeBytes({ bytes in
bytes.withMemoryRebound(to: sockaddr.self, capacity: 1, {sockBytes in
result = sockBytes.pointee.sa_family
})
})
}
return result
}
Getting error : Generic parameter ‘ContentType’ could not be inferred

Look at the signature of Data.withUnsafeBytesType:
func withUnsafeBytes<ResultType, ContentType>(_ body: (Swift.UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType
This method is generic over ResultType and ContentType, and the ContentType is used in the argument of the closure body.
What compiler is trying to say is that it does not know what type bytes is of. Generally, to fix this type of errors, you'll want to annotate the type in the closure:
data.withUnsafeBytes { (_ bytes: UnsafePointer<...>) -> Void in ... }
Also, it's unlikely you'll need to bind the memory twice since NSData is untyped, and you already specifying a type to bind it to.
Putting it all together:
func hostAddressFamily() -> sa_family_t {
var result = sa_family_t(AF_UNSPEC)
guard
let hostAddress = hostAddress,
hostAddress.count >= MemoryLayout<sockaddr>.size
else {
return result
}
hostAddress.withUnsafeBytes { (_ bytes: UnsafePointer<sockaddr>) in
result = bytes.pointee.sa_family
}
return result
}

Related

Pass list of one of two structures to the function

New in Go, couldn't find any intuitive way of doing that.
I have such piece of code
tx = getTx()
for _, record := range tx.a {
// do a lot with record.Important
}
for _, record := range tx.b {
// do a lot with record.Important
}
for _, record := range tx.c {
// do a lot with record.Important
}
And the following structs:
type Record1 struct {
// fields of Record1
Important string
}
type Record2 struct {
// fields of Record1
Important string
}
type TX struct {
a []Record1
b []Record1
c []Record2
}
Now the logical is to extract every for logic into the function:
func helper(records) { // Here is the problem
// do a lot with record.Important
}
Problem:
records is a []Record1 or []Record2 type. But it looks like Union types doesn't exists in Golang. So I thought I could pass []string into the helper, but cannot even find an elegant way to get something equivalent to map(lambda r: r.Important, tx.a). There is no high order map function, no list comprehesion. I am not convinced to use raw for loop to solve that.
One approach to do the loop across multiple types is to use interfaces together with generics. Have each Record type implement a getter method for the important field. Then declare an interface that includes that getter method in its method set. Then you can make your helper generic by declaring the interface as its type parameter.
func (r Record1) GetImportant() string { return r.Important }
func (r Record2) GetImportant() string { return r.Important }
type ImportantGetter interface {
GetImporant() string
}
func helper[T ImportantGetter](s []T) {
for _, v := range s {
_ = v.GetImportant()
}
}
Unless I'm misunderstanding your question, it seems like you want to extract all the values in column X from a set of records and then pass those values in as a slice to some function - I'm basing my assumption on your wish that go had something like map().
If what you're after is type-agnosticism, you could certainly use an interface approach like that suggested by mkopriva, but you aren't going to get out of using a for loop - iteration over list types is core to idiomatic go. If you need a mapping function, you're going to have to write one that performs the mapping you want.
I'd note that you do not need generics to do what mkopriva suggests, you can just use an interface without muddying the waters with generics go playground:
package main
import "fmt"
type Record1 struct {
Important string
}
type Record2 struct {
Important string
}
func (r Record1) GetImportant() string { return r.Important }
func (r Record2) GetImportant() string { return r.Important }
type ImportantGetter interface {
GetImportant() string
}
func helper(s []ImportantGetter) {
for _, v := range s {
fmt.Println(v.GetImportant())
}
}
func main() {
records := []ImportantGetter{Record1{Important: "foo"}, Record2{Important: "bar"}}
helper(records)
}
Another approach to the type-agnosticism, and one that's a bit more (IMHO) idiomatic for "I expect all of these types to have a common property," is to use struct embedding and type assertions to build your own Map() function up go playground:
type CommonFields struct {
Important string
}
type Record1 struct {
CommonFields
FieldSpecificToRecord1 string
}
type Record2 struct {
CommonFields
FieldSpecificToRecord2 int
}
func main() {
r1 := Record1{
CommonFields{Important: "I'm r1!"},
"foo",
}
r2 := Record2{
CommonFields{Important: "I'm r2!"},
5,
}
records := []interface{}{r1, r2, "this is not a valid record type"}
fmt.Println(Map(records))
}
func Map(source []interface{}) []string {
destination := make([]string, len(source))
for i, sourceRecord := range source {
if rr, ok := sourceRecord.(Record1); ok {
destination[i] = rr.Important
} else if rr, ok := sourceRecord.(Record2); ok {
destination[i] = rr.Important
} else {
destination[i] = "undefined"
}
}
return destination
}
You'd likely want to make your implementation of Map() accept an argument specifying the field to extract to conform to what you have in other languages, or possibly even just pass in a helper function which does most of the type-specific value extraction.

Unit Testing: Verify that a method was called, without testing frameworks like Mockito or MockK

Not using testing frameworks like MockK or Mockito seems to be becoming more and more popular. I decided to try this approach. So far so good, returning fake data is simple. But how do I verify that a function (that does not return data) has been called?
Imagine having a calss like this:
class TestToaster: Toaster {
override fun showSuccessMessage(message: String) {
throw UnsupportedOperationException()
}
override fun showSuccessMessage(message: Int) {
throw UnsupportedOperationException()
}
override fun showErrorMessage(message: String) {
throw UnsupportedOperationException()
}
override fun showErrorMessage(message: Int) {
throw UnsupportedOperationException()
}
}
With MockK I would do
verify { toaster.showSuccessMessage() }
I do not want to reinvent a wheel so decided to ask. Finding anything on Google seems to be very difficult.
Since this is a thing, I assume the point would be to totally remove mocking libraries and everything can be done without them.
The old school way to do it before any appearance of the mocking library is to manually create an implementation that is just for testing . The test implementation will store how an method is called to some internal state such that the testing codes can verify if a method is called with expected parameters by checking the related state.
For example , a very simple Toaster implementation for testing can be :
public class MockToaster implements Toaster {
public String showSuccesMessageStr ;
public Integer showSuccesMessageInt;
public String showErrorMessageStr;
public Integer showErrorMessageInt;
public void showSuccessMessage(String msg){
this.showSuccesMessageStr = msg;
}
public void showSuccessMessage(Integer msg){
this.showSuccesMessageInt = msg;
}
public void showErrorMessage(String msg){
this.showErrorMessageStr = msg;
}
public void showErrorMessage(Integer msg){
this.showErrorMessageInt = msg;
}
}
Then in your test codes , you configure the object that you want to test to use MockToaster. To verify if it does really call showSuccessMessage("foo") , you can then assert if its showSuccesMessageStr equal to foo at the end of the test.
A lot of people seem to be suggesting the very straight forward solution for this, which totally makes sense. I decided to go a bit fancy and achieve this syntax:
verify(toaster = toaster, times = 1).showErrorMessage(any<String>()).
I created simple Matchers:
inline fun <reified T> anyObject(): T {
return T::class.constructors.first().call()
}
inline fun <reified T> anyPrimitive(): T {
return when (T::class) {
Int::class -> Int.MIN_VALUE as T
Long::class -> Long.MIN_VALUE as T
Byte::class -> Byte.MIN_VALUE as T
Short::class -> Short.MIN_VALUE as T
Float::class -> Float.MIN_VALUE as T
Double::class -> Double.MIN_VALUE as T
Char::class -> Char.MIN_VALUE as T
String:: class -> "io.readian.readian.matchers.strings" as T
Boolean::class -> false as T
else -> {
throw IllegalArgumentException("Not a primitive type ${T::class}")
}
}
}
Added a map to store call count for each method to my TestToaster where the key is the name of the function and value is the count:
private var callCount: MutableMap<String, Int> = mutableMapOf()
Whenever a function gets called I increase current call count value for a method. I get current method name through reflection
val key = object {}.javaClass.enclosingMethod?.name + param::class.simpleName
addCall(key)
In oder to achieve the "fancy" syntax, I created inner subcalss for TestToaster and a verify function:
fun verify(toaster: Toaster , times: Int = 1): Toaster {
return TestToaster.InnerToaster(toaster, times)
}
That function sends current toaster instance to the inner subclass to create new instance and returns it. When I call a method of the subclass in my above syntax, the check happens. If the check passes, nothing happens and test is passed, if conditions not met - and exception is thrown.
To make it more general and extendable I created this interface:
interface TestCallVerifiable {
var callCount: MutableMap<String, Int>
val callParams: MutableMap<String, CallParam>
fun addCall(key: String, vararg param: Any) {
val currentCountValue = callCount.getOrDefault(key, 0)
callCount[key] = currentCountValue + 1
callParams[key] = CallParam(param.toMutableList())
}
abstract class InnerTestVerifiable(
private val outer: TestCallVerifiable,
private val times: Int = 1,
) {
protected val params: CallParam = CallParam(mutableListOf())
protected fun check(functionName: String) {
val actualTimes = getActualCallCount(functionName)
if (actualTimes != times) {
throw IllegalStateException(
"$functionName expected to be called $times, but actual was $actualTimes"
)
}
val callParams = outer.callParams.getOrDefault(functionName, CallParam(mutableListOf()))
val result = mutableListOf<Boolean>()
callParams.values.forEachIndexed { index, item ->
val actualParam = params.values[index]
if (item == params.values[index] || (item != actualParam && isAnyParams(actualParam))) {
result.add(true)
}
}
if (params.values.isNotEmpty() && !result.all { it } || result.isEmpty()) {
throw IllegalStateException(
"$functionName expected to be called with ${callParams.values}, but actual was with ${params.values}"
)
}
}
private fun isAnyParams(vararg param: Any): Boolean {
param.forEach {
if (it.isAnyPrimitive()) return true
}
return false
}
private fun getActualCallCount(functionName: String): Int {
return outer.callCount.getOrDefault(functionName, 0)
}
}
data class CallParam(val values: MutableList<Any> = mutableListOf())
}
Here is the complete class:
open class TestToaster : TestCallVerifiable, Toaster {
override var callCount: MutableMap<String, Int> = mutableMapOf()
override val callParams: MutableMap<String, TestCallVerifiable.CallParam> = mutableMapOf()
override fun showSuccessMessage(message: String) {
val key = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
addCall(key, message)
}
override fun showSuccessMessage(message: Int) {
val key = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
addCall(key, message)
}
override fun showErrorMessage(message: String) {
val key = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
addCall(key, message)
}
override fun showErrorMessage(message: Int) {
val key = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
addCall(key, message)
}
private class InnerToaster(
verifiable: TestCallVerifiable,
times: Int,
) : TestCallVerifiable.InnerTestVerifiable(
outer = verifiable,
times = times,
), Toaster {
override fun showSuccessMessage(message: String) {
params.values.add(message)
val functionName = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
check(functionName)
}
override fun showSuccessMessage(message: Int) {
params.values.add(message)
val functionName = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
check(functionName)
}
override fun showErrorMessage(message: String) {
params.values.add(message)
val functionName = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
check(functionName)
}
override fun showErrorMessage(message: Int) {
params.values.add(message)
val functionName = object {}.javaClass.enclosingMethod?.name + message::class.simpleName
check(functionName)
}
}
companion object {
fun verify(toaster: Toaster, times: Int = 1): Toaster {
return InnerToaster(toaster as TestCallVerifiable, times)
}
}
}
I have not tested this extensively and it will evolve with time, but so far it works well for me.
I also wrote an article about this on Medium: https://sermilion.medium.com/unit-testing-verify-that-a-method-was-called-without-testing-frameworks-like-mockito-or-mockk-433ef8e1aff4

How to recover the concrete type from Any

Code:
use std::fmt::Debug;
use std::any::Any;
fn any_to_u16(value: &dyn Any)
{
let v = value as u16;
}
fn main()
{
let x = true;
any_to_u16(&x);
}
Erorr :
error[E0606]: casting `&(dyn std::any::Any + 'static)` as `u16` is invalid
--> src/lib.rs:6:13
|
6 | let v = value as u16;
| ^^^^^^^^^^^^
|
= help: cast through a raw pointer first
Playground
How to fix?
You must use Any::downcast_ref:
use std::any::Any;
fn any_to_u16(value: &dyn Any)
{
if let Some(value) = value.downcast_ref::<bool>().map(|b| *b as u16) {
// value is a `bool`
assert_eq!(value, 1);
}
}
fn main()
{
let x = true;
any_to_u16(&x);
}

Panic because parameters must be struct and not interface, in web.Router?

In testing the following code:
package logHandler
import (
"ezsoft/apiserver_sdk/context"
"github.com/hsoshiant/web"
)
// Build simply builds a log handler router
//
// Parameters:
//
// - `mainRouter` : the main Router
//
// Returns:
//
// - a sub Router made specifically for logging
func Build(mainRouter *web.Router) *web.Router {
return mainRouter.Subrouter(context.Context{}, "/log").
Post("/", doLog)
}
I hit a panic. context.Context is defined thus:
//BaseContext contains all the base context to be helpful when using the utilities
type BaseContext struct {
Session session.Store
ResponseWriter *web.ResponseWriter
RequestReader *web.Request
}
//Context contains all values needed when using the utilities
type Context struct {
BaseContext
JSONBody map[string]interface{}
tokenHandler *apiToken.APITokenHandlerSt
OAuthInstance *oAuth2.OAuth2St
}
and with testability/flexibility in mind, the developers wrote the middleware functions to take context.ContextIntf, which context.Context implements, which is defined as follows:
//ContextIntf is the interface to use when using the context interface functions.
type ContextIntf interface {
SetUniversalHeaders(header map[string]string) map[string]string
GetInfo() *Context
GetOAuth() *oAuth2.OAuth2St
}
Here's one such middleware func:
//AuthenticationMiddleware Middleware which handles all of the authentication.
func AuthenticationMiddleware(mw AuthenticationMiddlewareIntf, context context.ContextIntf, w web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) {
//Check if the url should be public.
for _, url := range mw.GetInfo().nonAuthURLs {
if url.Method == r.Method && strings.Contains(r.URL.Path, url.DomainName) {
key := utilities.GetRemoteAdd(r) + ";" + r.URL.Path
if timeSince, ok := NonAuthSecurityMap[key]; ok {
var (
timeSinceTime, _ = time.Parse(time.UnixDate, timeSince)
timeSinceDuration = time.Since(timeSinceTime)
)
if timeSinceDuration < nonAuthTimeReset {
// will sleep for `nonAuthTimeReset` - `timeSinceDuration` > 0
time.Sleep(-(timeSinceDuration - nonAuthTimeReset))
}
}
NonAuthSecurityMap[key] = time.Now().Format(time.UnixDate)
next(w, r)
return
}
}
if errSt := CheckForAuthorization(mw, context, r, w); errSt != nil {
responses.Write(w, responses.Unauthorized(*errSt))
return
}
defer context.GetInfo().Session.SessionRelease(w)
next(w, r)
}
I am unsure which middleware business functions that package web is checking, let alone what business packages they reside in, and the call stack trace returns no such clues.
The error I get is thus:
* You are adding a handler to a router with context type 'Context'
*
*
* Your handler function can have one of these signatures:
*
* // If you don't need context:
* func YourFunctionName(rw web.ResponseWriter, req *web.Request)
*
* // If you want your handler to accept a context:
* func (c *Context) YourFunctionName(rw web.ResponseWriter, req *web.Request) // or,
* func YourFunctionName(c *Context, rw web.ResponseWriter, req *web.Request)
*
* Unfortunately, your function has this signature: func(context.ContextIntf, web.ResponseWriter, *web.Request)
*
************************************************************************************************************************
Why is this requesting a Context struct, instead of the ContextIntf that it implements?!
The stack trace
Looks like this:
goroutine 20 [running]:
testing.tRunner.func1(0xc04213e1e0)
C:/Go/src/testing/testing.go:742 +0x2a4
panic(0x7633c0, 0xc0421320a0)
C:/Go/src/runtime/panic.go:502 +0x237
github.com/hsoshiant/web.validateHandler(0x778420, 0x80d8f0, 0x13, 0x8405c0, 0x7b7960)
D:/dev2017/GO/src/github.com/hsoshiant/web/router_setup.go:286 +0x242
github.com/hsoshiant/web.(*Router).addRoute(0xc042106680, 0x7eeb93, 0x4, 0x7ee4bd, 0x1, 0x778420, 0x80d8f0, 0xc042051f80)
D:/dev2017/GO/src/github.com/hsoshiant/web/router_setup.go:223 +0x94
github.com/hsoshiant/web.(*Router).Post(0xc042106680, 0x7ee4bd, 0x1, 0x778420, 0x80d8f0, 0xc042106680)
D:/dev2017/GO/src/github.com/hsoshiant/web/router_setup.go:193 +0x6f
ezsoft/apiserver_sdk/logger/logHandler.Build(0xc0421064e0, 0xc042051f40)
D:/dev2017/GO/src/ezsoft/apiserver_sdk/logger/logHandler/handler.go:20 +0xcf
ezsoft/apiserver_sdk/logger/logHandler.TestBuild.func1(0xc04213e1e0)
D:/dev2017/GO/src/ezsoft/apiserver_sdk/logger/logHandler/handler_test.go:16 +0x91
testing.tRunner(0xc04213e1e0, 0x80d8e0)
C:/Go/src/testing/testing.go:777 +0xd7
created by testing.(*T).Run
C:/Go/src/testing/testing.go:824 +0x2e7
UPDATE : It's hitting the private method doLog, which is defined thus:
func doLog(contextIntf context.ContextIntf, rw web.ResponseWriter, req *web.Request) {
var (
logType int = 0
code string = ""
message string = ""
context = contextIntf.GetInfo()
)
if val, OK := context.JSONBody["type"]; OK {
if val1, noErr := val.(float64); noErr {
logType = int(val1)
}
}
if logType == 0 {
responses.Write(rw, responses.FreeUnprocessableEntity("Type"))
return
}
if val, OK := context.JSONBody["code"]; OK {
if val1, noErr := val.(string); noErr {
code = val1
} else {
responses.Write(rw, responses.FreeUnprocessableEntity("Code"))
return
}
}
if val, OK := context.JSONBody["message"]; OK {
if val1, noErr := val.(string); noErr {
message = val1
}
}
if message == "" {
responses.Write(rw, responses.FreeUnprocessableEntity("message"))
return
}
if code > "" {
code = " (" + code + ") "
}
switch logType {
case 1:
logger.Instance.LogError(code + message)
case 2:
logger.Instance.LogWarning(code + message)
case 3:
logger.Instance.LogInfo(code + message)
default:
logger.Instance.LogWarning(code + message)
}
responses.Write(rw, responses.OK(0))
}
I still don't get why that argument needs to be a context.Context, or what I, the unit-tester, can do about it.

How do I get the X window class given a window ID with rust-xcb?

I'm trying to use rust-xcb to get a window's class given a window ID.
fn get_class(conn: &xcb::Connection, id: &i32) {
let window: xcb::xproto::Window = *id as u32;
let class_prop: xcb::xproto::Atom = 67; // XCB_ATOM_WM_CLASS from xproto.h
let cookie = xcb::xproto::get_property(&conn, false, window, class_prop, 0, 0, 2);
match cookie.get_reply() {
Ok(reply) => {
let x: &[std::os::raw::c_void] = reply.value();
println!("reply is {:?}", x[0]);
}
Err(err) => println!("err {:?}", err),
}
}
The documentation is kind of sparse and hasn't been incredibly helpful, though I did find this bit about the GetPropertyReply and of the xcb_get_property_reply_t it wraps.
I looked at this answer in JavaScript but I don't know what the ctypes equivalent in Rust is. I tried just casting the &[c_void] as a &str or String:
...
Ok(reply) => {
let len = reply.value_len() as usize;
let buf = reply.value() as &str;
println!("{}", buf.slice_unchecked(0, len)); // this seems redundant
}
...
but it returns
error: non-scalar cast: `&[_]` as `&str`
I tried casting the &[c_void] as a &[u8] and then collecting the Vec into a String, which sort of works:
...
Ok(reply) => {
let value : &[u8] = reply.value();
let buf : String = value.into_iter().map(|i| *i as char).collect();
println!("\t{:?}", buf);
}
...
but I'm now getting weird results. for example , when I use xprop on Chrome I see "google-chrome" but for me it is only showing "google-c", and "roxterm" is showing up as "roxterm\u{0}". I'm guessing "\u{0}" is something Unicode related but I'm not sure, and I don't know why stuff is being concatenated either. Maybe I have to check the reply again?
Here's my updated function:
fn get_class(conn: &Connection, id: &i32) -> String {
let window: xproto::Window = *id as u32;
let long_length: u32 = 8;
let mut long_offset: u32 = 0;
let mut buf = Vec::new();
loop {
let cookie = xproto::get_property(
&conn,
false,
window,
xproto::ATOM_WM_CLASS,
xproto::ATOM_STRING,
long_offset,
long_length,
);
match cookie.get_reply() {
Ok(reply) => {
let value: &[u8] = reply.value();
buf.extend_from_slice(value);
match reply.bytes_after() {
0 => break,
_ => {
let len = reply.value_len();
long_offset += len / 4;
}
}
}
Err(err) => {
println!("{:?}", err);
break;
}
}
}
let result = String::from_utf8(buf).unwrap();
let results: Vec<&str> = result.split('\0').collect();
results[0].to_string()
}
There were three main parts to this question:
I put xproto::get_property() in a loop so I could check reply.bytes_after() and accordingly adjust long_offset. I think with an appropriate long_length there will usually only be one read, but just being safe.
As #peter-hall said, converting &[u8] -> String should be done using String::from_utf8, which needs a Vec; so I let mut buf = Vec::new() and buf.extend_from_slice over the loop before creating the result string with String::from_utf8(buf).unwrap()
According to this random page WM_CLASS is actually two consecutive null-terminated strings, so I split the result by \0 and grab the first value.
I might've just been looking in the wrong place, but xcb has absolutely terrible documentation..