Is there a function in gtkmm that reads from FileInputStream in the way that can then be used to set the TextArea - unicode

I'm trying to read text from file and put it in the TextView. FileInputStream has read_bytes, there is set_text in TextBuffer that can take ustring, but there seem to be no way to go from one to another.
In the InputStream's child classes i found DataInputStream which does have read_line_utf8 giving one an std::string (better than nothing), but even DataInputStream is on the separate class hierarchy branch from FileInputStream.
Of course, theoretically it is possible to just cycle through the array of bytes returned by the read_bytes and turn them into characters, but somehow i just refuse to believe that there is no ready function that i'm overlooking.
Ultimately i'm looking for a function that would take Glib::RefPtr<Glib::Bytes> and return me a Glib::ustring

OK, after searching far and wide i have managed to confirm that there is no way to do so within the confines of gtkmm library. This does seem pretty strange to me, but there it is.
So here is how to read the file via the normal tools, then convert what you've read, and display it in the TextArea:
I assume here that you've already opened the dialog and connected all that needs to be connected for it. If you have a Controller class you will end up with something along the lines of:
fh = dialog->get_file();
fh->read_async( sigc::mem_fun( *this, &Controller::on_file_read_complete ));
Make sure that you have Glib::RefPtr< Gio::File > fh; as the private data member and not as a local variable. You will then need a function on_file_read_complete
void Controller::on_file_read_complete(Glib::RefPtr<Gio::AsyncResult>& res)
{
Glib::RefPtr<Gio::InputStream> fin = fh->read_finish(res);
Glib::RefPtr<Glib::Bytes> fbytes = fin->read_bytes(8192, Glib::RefPtr<Gio::Cancellable>());
Glib::ustring str = bytesToUstring(fbytes);
Gtk::TextView *textview = NULL;
refGlade->get_widget("textviewUser", textview);
assert(textview!=NULL);
textview->get_buffer()->set_text(str);
}
This function fires off when the file has been read and you can safely talk to the FileInputStream. Use the function of the parent of that class read_bytes, here i ask to read 8192 bytes, but it can potentially be more, the Cancellable reference must be provided, but can be empty as is the case above. Now the tricky part, grab the Glib::RefPtr<Glib::Bytes> and do the conversion with the function that had to be written for this:
Glib::ustring bytesToUstring(Glib::RefPtr<Glib::Bytes> data)
{
Glib::ustring result = "";
gsize s;
gconstpointer d = g_bytes_get_data(data->gobj(), &s);
unsigned char c;
wchar_t wc;
unsigned short toread = 0;
for(int i=0; i<(int)s; ++i)
{
c = ((char*)d)[i];
if((c >> 7) == 0b0)
{
//std::cout << "Byte 0b0" << std::endl;
if(toread!=0)
{
std::cerr << "Help. I lost my place in the stream" << std::endl;
}
wc = (wchar_t)c;
}
else if((c >> 6) == 0b10)
{
//std::cout << "Byte 0b10" << std::endl;
if(toread==0)
{
std::cerr << "Help. I lost my place in the stream" << std::endl;
}
wc <<= 6; // 6 more bits are coming in
wc |= (c & 0b00111111);
--toread;
}
else // we can be sure that we have something starting with at least 2 set bits
{
if(toread!=0)
{
std::cerr << "Help. I lost my place in the stream" << std::endl;
}
if((c >> 5) == 0b110)
{
//std::cout << "Byte 0b110" << std::endl;
wc = c & 0b00011111;
toread = 1;
}
else if((c >> 4) == 0b1110)
{
//std::cout << "Byte 0b1110" << std::endl;
wc = c & 0b00001111;
toread = 2;
}
else if((c >> 3) == 0b11110)
{
//std::cout << "Byte 0b11110" << std::endl;
wc = c & 0b00000111;
toread = 3;
}
else if((c >> 2) == 0b111110)
{
//std::cout << "Byte 0b111110" << std::endl;
wc = c & 0b00000011;
toread = 4;
}
else if((c >> 1) == 0b1111110)
{
//std::cout << "Byte 0b1111110" << std::endl;
wc = c & 0b00000001;
toread = 5;
}
else // wtf?
{
std::cerr << "Help! Something is probaby not a UTF-8 at all" << std::endl;
for(int j=(8*(int)sizeof c) - 1; j>=0; --j)
{
std::cerr << (char)('0'+ (char)((c >> j) & 1));
}
std::cerr << std::endl;
}
}
if(toread == 0)
{
result += (gunichar)wc;
wc = L'\0';
//std::cout << i << ' ' << result << std::endl;
}
}
return result;
}
In here we must first and foremost grab the real pointer to bytes, since Glib::Bytes will refuse to give you the tools that you need. And then you can start converting into the wchar_t. The process isn't that difficult and is described in Wikipedia article on UTF-8 well enough.
And luckily wchar_t can be converted to gunichar and that in turn can be added to Glib::ustring.
So the path that we must take is:
Dialog -> Gio::File -> Glib::Bytes -> gconstpointer -> char -> (combining several chars) wchar_t -> gunichar -> Glib::ustring -> (add to TextArea's TextBuffer)
:Note: Currently this is not a ready to use code, it only reads 8192 bytes, and it won't help to then read more because there is no guarantee that the character didn't get broken in the middle of two reads, maybe i'll update the code a little later.

Related

Simulink Error S-function Escaped character \D is not Valid

I'm lately getting this weird error in Simulink that I can't find any information on.
Matlab version: 2018a
OS: Windows 10
gpio_in.c is the code for an s-function that was generated using the s-function builder. My own code is located in the associated wrapper file gpio_in_wrapper.c. The s-function builder is set to save code only and not to build it. I use this file for hardware interaction in later deployment via the Simulink coder.
Whenever I try to start the simulation, Simulink presents the above error to me and I don't have a clue what the problem could be. It looks to me like D: is the beginning of a file path, especially if you consider the warning above which says \D and is probably the beginning of the models directory which is D:\Dateien\Git_Repositories\BMaS_Neu\Simulink.
Contents of gpio_in_wrapper.c as suggested by UnbearableLightness
/*
* Include Files
*
*/
#if defined(MATLAB_MEX_FILE)
#include "tmwtypes.h"
#include "simstruc_types.h"
#else
#include "rtwtypes.h"
#endif
/* %%%-SFUNWIZ_wrapper_includes_Changes_BEGIN --- EDIT HERE TO _END */
#include <gpio.h>
/* %%%-SFUNWIZ_wrapper_includes_Changes_END --- EDIT HERE TO _BEGIN */
#define u_width 1
#define y_width 1
/*
* Create external references here.
*
*/
/* %%%-SFUNWIZ_wrapper_externs_Changes_BEGIN --- EDIT HERE TO _END */
/* %%%-SFUNWIZ_wrapper_externs_Changes_END --- EDIT HERE TO _BEGIN */
/*
* Output function
*
*/
void gpio_in_Outputs_wrapper(const int32_T *port_popupvalue,
const int32_T *pin_number,
boolean_T *gpio_in)
{
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */
if (*port_popupvalue == 1) {
*gpio_in = HAL_GPIO_ReadPin(GPIOA, (1 << *pin_number));
} else if (*port_popupvalue == 2) {
*gpio_in = HAL_GPIO_ReadPin(GPIOB, (1 << *pin_number));
} else if (*port_popupvalue == 3) {
*gpio_in = HAL_GPIO_ReadPin(GPIOC, (1 << *pin_number));
} else if (*port_popupvalue == 4) {
*gpio_in = HAL_GPIO_ReadPin(GPIOD, (1 << *pin_number));
} else if (*port_popupvalue == 5) {
*gpio_in = HAL_GPIO_ReadPin(GPIOE, (1 << *pin_number));
} else if (*port_popupvalue == 6) {
*gpio_in = HAL_GPIO_ReadPin(GPIOF, (1 << *pin_number));
} else if (*port_popupvalue == 7) {
*gpio_in = HAL_GPIO_ReadPin(GPIOG, (1 << *pin_number));
} else if (*port_popupvalue == 8) {
*gpio_in = HAL_GPIO_ReadPin(GPIOH, (1 << *pin_number));
} else if (*port_popupvalue == 9) {
*gpio_in = HAL_GPIO_ReadPin(GPIOI, (1 << *pin_number));
}
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */
}
I'd appreciate every hint of yours.
I think what is happening is that your code is accessing something from a path on D drive. For example, if the path name is 'D:\Somedirectory\Somefile', sometimes it treats '\S' as an escape sequence and throws an error. The solution for this would be replacing '\' with '\\', i.e, 'D:\\Somedirectory\\Somefile'.
According to the error it has escaped '\D' which means that the first letter of the directory or filename starts with 'D'.
As Cris Luengo mentioned in his comment, you should check the m-file, which is were you might find the part of code using a path.
Also is there any error text on the command window?

Getting information about process in Swift

I am trying to get some data about a process in Swift.
I am using this code as a starting point:
pid_t pid = 10000;
rusage_info_current rusage;
if (proc_pid_rusage(pid, RUSAGE_INFO_CURRENT, (void **)&rusage) == 0)
{
cout << rusage.ri_diskio_bytesread << endl;
cout << rusage.ri_diskio_byteswritten << endl;
}
taken from Per Process disk read/write statistics in Mac OS X.
However, I have trouble converting the code above to Swift:
var usage = rusage_info_v3()
if proc_pid_rusage(100, RUSAGE_INFO_CURRENT, &usage) == 0
{
Swift.print("Success")
}
The function prod_pid_rusage expects a parameter of type rusage_info_t?, but I can not instantiate an instance of that type.
Is it possible to use the function in Swift?
Regards,
Sascha
As in C you have to take the address of a rusage_info_current
variable and cast it to the type expected by proc_pid_rusage().
In Swift this is done using withUnsafeMutablePointer()
and withMemoryRebound():
let pid = getpid()
var usage = rusage_info_current()
let result = withUnsafeMutablePointer(to: &usage) {
$0.withMemoryRebound(to: rusage_info_t?.self, capacity: 1) {
proc_pid_rusage(pid, RUSAGE_INFO_CURRENT, $0)
}
}
if result == 0 {
print(usage.ri_diskio_bytesread)
// ...
}
You have to add
#include <libproc.h>
to the bridging header file to make it compile.

CCITT implement in Swift

How do I implement CRC-CCITT in swift. I manage to get it work on Java
public static String createCRC(String string) {
String crcCode = "";
int crc = 0xFFFF; // initial value
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
// byte[] testBytes = "123456789".getBytes("ASCII");
byte[] bytes = string.getBytes();
for (byte b : bytes) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7-i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
crcCode = Integer.toHexString(crc).toUpperCase();
return crcCode;
}
Can someone help me to convert to Swift. or maybe other file I can use like similar with this function?
Thankyou
use clasic "table" approach
let crc_table: [UInt16] = [
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
]
func crc16Ccitt(data: [UInt8], seed: UInt16, final: UInt16)->UInt16
{
var crc: UInt32 = UInt32(seed)
var temp: UInt32 = 0
data.forEach { byte in
temp = UInt32(byte) ^ (crc >> 8) & 0xff
crc = UInt32(crc_table[Int(temp)]) ^ (crc << 8)
}
return UInt16((crc ^ UInt32(final)) & 0xffff)
}
// test it first
print(crc16Ccitt(data: "".utf8.map{$0}, seed: 0x1D0F, final: 0) == 0x1d0f)
print(crc16Ccitt(data: "A".utf8.map{$0}, seed: 0x1D0F, final: 0) == 0x9479)
print(crc16Ccitt(data: "123456789".utf8.map{$0}, seed: 0x1D0F, final: 0) == 0xe5cc)
prints
true
true
true
or this very short Swift version
func crc16ccitt(data: [UInt8],seed: UInt16 = 0x1d0f, final: UInt16 = 0xffff)->UInt16{
var crc = seed
data.forEach { (byte) in
crc ^= UInt16(byte) << 8
(0..<8).forEach({ _ in
crc = (crc & 0x8000) != 0 ? (crc << 1) ^ 0x1021 : crc << 1
})
}
return crc & final
}
print(crc16ccitt(data: "".utf8.map{$0}) == 0x1d0f)
print(crc16ccitt(data: "A".utf8.map{$0}) == 0x9479)
print(crc16ccitt(data: "123456789".utf8.map{$0}) == 0xe5cc)
prints
true
true
true
Posting my answer to calculate CRC-16/CCITT-FALSE in case anybody finds it useful too, because the first two answers didn't work for me.
let data: [UInt8] = [0xE2, 0x2C, 0x1F, 0x4D, 0x7F, 0x28]
func crc16(buffer: [UInt8]) -> Int {
var crc: Int = 0xFFFF
for i in 0..<buffer.count {
crc = (crc >> 8 ^ crc << 8) & 0xffff
crc ^= Int((buffer[Int(i)] & 0xff))
crc ^= (crc & 0xff) >> 4
crc ^= (crc << 12) & 0xffff
crc ^= ((crc & 0xff) << 5) & 0xffff
}
crc &= 0xffff
return crc
}
Here is the output:
let intCRC = crc16(buffer: data)
let hexCRC = String(format:"%2X", a)
print(intCRC)
print(hexCRC)
Prints out:
41039
A04F
On this website https://crccalc.com you can check the answer:
func CRC16(hexStr : String)->NSString{
let data = hexStringToBytes(hexStr as String)
let final: UInt32 = 0xffff
var crc = final
data?.forEach { (byte) in
crc ^= UInt32(byte) << 8
(0..<8).forEach({ _ in
crc = (crc & UInt32(0x8000)) != 0 ? (crc << 1) ^ 0x1021 : crc << 1
})
}
let crcNew = UInt16(UInt32(crc & final))
return String(format:"%2X", crcNew) as NSString
}

How to use getaddrinfo()?

Im trying to make a simple program that takes in a string like www.google.com and returns the ip address...
What i have so far:
char* hostname = new char[www.size()+1];
std::copy(www.begin(), www.end(), hostname);
hostname[www.size()] = '\0';
struct addrinfo new_addr, *res;
getaddrinfo(www.c_str(), SERVICE.c_str(), &new_addr, &res);
cout << new_addr.ai_addr;
What are the 3rd of 4th parameters supposed to do? Does the getaddrinfo function modify the new_addr structure or what? I dont really understand the msdn documentation. After the hostname is resolved I want to connect a socket to it.
What if i leave the third parameter nullified?
Heres the code i developed so far.
char* hostname = new char[www.size()+1];
copy(www.begin(), www.end(), hostname);
hostname[www.size()] = '\0';
struct addrinfo *res;
struct in_addr addr;
getaddrinfo(hostname, NULL, 0, &res);
addr.S_un = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.S_un;
server.sin_addr.s_addr = inet_addr(inet_ntoa(addr));
server.sin_port = htons(portno);
freeaddrinfo(res);
delete []hostname;
server.sin is declared elsewhere that i use to fill a socket in another method of my sockets class.
The MSDN documentation is very detailed and explains exactly what the various parameters are for. The third parameter lets you specify the type of socket that will be used with the results of the lookup. This allies the results to be optimized as needed. The fourth parameter returns the actual results. The documentation also contains a full example of how to use the function. So what example is unclear about what the documentation says?
Try this:
struct addrinfo hints = {0};
hints.ai_flags = 0;
hints.ai_family = AF_UNSPEC; // IPv4 and IPv6 allowed
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
struct addrinfo *res = NULL;
if (getaddrinfo(www.c_str(), SERVICE.c_str(), &hints, &res) == 0)
{
TCHAR szIPAddr[64];
DWORD szIPAddrLen;
SOCKET skt;
struct addrinfo *addr = res;
do
{
skt = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (skt == INVALID_SOCKET)
cout << "Unable to create socket, error " << WSAGetLastError() << endl;
else
{
szIPAddrLen = 64;
WSAAddressToString(addr->ai_addr, addr->ai_addrlen, NULL, szIPAddr, &szIPAddrLen);
cout << "Connecting to " << szIPAddr << " ..." << endl;
if (connect(skt, addr->ai_addr, addr->ai_addrlen) == 0)
{
cout << "Connected!" << endl;
break;
}
cout << "Unable to connect, error " << WSAGetLastError() << endl;
closesocket(skt);
skt = INVALID_SOCKET;
}
addr = addr->ai_next;
}
while (addr);
freeaddrinfo(res);
if (skt != INVALID_SOCKET)
{
// use skt as needed...
closesocket(skt);
}
}

If I have two instances of Glib::IOChannel, they block until both written. What is the correct way to do this?

I have modified the example found here to use two io channels. None of the callbacks seem to be called before I have written to both channels. After that they are called individually when writing to the fifos. Am I forgetting something?
Start the test program in one shell window.
Write echo "abc" > testfifo1 in second shell window. -> nothing happens.
Write echo "def" > testfifo2 in a third shell window. -> now I get "abc" and "def"
Write to one of the fifos. This is immediately served.
Edit:
The solution, as hinted by Gormley below, was the lack of nonblock.
read_fd1 = open("testfifo1", O_RDONLY | O_NONBLOCK);
...
read_fd2 = open("testfifo2", O_RDONLY | O_NONBLOCK);
This change to the code below made it respond immediately.
The code:
#include <gtkmm/main.h>
#include <fcntl.h>
#include <iostream>
int read_fd1, read_fd2;
Glib::RefPtr<Glib::IOChannel> iochannel1, iochannel2;
// Usage: "echo "Hello" > testfifo<1|2>", quit with "Q"
bool MyCallback1(Glib::IOCondition io_condition)
{
Glib::ustring buf;
iochannel1->read_line(buf);
std::cout << "io 1: " << buf;
if (buf == "Q\n")
Gtk::Main::quit();
return true;
}
bool MyCallback2(Glib::IOCondition io_condition)
{
Glib::ustring buf;
iochannel2->read_line(buf);
std::cout << "io 2: " << buf;
if (buf == "Q\n")
Gtk::Main::quit();
return true;
}
int main(int argc, char *argv[])
{
// the usual Gtk::Main object
Gtk::Main app(argc, argv);
if (access("testfifo1", F_OK) == -1)
{
if (mkfifo("testfifo1", 0666) != 0)
return -1;
}
if (access("testfifo2", F_OK) == -1)
{
if (mkfifo("testfifo2", 0666) != 0)
return -1;
}
read_fd1 = open("testfifo1", O_RDONLY);
if (read_fd1 == -1)
return -1;
read_fd2 = open("testfifo2", O_RDONLY);
if (read_fd2 == -1)
return -1;
Glib::signal_io().connect(sigc::ptr_fun(MyCallback1), read_fd1, Glib::IO_IN);
Glib::signal_io().connect(sigc::ptr_fun(MyCallback2), read_fd2, Glib::IO_IN);
iochannel1 = Glib::IOChannel::create_from_fd(read_fd1);
iochannel2 = Glib::IOChannel::create_from_fd(read_fd2);
app.run();
if (unlink("testfifo1"))
std::cerr << "error removing fifo 1" << std::endl;
if (unlink("testfifo2"))
std::cerr << "error removing fifo 2" << std::endl;
return 0;
}
These two statements block the program from getting into the main loop until both fifos
are open for write. fifos block until both sides are connected
iochannel1 = Glib::IOChannel::create_from_fd(read_fd1);
iochannel2 = Glib::IOChannel::create_from_fd(read_fd2);