#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSharedMemory>
#include <QSystemSemaphore>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QSharedMemory *sharedMemory_;

private slots:
    void on_btnRead_clicked();
    void on_btnWrite_clicked();
};

#endif // MAINWINDOW_H




#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QImage>
#include <QBuffer>
#include <QDataStream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    sharedMemory_ = new QSharedMemory(this);
    sharedMemory_->setKey("HmiRunTime.MemoryMessageService");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btnRead_clicked()
{
    QSystemSemaphore semDo("HmiRunTime.MemoryMessageService.Semaphore.do", 0, QSystemSemaphore::Open);
    QSystemSemaphore semDone("HmiRunTime.MemoryMessageService.Semaphore.done", 0, QSystemSemaphore::Open);

    if(!sharedMemory_->isAttached()) {
        if (!sharedMemory_->attach()) {
            qDebug() << "1-Unable to attach to shared memory segment.";
            return;
        }
    }

    QBuffer outBuffer;
    outBuffer.open(QBuffer::ReadWrite);
    QDataStream out(&outBuffer);

    qint32 iOptCode = 2; // 1-write, 2-read
    out << iOptCode;

    QMap<QString, QString> dat;
    dat["sys.1"] = "";
    dat["sys.2"] = "";
    dat["sys.3"] = "";
    dat["sys.4"] = "";
    dat["sys.5"] = "";
    dat["sys.6"] = "";
    out << dat;

    int size = 8 * 1024;

    sharedMemory_->lock();
    char *to = (char*)sharedMemory_->data();
    const char *from = outBuffer.data().data();
    memcpy(to, from, qMin(sharedMemory_->size(), size));
    sharedMemory_->unlock();

    semDo.release(1);


    ///////////////////////////////////////////////////////////////////////////

    semDone.acquire();

    QBuffer readBuffer;
    QDataStream in(&readBuffer);

    sharedMemory_->lock();
    readBuffer.setData((char*)sharedMemory_->constData(), sharedMemory_->size());
    readBuffer.open(QBuffer::ReadWrite);

    iOptCode = 0;
    in >> iOptCode;

    QMap<QString, QString> dat2;
    in >> dat2;
    QList<QString> listId = dat2.keys();
    QString szVal = "";
    foreach(QString szId, listId) {
        szVal += QString("%1=%2").arg(szId).arg(dat2[szId]) + "\n";
    }

    qDebug() << "iOptCode: " << iOptCode << " szDat:" << szVal;

    ui->plainTextEdit->appendPlainText(QString::number(iOptCode) + ":" + szVal);

    sharedMemory_->unlock();
}

#if 0
bool QSharedMemory::detach()
Detaches the process from the shared memory segment.
If this was the last process attached to the shared memory segment,
then the shared memory segment is released by the system, i.e., the contents are destroyed.
The function returns true if it detaches the shared memory segment.
If it returns false, it usually means the segment either isn't attached, or it is locked by another process.
#endif

void MainWindow::on_btnWrite_clicked()
{
    static int iVal1 = 1;
    static int iVal2 = 11;

    QSystemSemaphore semDo("HmiRunTime.MemoryMessageService.Semaphore.do", 0, QSystemSemaphore::Open);
    //QSystemSemaphore semDone("HmiRunTime.MemoryMessageService.Semaphore.done", 0, QSystemSemaphore::Open);

    if(!sharedMemory_->isAttached()) {
        if (!sharedMemory_->attach()) {
            qDebug() << "1-Unable to attach to shared memory segment.";
            return;
        }
    }

    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);
    QDataStream out(&buffer);

    qint32 iOptCode = 1; // 1-write, 2-read
    out << iOptCode;

    QMap<QString, QString> dat;
    dat["io.group3.1"] = QString::number(iVal1);
    dat["io.group3.2"] = QString::number(iVal2);
    iVal1++;
    iVal2++;
    out << dat;

    int size = 8 * 1024;

    sharedMemory_->lock();
    char *to = (char*)sharedMemory_->data();
    const char *from = buffer.data().data();
    memcpy(to, from, qMin(sharedMemory_->size(), size));
    sharedMemory_->unlock();

    semDo.release(1);
}
