Multi-threading through lots of files - c++

Good evening to everyone.
First, sorry for my English, I'm trying to know better this language.
I've three files:
Main.cpp -> Contain the graphics interface, and the two worker
thread.
Lettore.cpp -> Contain the functions to reconize the type of
the file and use the correct library for play the audio, also contain
the function for stop, play,pause,skip a song.
The two audio code library -> That decode the track and send it to ao for playing.
Now, i'm trying to divide the audio process from the main code. But i don't know how to realize that.
I see C++ 11 reference, i study the condition variable of the pthreded module, but how i can implement this ?
For example, a implement like this in one of the libraries audio files, is correct?
//mpg123.c
int playmp3(char* filename,int action)
{
static mpg123_handle *mh;
static unsigned char *buffer;
/*...Many Static Dichiaration.../*
static long rate;
char* canzone=filename;
if (action==0)
{
/* Inizialize */
/*...*/
/* open the file and get the decoding format */
mpg123_open(mh,canzone);
mpg123_getformat(mh, &rate, &channels, &encoding);
/* set the output format and open the output device */
format.bits = mpg123_encsize(encoding) * BITS;
/*...*/
dev = ao_open_live(driver, &format, NULL);
}
if(action==1)
{
/* decode and play */
while (action==1&&mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK)
if((ao_play(dev, (char*)buffer, done)==0)&&action==1)
}
if(action==2)
{
/* clean up */
free(buffer);
ao_close(dev);
mpg123_close(mh);
/*...*/
}
}
Like you can see i need extern the code in other files because "playmp3" is write in C and "playother" is write in C++.
In "Lettore.cpp" how i can control the audio flow ? I can include directly a function of Lettore.cpp in a thread of the main.cpp?
Thank you for your time
Ps: if this question isn't congruent with the rules i modify this question instantly!
EDIT: For clarity I attach also my attempt on Lettore.cpp
//Lettore.cpp
#include <iostream>
#include "playother.h"
#include "Lettore.h"
extern "C" {
#include "mpg123.h"
}
bool Audio::isMp3(char * nome)
{
//Reconize if the file is an mp3.
}
void Audio::inizialize(char * filename)
{
Audio::currentrack=filename;
Audio::isOpen=true;
if (isMp3(Audio::tracciacorrente)){
playmp3(Audio::currentrack,0);
}else{
playmusic(Audio::currentrack,0);
}
}
void Audio::play()
{
if (isMp3(Audio::currentrack)){
playmp3(Audio::currentrack,1);
}else{
playmusic(Audio::currentrack,1);
}
}
void Audio::close()
{
if (isMp3(Audio::currentrack)){
playmp3(Audio::currentrack,2);
}else{
playmusic(Audio::currentrack,2);
}
Audio::currentrack=NULL;
Audio::isOpen=false;
}
void Audio::pause()
{
if (isMp3(Audio::currentrack)){
playmp3(Audio::currentrack,4);
}else{
playmusic(Audio::currentrack,4);
}
}
bool Audio::get_openstatus()
{
return Audio::isOpen;
}
Now the question is the same: If this is the correct implementation of the two files, what should I write about main.cpp order to use these files?

Related

Arduino - MagStripe card.available pauses and no other code can run

I am using the MagStrip library (https://github.com/carlosefr/magstripelib). In my main loop I call the function which runs the code:
void magcardFunc()
{
static const byte DATA_BUFFER_LEN = 108;
static char magcard[DATA_BUFFER_LEN];
// Don't do anything if there isn't a card present
if (!card.available()) {
return;
}
// Read the card into the buffer "magcard" (as a null-terminated string)
short chars = card.read(magcard, DATA_BUFFER_LEN);
if (chars < 0) {
Serial.print("bad read");
return;
}
// Send the data to the computer if data was read
if (chars != 0) {
Serial.print(magcardstr);
}
}
The code successfully reads a magnetic card when inserted.
The problem is, I have other functions which are called from the main loop but they do not get called as the code pauses at:
if (!card.available()) {
return;
}
// Read the card into the buffer "magcard" (as a null-terminated string)
short chars = card.read(magcard, DATA_BUFFER_LEN);
If I insert a card into my mag reader (and leave it there), the program continues and the other functions are called. I want the main loop to continue and the other functions be called without having to leave a card inserted.
I have tried removing the IF statement:
if (!card.available()) {
return;
}
and I have tried reversing it
if (card.available()) {
return;
}
If I reverse it as above, the other functions run but when I do swipe a card, it is not read.
I get no compiler errors.
EDIT:
Here is an example sketch which replicates the problem. I noticed that this sketch actually did call the otherFunc when the mag card reader was unplugged. I am not sure why when it is plugged in it pauses. Maybe an interrupt is always on?
#include <MagStripe.h>
void magcardFunc();
void otherFunc();
MagStripe card;
static const byte DATA_BUFFER_LEN = 108;
static char data[DATA_BUFFER_LEN];
void setup()
{
// The card data will be sent over serial...
Serial.begin(9600);
// Initialize the library for reading track 2...
card.begin(2);
}
void loop()
{
magcardFunc();
otherFunc();
}
void magcardFunc()
{
// Don't do anything if there isn't a card present...
if (!card.available()) {
return;
}
Any help is appreciated.

c++ Protocol buffer sending over network [duplicate]

I'm trying to read / write multiple Protocol Buffers messages from files, in both C++ and Java. Google suggests writing length prefixes before the messages, but there's no way to do that by default (that I could see).
However, the Java API in version 2.1.0 received a set of "Delimited" I/O functions which apparently do that job:
parseDelimitedFrom
mergeDelimitedFrom
writeDelimitedTo
Are there C++ equivalents? And if not, what's the wire format for the size prefixes the Java API attaches, so I can parse those messages in C++?
Update:
These now exist in google/protobuf/util/delimited_message_util.h as of v3.3.0.
I'm a bit late to the party here, but the below implementations include some optimizations missing from the other answers and will not fail after 64MB of input (though it still enforces the 64MB limit on each individual message, just not on the whole stream).
(I am the author of the C++ and Java protobuf libraries, but I no longer work for Google. Sorry that this code never made it into the official lib. This is what it would look like if it had.)
bool writeDelimitedTo(
const google::protobuf::MessageLite& message,
google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
// We create a new coded stream for each message. Don't worry, this is fast.
google::protobuf::io::CodedOutputStream output(rawOutput);
// Write the size.
const int size = message.ByteSize();
output.WriteVarint32(size);
uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL) {
// Optimization: The message fits in one buffer, so use the faster
// direct-to-array serialization path.
message.SerializeWithCachedSizesToArray(buffer);
} else {
// Slightly-slower path when the message is multiple buffers.
message.SerializeWithCachedSizes(&output);
if (output.HadError()) return false;
}
return true;
}
bool readDelimitedFrom(
google::protobuf::io::ZeroCopyInputStream* rawInput,
google::protobuf::MessageLite* message) {
// We create a new coded stream for each message. Don't worry, this is fast,
// and it makes sure the 64MB total size limit is imposed per-message rather
// than on the whole stream. (See the CodedInputStream interface for more
// info on this limit.)
google::protobuf::io::CodedInputStream input(rawInput);
// Read the size.
uint32_t size;
if (!input.ReadVarint32(&size)) return false;
// Tell the stream not to read beyond that size.
google::protobuf::io::CodedInputStream::Limit limit =
input.PushLimit(size);
// Parse the message.
if (!message->MergeFromCodedStream(&input)) return false;
if (!input.ConsumedEntireMessage()) return false;
// Release the limit.
input.PopLimit(limit);
return true;
}
Okay, so I haven't been able to find top-level C++ functions implementing what I need, but some spelunking through the Java API reference turned up the following, inside the MessageLite interface:
void writeDelimitedTo(OutputStream output)
/* Like writeTo(OutputStream), but writes the size of
the message as a varint before writing the data. */
So the Java size prefix is a (Protocol Buffers) varint!
Armed with that information, I went digging through the C++ API and found the CodedStream header, which has these:
bool CodedInputStream::ReadVarint32(uint32 * value)
void CodedOutputStream::WriteVarint32(uint32 value)
Using those, I should be able to roll my own C++ functions that do the job.
They should really add this to the main Message API though; it's missing functionality considering Java has it, and so does Marc Gravell's excellent protobuf-net C# port (via SerializeWithLengthPrefix and DeserializeWithLengthPrefix).
I solved the same problem using CodedOutputStream/ArrayOutputStream to write the message (with the size) and CodedInputStream/ArrayInputStream to read the message (with the size).
For example, the following pseudo-code writes the message size following by the message:
const unsigned bufLength = 256;
unsigned char buffer[bufLength];
Message protoMessage;
google::protobuf::io::ArrayOutputStream arrayOutput(buffer, bufLength);
google::protobuf::io::CodedOutputStream codedOutput(&arrayOutput);
codedOutput.WriteLittleEndian32(protoMessage.ByteSize());
protoMessage.SerializeToCodedStream(&codedOutput);
When writing you should also check that your buffer is large enough to fit the message (including the size). And when reading, you should check that your buffer contains a whole message (including the size).
It definitely would be handy if they added convenience methods to C++ API similar to those provided by the Java API.
IsteamInputStream is very fragile to eofs and other errors that easily occurs when used together with std::istream. After this the protobuf streams are permamently damaged and any already used buffer data is destroyed. There are proper support for reading from traditional streams in protobuf.
Implement google::protobuf::io::CopyingInputStream and use that together with CopyingInputStreamAdapter. Do the same for the output variants.
In practice a parsing call ends up in google::protobuf::io::CopyingInputStream::Read(void* buffer, int size) where a buffer is given. The only thing left to do is read into it somehow.
Here's an example for use with Asio synchronized streams (SyncReadStream/SyncWriteStream):
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
using namespace google::protobuf::io;
template <typename SyncReadStream>
class AsioInputStream : public CopyingInputStream {
public:
AsioInputStream(SyncReadStream& sock);
int Read(void* buffer, int size);
private:
SyncReadStream& m_Socket;
};
template <typename SyncReadStream>
AsioInputStream<SyncReadStream>::AsioInputStream(SyncReadStream& sock) :
m_Socket(sock) {}
template <typename SyncReadStream>
int
AsioInputStream<SyncReadStream>::Read(void* buffer, int size)
{
std::size_t bytes_read;
boost::system::error_code ec;
bytes_read = m_Socket.read_some(boost::asio::buffer(buffer, size), ec);
if(!ec) {
return bytes_read;
} else if (ec == boost::asio::error::eof) {
return 0;
} else {
return -1;
}
}
template <typename SyncWriteStream>
class AsioOutputStream : public CopyingOutputStream {
public:
AsioOutputStream(SyncWriteStream& sock);
bool Write(const void* buffer, int size);
private:
SyncWriteStream& m_Socket;
};
template <typename SyncWriteStream>
AsioOutputStream<SyncWriteStream>::AsioOutputStream(SyncWriteStream& sock) :
m_Socket(sock) {}
template <typename SyncWriteStream>
bool
AsioOutputStream<SyncWriteStream>::Write(const void* buffer, int size)
{
boost::system::error_code ec;
m_Socket.write_some(boost::asio::buffer(buffer, size), ec);
return !ec;
}
Usage:
AsioInputStream<boost::asio::ip::tcp::socket> ais(m_Socket); // Where m_Socket is a instance of boost::asio::ip::tcp::socket
CopyingInputStreamAdaptor cis_adp(&ais);
CodedInputStream cis(&cis_adp);
Message protoMessage;
uint32_t msg_size;
/* Read message size */
if(!cis.ReadVarint32(&msg_size)) {
// Handle error
}
/* Make sure not to read beyond limit of message */
CodedInputStream::Limit msg_limit = cis.PushLimit(msg_size);
if(!msg.ParseFromCodedStream(&cis)) {
// Handle error
}
/* Remove limit */
cis.PopLimit(msg_limit);
Here you go:
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>
using namespace google::protobuf::io;
class FASWriter
{
std::ofstream mFs;
OstreamOutputStream *_OstreamOutputStream;
CodedOutputStream *_CodedOutputStream;
public:
FASWriter(const std::string &file) : mFs(file,std::ios::out | std::ios::binary)
{
assert(mFs.good());
_OstreamOutputStream = new OstreamOutputStream(&mFs);
_CodedOutputStream = new CodedOutputStream(_OstreamOutputStream);
}
inline void operator()(const ::google::protobuf::Message &msg)
{
_CodedOutputStream->WriteVarint32(msg.ByteSize());
if ( !msg.SerializeToCodedStream(_CodedOutputStream) )
std::cout << "SerializeToCodedStream error " << std::endl;
}
~FASWriter()
{
delete _CodedOutputStream;
delete _OstreamOutputStream;
mFs.close();
}
};
class FASReader
{
std::ifstream mFs;
IstreamInputStream *_IstreamInputStream;
CodedInputStream *_CodedInputStream;
public:
FASReader(const std::string &file), mFs(file,std::ios::in | std::ios::binary)
{
assert(mFs.good());
_IstreamInputStream = new IstreamInputStream(&mFs);
_CodedInputStream = new CodedInputStream(_IstreamInputStream);
}
template<class T>
bool ReadNext()
{
T msg;
unsigned __int32 size;
bool ret;
if ( ret = _CodedInputStream->ReadVarint32(&size) )
{
CodedInputStream::Limit msgLimit = _CodedInputStream->PushLimit(size);
if ( ret = msg.ParseFromCodedStream(_CodedInputStream) )
{
_CodedInputStream->PopLimit(msgLimit);
std::cout << mFeed << " FASReader ReadNext: " << msg.DebugString() << std::endl;
}
}
return ret;
}
~FASReader()
{
delete _CodedInputStream;
delete _IstreamInputStream;
mFs.close();
}
};
I ran into the same issue in both C++ and Python.
For the C++ version, I used a mix of the code Kenton Varda posted on this thread and the code from the pull request he sent to the protobuf team (because the version posted here doesn't handle EOF while the one he sent to github does).
#include <google/protobuf/message_lite.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/coded_stream.h>
bool writeDelimitedTo(const google::protobuf::MessageLite& message,
google::protobuf::io::ZeroCopyOutputStream* rawOutput)
{
// We create a new coded stream for each message. Don't worry, this is fast.
google::protobuf::io::CodedOutputStream output(rawOutput);
// Write the size.
const int size = message.ByteSize();
output.WriteVarint32(size);
uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL)
{
// Optimization: The message fits in one buffer, so use the faster
// direct-to-array serialization path.
message.SerializeWithCachedSizesToArray(buffer);
}
else
{
// Slightly-slower path when the message is multiple buffers.
message.SerializeWithCachedSizes(&output);
if (output.HadError())
return false;
}
return true;
}
bool readDelimitedFrom(google::protobuf::io::ZeroCopyInputStream* rawInput, google::protobuf::MessageLite* message, bool* clean_eof)
{
// We create a new coded stream for each message. Don't worry, this is fast,
// and it makes sure the 64MB total size limit is imposed per-message rather
// than on the whole stream. (See the CodedInputStream interface for more
// info on this limit.)
google::protobuf::io::CodedInputStream input(rawInput);
const int start = input.CurrentPosition();
if (clean_eof)
*clean_eof = false;
// Read the size.
uint32_t size;
if (!input.ReadVarint32(&size))
{
if (clean_eof)
*clean_eof = input.CurrentPosition() == start;
return false;
}
// Tell the stream not to read beyond that size.
google::protobuf::io::CodedInputStream::Limit limit = input.PushLimit(size);
// Parse the message.
if (!message->MergeFromCodedStream(&input)) return false;
if (!input.ConsumedEntireMessage()) return false;
// Release the limit.
input.PopLimit(limit);
return true;
}
And here is my python2 implementation:
from google.protobuf.internal import encoder
from google.protobuf.internal import decoder
#I had to implement this because the tools in google.protobuf.internal.decoder
#read from a buffer, not from a file-like objcet
def readRawVarint32(stream):
mask = 0x80 # (1 << 7)
raw_varint32 = []
while 1:
b = stream.read(1)
#eof
if b == "":
break
raw_varint32.append(b)
if not (ord(b) & mask):
#we found a byte starting with a 0, which means it's the last byte of this varint
break
return raw_varint32
def writeDelimitedTo(message, stream):
message_str = message.SerializeToString()
delimiter = encoder._VarintBytes(len(message_str))
stream.write(delimiter + message_str)
def readDelimitedFrom(MessageType, stream):
raw_varint32 = readRawVarint32(stream)
message = None
if raw_varint32:
size, _ = decoder._DecodeVarint32(raw_varint32, 0)
data = stream.read(size)
if len(data) < size:
raise Exception("Unexpected end of file")
message = MessageType()
message.ParseFromString(data)
return message
#In place version that takes an already built protobuf object
#In my tests, this is around 20% faster than the other version
#of readDelimitedFrom()
def readDelimitedFrom_inplace(message, stream):
raw_varint32 = readRawVarint32(stream)
if raw_varint32:
size, _ = decoder._DecodeVarint32(raw_varint32, 0)
data = stream.read(size)
if len(data) < size:
raise Exception("Unexpected end of file")
message.ParseFromString(data)
return message
else:
return None
It might not be the best looking code and I'm sure it can be refactored a fair bit, but at least that should show you one way to do it.
Now the big problem: It's SLOW.
Even when using the C++ implementation of python-protobuf, it's one order of magnitude slower than in pure C++. I have a benchmark where I read 10M protobuf messages of ~30 bytes each from a file. It takes ~0.9s in C++, and 35s in python.
One way to make it a bit faster would be to re-implement the varint decoder to make it read from a file and decode in one go, instead of reading from a file and then decoding as this code currently does. (profiling shows that a significant amount of time is spent in the varint encoder/decoder). But needless to say that alone is not enough to close the gap between the python version and the C++ version.
Any idea to make it faster is very welcome :)
Just for completeness, I post here an up-to-date version that works with the master version of protobuf and Python3
For the C++ version it is sufficient to use the utils in delimited_message_utils.h, here a MWE
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/util/delimited_message_util.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
template <typename T>
bool writeManyToFile(std::deque<T> messages, std::string filename) {
int outfd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
google::protobuf::io::FileOutputStream fout(outfd);
bool success;
for (auto msg: messages) {
success = google::protobuf::util::SerializeDelimitedToZeroCopyStream(
msg, &fout);
if (! success) {
std::cout << "Writing Failed" << std::endl;
break;
}
}
fout.Close();
close(outfd);
return success;
}
template <typename T>
std::deque<T> readManyFromFile(std::string filename) {
int infd = open(filename.c_str(), O_RDONLY);
google::protobuf::io::FileInputStream fin(infd);
bool keep = true;
bool clean_eof = true;
std::deque<T> out;
while (keep) {
T msg;
keep = google::protobuf::util::ParseDelimitedFromZeroCopyStream(
&msg, &fin, nullptr);
if (keep)
out.push_back(msg);
}
fin.Close();
close(infd);
return out;
}
For the Python3 version, building on #fireboot 's answer, the only thing thing that needed modification is the decoding of raw_varint32
def getSize(raw_varint32):
result = 0
shift = 0
b = six.indexbytes(raw_varint32, 0)
result |= ((ord(b) & 0x7f) << shift)
return result
def readDelimitedFrom(MessageType, stream):
raw_varint32 = readRawVarint32(stream)
message = None
if raw_varint32:
size = getSize(raw_varint32)
data = stream.read(size)
if len(data) < size:
raise Exception("Unexpected end of file")
message = MessageType()
message.ParseFromString(data)
return message
Was also looking for a solution for this. Here's the core of our solution, assuming some java code wrote many MyRecord messages with writeDelimitedTo into a file. Open the file and loop, doing:
if(someCodedInputStream->ReadVarint32(&bytes)) {
CodedInputStream::Limit msgLimit = someCodedInputStream->PushLimit(bytes);
if(myRecord->ParseFromCodedStream(someCodedInputStream)) {
//do your stuff with the parsed MyRecord instance
} else {
//handle parse error
}
someCodedInputStream->PopLimit(msgLimit);
} else {
//maybe end of file
}
Hope it helps.
Working with an objective-c version of protocol-buffers, I ran into this exact issue. On sending from the iOS client to a Java based server that uses parseDelimitedFrom, which expects the length as the first byte, I needed to call writeRawByte to the CodedOutputStream first. Posting here to hopegully help others that run into this issue. While working through this issue, one would think that Google proto-bufs would come with a simply flag which does this for you...
Request* request = [rBuild build];
[self sendMessage:request];
}
- (void) sendMessage:(Request *) request {
//** get length
NSData* n = [request data];
uint8_t len = [n length];
PBCodedOutputStream* os = [PBCodedOutputStream streamWithOutputStream:outputStream];
//** prepend it to message, such that Request.parseDelimitedFrom(in) can parse it properly
[os writeRawByte:len];
[request writeToCodedOutputStream:os];
[os flush];
}
Since I'm not allowed to write this as a comment to Kenton Varda's answer above; I believe there is a bug in the code he posted (as well as in other answers which have been provided). The following code:
...
google::protobuf::io::CodedInputStream input(rawInput);
// Read the size.
uint32_t size;
if (!input.ReadVarint32(&size)) return false;
// Tell the stream not to read beyond that size.
google::protobuf::io::CodedInputStream::Limit limit =
input.PushLimit(size);
...
sets an incorrect limit because it does not take into account the size of the varint32 which has already been read from input. This can result in data loss/corruption as additional bytes are read from the stream which may be part of the next message. The usual way of handling this correctly is to delete the CodedInputStream used to read the size and create a new one for reading the payload:
...
uint32_t size;
{
google::protobuf::io::CodedInputStream input(rawInput);
// Read the size.
if (!input.ReadVarint32(&size)) return false;
}
google::protobuf::io::CodedInputStream input(rawInput);
// Tell the stream not to read beyond that size.
google::protobuf::io::CodedInputStream::Limit limit =
input.PushLimit(size);
...
You can use getline for reading a string from a stream, using the specified delimiter:
istream& getline ( istream& is, string& str, char delim );
(defined in the header)

XBee, external libraries and passing structures as arguments

I have very weird problem with a library I am creating. The library will be used to communicate between Arduino modules using XBee Series 1 modules. Library is very simple wrapper library around Arduino XBee library.
I have one function that reads received packet and sends it back. At the moment it is implemented as a simple "echo" service - the function just displays the data received and sends it back to per-defined address.
At the moment I have three versions of this function, out of which one is not working.
A function taking no arguments: void processPacket()
A function taking structure as a value as an argument: void processPacket(valuesStruct valuesStructData) - THIS VERSION OF THE FUNCTION IS NOT WORKING!
A function taking pointer to the structure as an argument: void processPacket(valuesStruct* valuesStructData)
At this moment I noticed strange behavior in the 2nd version of the function. I do nothing with the passed argument - the content of all three functions is the same. In 2nd case the function reads wrong values from received XBee packet. In the 1st and 3rd case the function performs correctly.
Code:
ExampleLib.h
#ifndef ExampleLib_h
#define ExampleLib_h
#include "Arduino.h"
#include <XBee.h>
#define ADDRESS_BROADCAST 0xffff
#define ADDRESS_PC 0x3333
typedef struct
{
int valA;
int valB;
int valC;
} valuesStruct;
class ExampleLib
{
public:
ExampleLib();
void setSerial(Stream &serial);
boolean tryReceivePacket();
void processPacket();
// THIS FUNCTION IS NOT WORKING!
void processPacket(valuesStruct valuesStructData);
void processPacket(valuesStruct* valuesStructData);
private:
XBee xbee;
Rx16Response rx16;
};
#endif
ExampleLib.cpp
The value read in line byte* packetData = rx16.getData(); is wrong when we trigger processPacket(valuesStruct valuesStructData) function. In other cases the behavior is correct.
#include "Arduino.h"
#include <XBee.h>
#include "ExampleLib.h"
ExampleLib::ExampleLib()
{
xbee = XBee();
rx16 = Rx16Response();
}
void ExampleLib::setSerial(Stream &serial)
{
xbee.setSerial(serial);
}
boolean ExampleLib::tryReceivePacket()
{
xbee.readPacket();
if (xbee.getResponse().isAvailable()) {
// got something
if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
// got a rx packet
xbee.getResponse().getRx16Response(rx16);
return true;
}
else {
return false;
}
}
else if (xbee.getResponse().isError()) {
//nss.print("Error reading packet. Error code: ");
//nss.println(xbee.getResponse().getErrorCode());
// or flash error led
return false;
}
return false;
}
void ExampleLib::processPacket()
{
byte* packetData = rx16.getData();
byte dataLength = rx16.getDataLength();
Serial.print("START L:");
Serial.println(dataLength);
for (int i = 0; i < dataLength; i++) {
Serial.print(packetData[i]);
Serial.print(" - ");
}
Serial.println("END");
//16-bit addressing: Enter address of remote XBee, typically the coordinator
Tx16Request tx = Tx16Request(ADDRESS_PC, packetData, sizeof(packetData));
xbee.send(tx);
}
void ExampleLib::processPacket(valuesStruct valuesStructData)
{
processPacket();
}
void ExampleLib::processPacket(valuesStruct* valuesStructData)
{
processPacket();
}
Arduino sketch
#include <XBee.h>
#include <ExampleLib.h>
ExampleLib exampleLibObj = ExampleLib();
void setup()
{
Serial.begin(9600);
exampleLibObj.setSerial(Serial);
}
void loop()
{
boolean isPacketReceived = exampleLibObj.tryReceivePacket();
if (isPacketReceived) {
// leave only one section, the rest should be commented
//Section 1: working
exampleLibObj.processPacket();
//Section 2: not working
// valuesStruct test;
// test.valA = 0;
// test.valB = 0;
// test.valC = 0;
// exampleLibObj.processPacket(test);
//Section 3: working
// valuesStruct* test;
// test->valA = 0;
// test->valB = 0;
// test->valC = 0;
// exampleLibObj.processPacket(test);
}
}
I am really puzzled why in this one case function is performing differently. Looking forward to any suggestions to that issue.
Thanks,
Michal
Are you sure it isn't your section 3 that's causing problems? Because you're declaring a pointer to a structure, but not allocating memory for that structure.
You'd typically write your code like this:
valuesStruct test;
test.valA = 0;
test.valB = 0;
test.valC = 0;
//Section 2: not working
exampleLibObj.processPacket(test);
//Section 3: working
exampleLibObj.processPacket(&test);
But you also wouldn't typically pass a structure to a function -- you'd pass a pointer to that structure. There really isn't a need for your second sample.

Creating text file into C++ addon of node.js

I want to know how i can create file and append data inside it in c++ addon (.cc) file of node.js ??
I have used below code to do same, but not able to find file "data.txt" in my ubuntu machine(reason behind it may be below code is not correct way to create file, but strange i haven't received any error/warning at compile time).
FILE * pFileTXT;
pFileTXT = fopen ("data.txt","a+");
const char * c = localReq->strResponse.c_str();
fprintf(pFileTXT,c);
fclose (pFileTXT);
Node.js relies on libuv, a C library to handle the I/O (asynchronous or not). This allows you to use the event loop.
You'd be interested in this free online book/introduction to libuv: http://nikhilm.github.com/uvbook/index.html
Specifically, there is a chapter dedicated to reading/writing files.
int main(int argc, char **argv) {
// Open the file in write-only and execute the "on_open" callback when it's ready
uv_fs_open(uv_default_loop(), &open_req, argv[1], O_WRONLY, 0, on_open);
// Run the event loop.
uv_run(uv_default_loop());
return 0;
}
// on_open callback called when the file is opened
void on_open(uv_fs_t *req) {
if (req->result != -1) {
// Specify the on_write callback "on_write" as last argument
uv_fs_write(uv_default_loop(), &write_req, 1, buffer, req->result, -1, on_write);
}
else {
fprintf(stderr, "error opening file: %d\n", req->errorno);
}
// Don't forget to cleanup
uv_fs_req_cleanup(req);
}
void on_write(uv_fs_t *req) {
uv_fs_req_cleanup(req);
if (req->result < 0) {
fprintf(stderr, "Write error: %s\n", uv_strerror(uv_last_error(uv_default_loop())));
}
else {
// Close the handle once you're done with it
uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
}
}
Spend some time reading the book if you want to write C++ for node.js. It's worth it.

Why doesn't this keyboard intercepting kernel extension work?

my fellow developers! I hope very much that at least some of you will not get frightened by the amount of text this question contains (I simply did my best to be as descriptive as humanely possible). :)
To those who think I've asked this question to write malware or something. I want to write an application that will allow users to select applications to be launched after the OS will finish launching. The whole idea is to allow user to select these apps BEFORE the OS finished launching by pressing hotkeys previously binded to the apps. For example user turns on his Mac, types SMTV and goes away, when the system finishes launching my app recovers the input and launches Safari, Mail, Tweetie and Vuze. I'm new to SO but I do my best to help others by answering their questions - I think I can expect the same in return. Check my profile and my activity and after that start screaming about malware.
This question is a follow-up to the question Is it possible to recover keyboard input that was done while Mac OS was starting up?.
Guided by Pekka's advice, I've stumbled upon an article Intercepting Keyboard Events by Christian Starkjohann that describes how he and the Objective Development team succeeded in reassigning iBook's CDROM eject key from F12 to Shift+F12. The main part is that they actually intercepted keyboard events, which is what I need. In the end Christian has written this article exactly for developers like me to use the idea of iJect as a prototype for similar functionality.
To start with, I decided to create a simple kernel extension to simply log the user's keyboard input to /var/log/kernel.log. I've started a new Generic Kernel Extension project in XCode, followed the instructions of the Hello Kernel: Creating a Kernel Extension With Xcode tutorial found in Mac Dev Center's Kernel Extension Concepts to create a Hello World project and then stuffed it with code taken from iJect sources. Here are the results:
TestKEXT.c
#include <sys/systm.h>
#include <mach/mach_types.h>
extern int HidHackLoad(void);
extern int HidHackUnload(void);
kern_return_t MacOSSCKEXT_start (kmod_info_t * ki, void * d) {
return HidHackLoad() == 0 ? KERN_SUCCESS : KERN_FAILURE;
}
kern_return_t MacOSSCKEXT_stop (kmod_info_t * ki, void * d) {
return HidHackUnload() == 0 ? KERN_SUCCESS : KERN_FAILURE;
}
HIDHack.h
#ifdef __cplusplus
extern "C" {
#endif
#include <mach/mach_types.h>
#include <sys/systm.h>
extern int HidHackLoad(void);
extern int HidHackUnload(void);
#ifdef __cplusplus
}
#endif
#include <IOKit/system.h>
#include <IOKit/assert.h>
#include <IOKit/hidsystem/IOHIDSystem.h>
class HIDHack : public IOHIDSystem {
public:
virtual void keyboardEvent(unsigned eventType,
/* flags */ unsigned flags,
/* keyCode */ unsigned key,
/* charCode */ unsigned charCode,
/* charSet */ unsigned charSet,
/* originalCharCode */ unsigned origCharCode,
/* originalCharSet */ unsigned origCharSet,
/* keyboardType */ unsigned keyboardType,
/* repeat */ bool repeat,
/* atTime */ AbsoluteTime ts);
virtual void keyboardSpecialEvent(unsigned eventType,
/* flags */ unsigned flags,
/* keyCode */ unsigned key,
/* specialty */ unsigned flavor,
/* guid */ UInt64 guid,
/* repeat */ bool repeat,
/* atTime */ AbsoluteTime ts);
};
HIDHack.cpp
#include "HIDHack.h"
static void *oldVtable = NULL;
static void *myVtable = NULL;
int HidHackLoad(void) {
IOHIDSystem *p;
HIDHack *sub;
if (oldVtable != NULL) {
printf("###0 KEXT is already loaded\n");
return 1;
}
if (myVtable == NULL) {
sub = new HIDHack();
myVtable = *(void **)sub;
sub->free();
}
p = IOHIDSystem::instance();
oldVtable = *(void **)p;
*(void **)p = myVtable;
printf("###1 KEXT has been successfully loaded\n");
return 0;
}
int HidHackUnload(void) {
IOHIDSystem *p;
if (oldVtable != NULL) {
p = IOHIDSystem::instance();
if (*(void **)p != myVtable) {
printf("###2 KEXT is not loaded\n");
return 1;
}
*(void **)p = oldVtable;
oldVtable = NULL;
}
printf("###3 KEXT has been successfully unloaded\n");
return 0;
}
void HIDHack::keyboardEvent(unsigned eventType, unsigned flags, unsigned key, unsigned charCode, unsigned charSet, unsigned origCharCode, unsigned origCharSet, unsigned keyboardType, bool repeat,
AbsoluteTime ts) {
printf("###4 hid event type %d flags 0x%x key %d kbdType %d\n", eventType, flags, key, keyboardType);
IOHIDSystem::keyboardEvent(eventType, flags, key, charCode, charSet, origCharCode, origCharSet, keyboardType, repeat, ts);
}
void HIDHack::keyboardSpecialEvent( unsigned eventType,
/* flags */ unsigned flags,
/* keyCode */ unsigned key,
/* specialty */ unsigned flavor,
/* guid */ UInt64 guid,
/* repeat */ bool repeat,
/* atTime */ AbsoluteTime ts) {
printf("###5 special event type %d flags 0x%x key %d flavor %d\n", eventType, flags, key, flavor);
IOHIDSystem::keyboardSpecialEvent(eventType, flags, key, flavor, guid, repeat, ts);
}
The resulting kernel extension gets successfully loaded/unloaded by kextload/kextunload programs, but doesn't actually intercept any of the keyboard events. I've tried doing lots of things to get it working, but without any errors or other problems with it in the way I can't google anything useful and ask your help.
The problem is not with how you are overriding the existing IOHIDSystem instance. That works just fine.
The problem is that when IOHIKeyboard is opened, it is passed a callback function to the IOHIDSystem for processing events. The callback is a static private function of IOHIDSystem, called _keyboardEvent:
success = ((IOHIKeyboard*)source)->open(this, kIOServiceSeize,0,
(KeyboardEventCallback) _keyboardEvent,
(KeyboardSpecialEventCallback) _keyboardSpecialEvent,
(UpdateEventFlagsCallback) _updateEventFlags);
The callback then calls keyboardEvent function in the IOHIDSystem instance:
self->keyboardEvent(eventType, flags, key, charCode, charSet,
origCharCode, origCharSet, keyboardType, repeat, ts, sender);
It does not call the ten parameter one, which is virtual (and which you are overriding). Instead, what is being called is the 11 parameter non-virtual one. So even if you tried to override the 11 parameter one, it would not work as the call never goes through the vtable.