Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QQueue to QByteArray? C# to C++
Forum Updated to NodeBB v4.3 + New Features

QQueue to QByteArray? C# to C++

Scheduled Pinned Locked Moved General and Desktop
21 Posts 4 Posters 14.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    giesbert
    wrote on last edited by
    #9

    Hi,
    perhaps you should think of the class you want to use. QQueue is a QLIst and QList is a linked list.
    But it seams you want to use arrays, so QVector, QBuffer or QByteArray would fit better.

    My first question would be:

    Why do you use a Queue? Only because you uise it in C#?

    If you need a QByteArray for the interfaces / classes you are using, then fill the data into a QByteArray in the for each loop.

    Nokia Certified Qt Specialist.
    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

    1 Reply Last reply
    0
    • A Offline
      A Offline
      azkay
      wrote on last edited by
      #10

      [quote author="Gerolf" date="1302352548"]Hi,
      perhaps you should think of the class you want to use. QQueue is a QLIst and QList is a linked list.
      But it seams you want to use arrays, so QVector, QBuffer or QByteArray would fit better.

      My first question would be:

      Why do you use a Queue? Only because you uise it in C#?

      If you need a QByteArray for the interfaces / classes you are using, then fill the data into a QByteArray in the for each loop.[/quote]

      Yeah, the only reason I was using Queue was because I used it in C#.
      Though, I think ive got this working, I used std::stringstream instead of QQueue, seems to be working.

      1 Reply Last reply
      0
      • G Offline
        G Offline
        goetz
        wrote on last edited by
        #11

        Ah, ok. Sorry - you did not mention that lacking experience in C++, that explains a lot. And I'm sorry if my first answers sounded a bit rude. It was not my intention to expel you out of the Qt world :-)

        You might consider working on a C++ tutorial first, it's sometimes easier to learn the simple things (templates, see below) with simple examples :-)

        Regarding your actual problem:

        As you're from a C# background, I might assume your kind of familiar with inheritance and subclassing?

        QQueue is a subclass of QList. So QQueue basically is a QList with some additional methods. Both are so called template classes (metaprogramming in other languages, I don't know if C# has a similar construct), which take a type parameter if you want to create an instance of them. This way you write the code only once, and can use it with different types and can create lists (or queues) of ints, doubles, strings or whatever object else you have (including your own object types of course).

        The rationale behind there is no "toArray" method in the list/queue is simple: as you can put in so different classes, there is simply no general way to represent these classes as a byte array. So you will have to iterate over the contents of the list/queue convert the contents into a byte array and append this to another byte array.

        As you use a byte type (char) to your queue it seems to be logical to have a toArray method that returns a QByteArray. But as you now know, QList would have to handle any arbitrary complex object type to be converted to a byte array - that's the showstopper here.

        A QBuffer is basically a QByteArray which can be treated like a file (you have read/write/append/seek methods).

        So, if you have a QQueue of bytes, you need to append them to the byte array/buffer one bye one:

        @
        QQueue<char> inputQueue = methodToFillTheQueue();
        QBuffer buffer;
        foreach(char b, inputQueue) {
        buffer.append(b);
        }
        QByteArray ba = buffer.data();
        @

        This is what your code does. The question is now, do you need the additional methods of the queue (pull from the start of the list, append to the end) and of the buffer (file I/O like methods like read, write). If you do, the queue is not emptied upen the conversion process and you might consider this snippet:

        @
        QQueue<char> inputQueue = methodToFillTheQueue();
        QBuffer buffer;
        while(!inputQueue.isEmpty()) {
        // get the first entry, remove it from the queue
        // and append it to the buffer
        buffer.append(inputQueue.dequeue());
        }
        QByteArray ba = buffer.data();
        @

        But I suppose this is not the case, so the above code could be changed to this:

        @
        QList<char> inputList = methodToFillTheQueue();
        QByteArray buffer;
        foreach(char b, inputList) {
        buffer.append(b);
        }
        @

        You can of course mix the queue with the buffer replaces by a QByteArray directly or vice versa.

        In the end, you have a byte array that you can hand over to the QTcpSocket's write method.

        Please feel free to ask further questions if you need advice on which class to use in your use case.

        http://www.catb.org/~esr/faqs/smart-questions.html

        1 Reply Last reply
        0
        • G Offline
          G Offline
          goetz
          wrote on last edited by
          #12

          [quote author="azkay" date="1302352827"]Yeah, the only reason I was using Queue was because I used it in C#.
          Though, I think ive got this working, I used std::stringstream instead of QQueue, seems to be working.
          [/quote]

          Can you give us some more hints on what types you work on (you mentioned bytes and strings), we can point you to some convenient Qt classes then - there's almost everything here :-)

          http://www.catb.org/~esr/faqs/smart-questions.html

          1 Reply Last reply
          0
          • A Offline
            A Offline
            azkay
            wrote on last edited by
            #13

            What ive done seems to not be working either.
            Maybe itll be easier if I give you everything ive done so far;
            Also, sorry for sounding too bad, been working on this for hours and its getting frustrated.
            Ive coded in lots of different languages, but everytime I try to learn C++ again, I end up doing it for a couple of days, getting annoyed and moving on for a few months, always coming back, though.

            I thought using the stringstream would fix it, but I guess not.
            What im doing is, using "Smartcam":http://sourceforge.net/projects/smartcam/files/smartcam_windows/SmartCam_v1_4/ as the server, I coded up a "client":http://talk.maemo.org/showthread.php?t=71452 for the Nokia N900 (in C#) to stream the N900s camera to it.
            People suggested I learn some C++ and try to port it over, to save having to install all the mono libs on the n900 just to run it.

            So thats the background.
            This part of the code is what im trying to port over, which is basically the "heart" of it.
            It encodes the jpeg with the smartcam headers, then sends them to the smartcam server.
            Biggest problem has been trying to get a BitConverter.GetBytes() equivalent, which in the c++ code is sort of working/sort of broken, most probably very wrong but its the closest I got while getting annoyed at it all.

            C#: http://pastebin.com/EqxKk4H0
            C++: http://pastebin.com/XW8WPZH0

            If im making no sense, sorry.

            1 Reply Last reply
            0
            • G Offline
              G Offline
              goetz
              wrote on last edited by
              #14

              Thanks for the detailed infos. What you want to achieve should be easy in Qt. I'll have a look at it later and will come back with some sample code for you. I just need to do some gardening first ;-)

              I can understand that you are frustrated. C++ is a very powerful tool with the cost that you can easily shoot you in the foot. Maybe it's a bit hard to learn both C++ and the use of some 3rdparty libraray together with the more advanced parts of Qt (say networking for example) all in one step :)

              http://www.catb.org/~esr/faqs/smart-questions.html

              1 Reply Last reply
              0
              • G Offline
                G Offline
                goetz
                wrote on last edited by
                #15

                Unfortunately, the pastebin files are no longer available, can you please paste the code here. I have some solution at hand but want to check that it actually fits the original C# algorithms.

                http://www.catb.org/~esr/faqs/smart-questions.html

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  azkay
                  wrote on last edited by
                  #16

                  Sorry, here:
                  @
                  using System;
                  using System.IO;
                  using System.Collections.Generic;

                  namespace enqueue{
                  class MainClass {
                  public static void Main (string[] args){
                  Queue<byte> _buffer = new Queue<byte>();
                  byte[] _fileData = File.ReadAllBytes("test.jpg");
                  byte[] _tmpSize = BitConverter.GetBytes(_fileData.length());

                          _buffer.Enqueue(1);
                          _buffer.Enqueue(_tmpSize[2]);
                          _buffer.Enqueue(_tmpSize[1]);
                          _buffer.Enqueue(_tmpSize[0]);
                  
                          foreach(byte _b in _fileData){
                              _buffer.Enqueue(_b);
                          }
                  
                          byte[] _packet = _buffer.ToArray();
                          //tcp sending would be here
                      }
                  }
                  

                  }
                  @

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    giesbert
                    wrote on last edited by
                    #17

                    Hi azkay,

                    a possible Qt code for you C# would be this:

                    @
                    #include <QtCore/QBuffer>
                    #include <QtCore/QFile>

                    int foo()
                    {
                    QFile file("test.jpg");
                    if(file.open(QFile::ReadOnly))
                    {
                    QByteArray _fileData = file.readAll();
                    QByteArray _buffer;
                    qint32 nLength = _fileData.length();

                        _buffer.append(1);
                        // this doies the same a C# BitConverter.GetBytes(_fileData.length()); and then adding array[2], array[1] array[0]
                        _buffer.append((nLength >> 16) & 0xFF);
                        _buffer.append((nLength >> 8) & 0xFF);
                        _buffer.append(nLength & 0xFF);
                        _buffer.append(_fileData);
                         
                        //tcp sending would be here
                    }
                    

                    }
                    @

                    The only tricky thing is converting the result of this:

                    @
                    BitConverter.GetBytes(_fileData.length());
                    @

                    Instead of having two byte arrays, you could also work with only one:

                    @
                    #include <QtCore/QBuffer>
                    #include <QtCore/QFile>

                    int foo()
                    {
                    QFile file("test.jpg");
                    if(file.open(QFile::ReadOnly))
                    {
                    QByteArray _buffer = file.readAll();
                    qint32 nLength = _buffer.length();

                        // this does the same a C# BitConverter.GetBytes(_fileData.length()); and then adding array[2], array[1] array[0]
                        _buffer.prepend(nLength & 0xFF);
                        _buffer.prepend((nLength >> 8) & 0xFF);
                        _buffer.prepend((nLength >> 16) & 0xFF);
                        _buffer.prepend(1);
                        
                        //tcp sending would be here
                    }
                    

                    }
                    @

                    Nokia Certified Qt Specialist.
                    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      azkay
                      wrote on last edited by
                      #18

                      That is amazing, thank you all so much.

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        goetz
                        wrote on last edited by
                        #19

                        Prepending data on a QByteArray is a costly operation, as the content of the existing byte array must be copied.

                        As you will eventually send the data via a QTcpSocket, there is no need to buffer the data in a QByteArray. Just do some sanity checks (file.length() must not be greater than 2^24 = 256256256 = 16777216) and the write the data directly to the socket:

                        @
                        QFile file("test.jpg");
                        qint64 fileSize = file.size();

                        // 3 bytes = 24 bits:
                        // 2^24 = 256256256 = 16777216
                        if(fileSize > 16777216) {
                        qDebug() << "file too big";
                        return;
                        }

                        if(!file.open(QFile::ReadOnly)) {
                        qDebug() << "file cannot be opened";
                        return;
                        }

                        QByteArray fileContents = file.readAll();
                        file.close();

                        _tcpSocket.write(1); // the type
                        _tcpSocket.write((fileSize >> 16) & 0xFF);
                        _tcpSocket.write((fileSize >> 8) & 0xFF);
                        _tcpSocket.write(fileSize & 0xFF);
                        _tcpSocket.write(fileContents);
                        @

                        http://www.catb.org/~esr/faqs/smart-questions.html

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          giesbert
                          wrote on last edited by
                          #20

                          Ok, that's better, you are right.
                          I left out the socket part and thought, if you want to post process it, the it would be better top have the content in the array.

                          you could also first put the first 4 bytes in and then append the file content , but that also copies the content around...

                          And perhaps you want to put the tcp stuff in a separate function....

                          Nokia Certified Qt Specialist.
                          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            azkay
                            wrote on last edited by
                            #21

                            Thanks again, ive successfully (after a few more issues that I sorted out) gotten it to stream from my phones camera to the smartcam server.

                            Next step, making the GUI. Once all the bugs are fixed, step after that will be looking at recoding my own smartcam server/webcam filter to support higher resolutions and maybe other things, which I have a feeling will be a lot more trouble than this was.

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved