Appending a pointer to a Qlist - c++

this is my first post here!
I'm working on a code that parses Json to fill a struct that I append to a Qlist of tests to run.
My problem is with the payload inside my struct: when I send the first object in my list the payload it is not empty when it should be.
struct FrameTest {
QString protocol;
QString Length;
QByteArray *payload;
};
QList<FrameTest> _validTestLists;
FrameTest TxFrame;
Code of the JSON parser
void Cesa::JsonParser(QJsonObject _ScriptTestObject)
{
TxFrame.protocol = "00";
TxFrame.Length = "00";
TxFrame.payload = new QByteArray();
for(QJsonObject::iterator it = _ScriptTestObject.begin(); it!=_ScriptTestObject.end(); ++it)
{
TxFrame.protocol= "00";
TxFrame.Length = "00";
TxFrame.payload->clear();
_CmdObject = _ScriptTestObject.value(key).toObject(); // Get Json object
if (_CmdObject.contains("Board") && _CmdObject.value("Board") == "Exia")
{
QString payload;
TxFrame.protocol= "03";
TxFrame.Length = "06";
payload = QString("%1").arg(obj.value("hopPeriod").toInt(), 2, 16, QChar('0'));
}
else if (_CmdObject.contains("Board") && _CmdObject.value("Board") == "Cevee")
{
TxFrame.protocol= "03";
TxFrame.Length = "06";
}
_testLists.append(TxFrame);
}
Test(_testLists); // Test with only one object
Function for sending via port COM
bool Cesa::Test(FrameTest frame)
{
QByteArray txFrame;
/* Transmit command */
txFrame.insert(0, frame.protocol);
txFrame.insert(2, frame.Length);
txFrame.insert(4, *frame.payload);
_comPort->write(QByteArray::fromHex(txFrame));
}
I'm a student still learning coding, any help and advice will be appreciated :)

Related

Send HttpRequestMessage in C++, Windows API UWP

This is not C++/CLI. This is UWP C++/CX
I am trying to send an HttpRequestMessage outside of a managed class in C++. I looked at the UWP samples, but their requests occur inside of a managed class.
All I want to do is send the request, and then have a callback function. I don't need fancy async/await patterns. This is looking to be a lot more difficult than it should be.
EDIT: I have gotten it to work, but the error handling is atrocious. The extra error handling code from the UWP HttpClient example was not compiling.
client = ref new Windows::Web::Http::HttpClient();
client->DefaultRequestHeaders->UserAgent->Append(ref new Windows::Web::Http::Headers::HttpProductInfoHeaderValue("Windows", "10"));
cancellation_token_source cancellationTokenSource = cancellation_token_source();
create_task(client->SendRequestAsync(message)).then([=](Windows::Web::Http::HttpResponseMessage^ response)
{
auto operation = response->Content->ReadAsBufferAsync();
auto task = create_task(operation);
if (task.wait() == task_status::completed)
{
webResponse->statusCode = (int)response->StatusCode;
auto buffer = task.get();
size_t length = buffer->Length;
if (length > 0)
{
Array<byte>^ array = nullptr;
CryptographicBuffer::CopyToByteArray(buffer, &array);
webResponse->contentLength = array->Length;
webResponse->data = (byte*)malloc(webResponse->contentLength);
memcpy(webResponse->data, array->Data, webResponse->contentLength);
delete array;
}
for each(IKeyValuePair<String^, String^>^ pair in response->Headers)
{
std::string key = PlatformStringToString(pair->Key);
std::string value = PlatformStringToString(pair->Value);
if (key == "Content-Type" && false)
{
// Should have this for completeness, but do we really care?
}
else
{
Web::WebHeader *header = new Web::WebHeader(key.c_str(), value.c_str());
webResponse->AddHeader(header);
}
}
if (request->receiveDoneCallback)
request->receiveDoneCallback(webResponse, request->userPtr);
}
else
abort();
delete request;
delete response;
});

How save in an array the following 100 received value after a determined received string in Qt

I'm a newbie in C++ and Qt. I want to save in an array the value received in a serialport after I received the string: "Data".
I'm using the terminal example so the serialport works properly.
The read function in the Example is the same:
void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
}
How can I modify it? thanks!!!
If your manual sending the data i recommend you add a start of frame delimiter and an end of frame delimiter and checksum preferably.
QByteArray packet_storage;
just declare it the where you declare serial.
StartOfMessage and EndOfMessage will depend on your device.
I don't know what your transmitting. Hopefully you can figure out from the documentation of your device what your sending out.
as for me i am using
enum Constants
{
StartOfMessage = '\x02', /* Value of byte that marks the start of a message */
EndOfMessage = '\x03', /* Value of byte that marks the end of a message */
CarridgeReturn = '\x0D', /* Carridge return is first byte of end of line */
LineFeed = '\x0A', /* Line feed is second byte of end of line */
NullChar = '\0' /* Null Character */
};
void MainWindow::readData()
{
// read all
QByteArray data = serial->readAll();
// store all read data packet_storage is a QByteArray
packet_storage.append(data);
int start_index = 0;
int end_index = 0;
// process packet if not empty
if(!packet_storage.isEmpty())
{
if( packet_storage.contains(StartOfMessage) && packet_storage.contains(EndOfMessage))
{
start_index = packet_storage.indexOf(StartOfMessage,0);
end_index = packet_storage.indexOf(EndOfMessage,0);
int length = 0;
for (int i=start_index; i <= end_index; i++)
{
length++;
}
// get data
QByteArray dt = packet_storage.mid(start_index,length);
// do your processing here.
// store in vector write to file etc.
processpacket(dt);
packet_storage.remove(start_index,dt.size());
}
}
}

How to pass an array of integers as a property value in the Configuration object for MapReduce?

We can pass an integer as a Configuration property as below:
Configuration conf = new Configuration();
conf.set("size", 4);
Is there a way to send an array of integers as a property value?
conf.set("list.of.nums", {2, 4, 6, 8}); // one way is to pass them as a String but it doesn't look good
You can serialize the array object into a file and then move the file to HDFS.Then you can add the hdfs file path to Distributed cache using following.
DistributedCache.addCacheFile(new URI(dfsMetaPath + "#"
+ Constants.OBJSYMLINK0), conf);
DistributedCache.createSymlink(conf);
Serialization can be done as follows:-
public static <T> void serializeMetadata(T voObj,
String filePath) throws IOException,NullPointerException {
if(null==voObj){
throw new NullPointerException("NULL object found");
}
ObjectOutputStream oout = null;
FileOutputStream fsout = null;
try {
fsout = new FileOutputStream(filePath);
oout = new ObjectOutputStream(fsout);
oout.writeObject(voObj);
oout.close();
} finally {
if (null != fsout) {
fsout.close();
}
if (null != oout) {
oout.close();
}
}
}
You can use the filepath passed as arguments to the above method.Using this filepath you can move the file to HDFS filepath. Use the HDFS filepath to create the symlink.
To retireve in mapper you can use the following inside setup to get the object back.
File hdfsfilepath = new File(Constants.OBJSYMLINK0);
Integer[] youarray = MetadataSerDeUtils.deserializeMetadata(youarray ,
hdfsfilepath.getAbsolutePath());
For deserialization you can use following code:-
public static <T> T deserializeMetadata(T voObj,
String filePath) throws IOException,NullPointerException, ClassNotFoundException {
FileInputStream fsin = null;
ObjectInputStream oin = null;
try {
fsin = new FileInputStream(filePath);
oin = new ObjectInputStream(fsin);
voObj = (T) oin.readObject();
return voObj;
} finally {
if (null != fsin) {
fsin.close();
}
if (null != oin) {
oin.close();
}
}
}

TTS over web-service in compressed format

I have developed TTS engine in .NET. Now I want to expose it over web.
I have used the base64 string encoding to transfer the WAV format, but it is slow when I pass longer text.
Now I'm considering to build some MP3 streaming (maybe with NAudio) where I will convert the WAV formated MemoryStream into MP3 stream and pass it to the client. Does anyone has some experience with this?
Does anyone has experience how to convert WAV MemoryStream with NAudio to MP3 MemoryStream?
public class MP3StreamingPanel2 : UserControl
{
enum StreamingPlaybackState
{
Stopped,
Playing,
Buffering,
Paused
}
private BufferedWaveProvider bufferedWaveProvider;
private IWavePlayer waveOut;
private volatile StreamingPlaybackState playbackState;
private volatile bool fullyDownloaded;
private HttpWebRequest webRequest;
public void StreamMP32(string url)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
SettingsSection section = (SettingsSection)config.GetSection("system.net/settings");
section.HttpWebRequest.UseUnsafeHeaderParsing = true;
config.Save();
this.fullyDownloaded = false;
webRequest = (HttpWebRequest)WebRequest.Create(url);
int metaInt = 0; // blocksize of mp3 data
webRequest.Headers.Clear();
webRequest.Headers.Add("GET", "/ HTTP/1.0");
// needed to receive metadata informations
webRequest.Headers.Add("Icy-MetaData", "1");
webRequest.UserAgent = "WinampMPEG/5.09";
HttpWebResponse resp = null;
try
{
resp = (HttpWebResponse)webRequest.GetResponse();
}
catch (WebException e)
{
if (e.Status != WebExceptionStatus.RequestCanceled)
{
//ShowError(e.Message);
}
return;
}
byte[] buffer = new byte[16384 * 4]; // needs to be big enough to hold a decompressed frame
try
{
// read blocksize to find metadata block
metaInt = Convert.ToInt32(resp.GetResponseHeader("icy-metaint"));
}
catch
{
}
IMp3FrameDecompressor decompressor = null;
try
{
using (var responseStream = resp.GetResponseStream())
{
var readFullyStream = new ReadFullyStream(responseStream);
readFullyStream.metaInt = metaInt;
do
{
if (bufferedWaveProvider != null && bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
{
Debug.WriteLine("Buffer getting full, taking a break");
Thread.Sleep(500);
}
else
{
Mp3Frame frame = null;
try
{
frame = Mp3Frame.LoadFromStream(readFullyStream, true);
}
catch (EndOfStreamException)
{
this.fullyDownloaded = true;
// reached the end of the MP3 file / stream
break;
}
catch (WebException)
{
// probably we have aborted download from the GUI thread
break;
}
if (decompressor == null)
{
// don't think these details matter too much - just help ACM select the right codec
// however, the buffered provider doesn't know what sample rate it is working at
// until we have a frame
WaveFormat waveFormat = new Mp3WaveFormat(frame.SampleRate, frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frame.FrameLength, frame.BitRate);
decompressor = new AcmMp3FrameDecompressor(waveFormat);
this.bufferedWaveProvider = new BufferedWaveProvider(decompressor.OutputFormat);
this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // allow us to get well ahead of ourselves
//this.bufferedWaveProvider.BufferedDuration = 250;
}
int decompressed = decompressor.DecompressFrame(frame, buffer, 0);
//Debug.WriteLine(String.Format("Decompressed a frame {0}", decompressed));
bufferedWaveProvider.AddSamples(buffer, 0, decompressed);
}
} while (playbackState != StreamingPlaybackState.Stopped);
Debug.WriteLine("Exiting");
// was doing this in a finally block, but for some reason
// we are hanging on response stream .Dispose so never get there
decompressor.Dispose();
}
}
finally
{
if (decompressor != null)
{
decompressor.Dispose();
}
}
}
}
NAudio does not include an MP3 encoder. When I need to encode MP3 I use lame.exe. If you don't want to go via a file, lame.exe allows you to read from stdin and write to stdout, so if you redirect standard in and out on the process you can convert on the fly.

How to write and read Stream using indy 10.5.5 c++

Hi I have try to read Stream from the server with this code
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, wchar_t &Key)
{
//TMemoryStream *TMS = new TMemoryStream;
TStringStream *TSS = new TStringStream;
AnsiString A,B;
TStream *TS;
INT64 Len;
try
{
if (Key == VK_RETURN)
{
Beep(0,0);
if(Edit1->Text == "mystream")
{
TCPClient1->IOHandler->WriteLn("mystream");
Len = StrToInt(TCPClient1->IOHandler->ReadLn());
TCPClient1->IOHandler->ReadStream(TS,Len,false);
TSS->CopyFrom(TS,0);
RichEdit1->Lines->Text = TSS->DataString;
Edit1->Clear();
}
else
{
TCPClient1->IOHandler->WriteLn(Edit1->Text);
A = TCPClient1->IOHandler->ReadLn();
RichEdit1->Lines->Add(A);
Edit1->Clear();
}
}
}
__finally
{
TSS->Free();
}
}
and every times client try to read stream from the server, compiler says.
First chance exception at $75D89617. Exception class EAccessViolation with message 'Access violation at address 500682B3 in module 'rtl140.bpl'. Read of address 00000018'. Process Project1.exe (6056)
How to handle this?
You are not instantiating your TStream object before calling ReadStream(). Your TS variable is completely uninitialized. ReadStream() does not create the TStream object for you, only writes to it, so you have to create the TStream yourself beforehand.
Given the code you have shown, you can replace the TStream completely by using the ReadString() method instead:
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, wchar_t &Key)
{
if (Key == VK_RETURN)
{
Beep(0,0);
if (Edit1->Text == "mystream")
{
TCPClient1->IOHandler->WriteLn("mystream");
int Len = StrToInt(TCPClient1->IOHandler->ReadLn());
RichEdit1->Lines->Text = TCPClient1->IOHandler->ReadString(Len);
}
else
{
TCPClient1->IOHandler->WriteLn(Edit1->Text);
String A = TCPClient1->IOHandler->ReadLn();
RichEdit1->Lines->Add(A);
}
Edit1->Clear();
}
}