complex struct

Discussion in 'C++' started by Larry, Jan 26, 2010.

  1. Larry

    Larry Guest

    Hi,

    I have those structs:

    const int numbuff = 3;

    struct buffer
    {
    unsigned char data[1024];
    int bytesRecorded;
    int user;
    buffer(const unsigned char * data_, const int bytesRecorded_, const int
    user_) :
    bytesRecorded(bytesRecorded_), user(user_)
    {
    copy(data_, data_ + bytesRecorded_, data);
    }
    };

    struct circular
    {
    circular_buffer<buffer> cb[numbuff];
    };

    // circular is an array of numbiff buffer(s).


    Now, I can't seem to access buffer's fields by circular anymore! All I can
    access is buffer constructor:

    circular c;

    c.cb->push_back(buffer(NULL, 0, 0)); // write or overwrite buffer

    If I were to read the last element from buffer how could I go about it?

    thanks
     
    Larry, Jan 26, 2010
    #1
    1. Advertising

  2. Larry

    John H. Guest

    On Jan 26, 10:18 am, "Larry" <> wrote:
    > struct buffer
    > {
    >  unsigned char data[1024];
    >  int bytesRecorded;
    >  buffer(const unsigned char * data_, const int bytesRecorded_, const int
    > user_);
    > };
    >
    > struct circular
    > {
    >  circular_buffer<buffer> cb[numbuff];
    >
    > };
    >
    > // circular is an array of numbiff buffer(s).


    More accurately, circular HAS an array. That array contains numbuff
    circular_buffers. Those circular_buffers are themselves containers
    that can contain buffers.

    > circular c;
    >
    > Now, I can't seem to access buffer's fields by circular anymore! All I can
    > access is buffer constructor:


    c; // gives you the circular object
    c.cb; // gives you the array of circular_buffers in c
    c.cb[0]; // gives you the first of the circular_buffers in the array
    in c
    c.cb[0][0]; // gives you the first of the buffers inside the first
    circular_buffer in the array in c
    c.cb[0][0].data // gives you the data of the first of the buffers
    inside the first circular_buffer in the array in c

    > If I were to read the last element from buffer how could I go about it?


    If you really ment "last element from buffer", perhaps you want to
    access the last byte in a buffer object's data member. If this is the
    case then:
    buffer buff(...);
    buff.data[1023];
    Perhaps you ment the last byte recorded to the buffer, then something
    like:
    buff.data[buffer.bytesRecorded-1];

    > c.cb->push_back(buffer(NULL, 0, 0));


    What you are doing here is taking your circular object named c,
    getting the array of circular_buffers named cb, then taking the first
    of those circular_buffers, and pushing back a buffer into it. This
    might be written more clearly as:
    c.cb[0].push_back(buffer(NULL, 0, 0));
    Neither of these statement will do anything because all of our
    circular_buffers in the array in c are of size 0.

    Since you didn't talk much about what you are trying to do, I can only
    speculate, but I am guessing that your design here is not doing what
    you want it to.
     
    John H., Jan 26, 2010
    #2
    1. Advertising

  3. Larry

    Larry Guest

    "John H." <> ha scritto nel messaggio
    news:...

    > Since you didn't talk much about what you are trying to do, I can only
    > speculate, but I am guessing that your design here is not doing what
    > you want it to.


    This is what I am tring to do: a tiny streaming server to stream to at least
    a couple of clients at the same time. (capturing from a given wave in
    device, mp3 encoding and streaming) for the moment I am coding the server
    part:

    #include <iostream>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <process.h>
    #include <cstdlib>
    #include <ctime>
    #include "socket.h"
    #include <boost/circular_buffer.hpp>
    using namespace std;
    using namespace boost;

    const string CRLF = "\r\n";
    const int numbuff = 3;
    const int buflen = 30;

    unsigned int __stdcall Consumer(void* sock);
    unsigned int __stdcall Producer(void*);

    void getDateTime(char * szTime);

    struct buffer
    {
    unsigned char data[1024];
    int bytesRecorded;
    int user;
    buffer(const unsigned char * data_, const int bytesRecorded_, const int
    user_) :
    bytesRecorded(bytesRecorded_), user(user_)
    {
    copy(data_, data_ + bytesRecorded_, data);
    }
    };

    struct circular
    {
    circular_buffer<buffer> cb[numbuff];
    circular_buffer<buffer>::const_iterator it;
    };

    map<int, circular> users;
    map<int, circular>::iterator uit;

    int main()
    {
    // Launch Producer
    unsigned int prodRet;
    _beginthreadex(0,0,Producer,NULL,0,&prodRet);
    if(prodRet)
    cout << "Launched Producer Thread!" << endl;

    // Set up server (port: 8000, maxconn: 10)
    SocketServer sockIn(8000, 10);

    while(1)
    {
    // ...wait for incoming connections...
    Socket* s = sockIn.Accept();
    unsigned int sockRet;
    _beginthreadex(0,0,Consumer,s,0,&sockRet);
    if(sockRet)
    cout << "Spawned a new thread!" << endl;
    else
    cout << "Thread error!" << endl;
    }

    sockIn.Close();

    system("pause");
    return EXIT_SUCCESS;
    }

    // Consumer
    unsigned int __stdcall Consumer(void* sock)
    {
    Socket* s = (Socket*) sock;

    s->SendBytes("Hello World!" + CRLF);

    int threadid = (int)GetCurrentThreadId();

    // Prepare & add circular buffer to the map
    circular c;
    c.cb->push_back(buffer(NULL,0,0));
    c.cb->push_back(buffer(NULL,0,0));
    c.cb->push_back(buffer(NULL,0,0));

    users.insert(make_pair(threadid, c));

    // TODO:
    // Read data from the buffer
    // and send it to the client
    Sleep(10000);

    // Remove buffer from the map
    users.erase(threadid);

    // Say bye to the client
    s->SendBytes("Bye bye!" + CRLF);

    // Disconnect client
    cout << "Closing thread..." << endl;
    s->Close();
    delete s;
    return 0;
    }

    // Producer
    unsigned int __stdcall Producer(void*)
    {
    while(1)
    {
    Sleep(1000);
    char szTime[30]; getDateTime(szTime);
    for(uit=users.begin(); uit!=users.end(); ++uit)
    {
    users[uit->first].cb->push_back(buffer((unsigned char*)szTime, 30, 1));
    cout << "Producer is writing to: " << uit->first << endl;
    }
    }
    return 0;
    }

    void getDateTime(char * szTime)
    {
    time_t rawtime = time(NULL);
    struct tm timeinfo;
    gmtime_s(&timeinfo, &rawtime);
    strftime(szTime, 30, "%a, %d %b %Y %X GMT", &timeinfo);
    }

    thanks
     
    Larry, Jan 26, 2010
    #3
  4. Larry

    Larry Guest

    "John H." <> ha scritto nel messaggio
    news:...

    > Since you didn't talk much about what you are trying to do, I can only
    > speculate, but I am guessing that your design here is not doing what
    > you want it to.


    anyway,before I was doing:

    struct buffer
    {
    char data[1024];
    int bytesRecorded;
    buffer(const char * data_, const int bytesRecorded_) :
    bytesRecorded(bytesRecorded_)
    {
    copy(data_, data_ + (bytesRecorded_ * sizeof(char)), data);
    }
    };

    int main()
    {
    circular_buffer<buffer> cb(numbuff);

    // Insert elements
    cout << "Push elements:" << endl;
    for(int i = 0; i < 10; i++)
    {
    char szTime[30]; getDateTime(szTime);

    cb.push_back( buffer(szTime, 30) );

    cout << szTime << endl;

    Sleep(1000);
    }

    // Show elements:
    cout << "Show elements:" << endl;
    for(int i = 0; i<(int)cb.size(); i++)
    {
    cout << &cb.data[0] << endl;
    }

    system("pause");
    return EXIT_SUCCESS;
    }

    that worked great! But now I needed to to something like:

    std::map<int, circular_buffer<buffer> cb(numbuff)> users

    which is impossible, that's why I thought I'd wrap up into another struct:

    struct circular
    {
    circular_buffer<buffer> cb[numbuff];
    };

    so that I should do:

    std::map<int, circular> users

    but that led me to some problems...
     
    Larry, Jan 26, 2010
    #4
  5. Larry

    Larry Guest

    "Yu Han" <> ha scritto nel messaggio
    news:hjo7uh$2rje$...

    > What you give is an object, not a type. only circular_buffer<buffer>
    > Again, you *must* use a pointer(i.e, circular_buffer<buffer>*), or your
    > application will not work!


    I read up a little better on boost::circular_buffer so I can now do like
    this:

    const int numbuff = 3;

    struct buffer
    {
    unsigned char data[1024];
    int bytesRecorded;
    int user;
    buffer(const unsigned char * data_, const int bytesRecorded_, const int
    user_) :
    bytesRecorded(bytesRecorded_), user(user_)
    {
    copy(data_, data_ + bytesRecorded_, data);
    }
    };

    struct circular
    {
    circular_buffer<buffer> cb;
    };

    int main()
    {
    map<int, circular> users;

    int regkey = 1000;

    circular k;
    k.cb.set_capacity(numbuff); // Finally!

    // Prepare buffer
    for(int i = 0; i<numbuff; i++)
    {
    k.cb.push_back(buffer(NULL,0,0));
    }

    // Add buffer
    k.cb.push_back(buffer((unsigned char*)"hellow world!", 15,1));
    k.cb.push_back(buffer((unsigned char*)"hellow world!", 15,2));
    k.cb.push_back(buffer((unsigned char*)"hellow world!", 15,3));

    // Push in the map
    users.insert(make_pair(regkey, k));

    // Show map: element regkey

    // First element
    cout << users[regkey].cb.at(0).user << endl; // 1

    // Last element
    cout << users[regkey].cb.at(numbuff-1).user << endl; // 3

    // Remove from map
    users.erase(regkey);
    }

    I cannot use std::string since I need to deal with binary data
     
    Larry, Jan 27, 2010
    #5
  6. Larry

    Larry Guest

    "Yannick Tremblay" <> ha scritto nel messaggio
    news:...

    > std::basic_string<unsigned char>
    > std::vector<unsigned char>
    >
    > std::basic_string<char>
    > std::vector<char>
    >
    > or typedef a "byte" type the way you prefer.
    >
    >
    > There is nothing in std::basic_string<> nor in std::string (which is
    > just std::basic_string<char>) that makes it unable to hold binary
    > data.
    >
    > Several people have been trying to recommend you to give up on writing
    > code that is so prone to buffer overflow and memory violations. C++
    > offers you tool to make life for yourself much easier.


    I am going to deal with chars form 0x00 to 0xFF mostly.I don't think the
    lastest code I have written (and posted above) is so prone to buffer
    overflow as well as memory violations.
     
    Larry, Jan 27, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. news.amnet.net.au
    Replies:
    1
    Views:
    597
    =?UTF-8?b?TMSByrtpZSBUZWNoaWU=?=
    Apr 13, 2004
  2. Stanimir Stamenkov
    Replies:
    2
    Views:
    774
    Stanimir Stamenkov
    Oct 25, 2005
  3. Chris Fogelklou
    Replies:
    36
    Views:
    1,433
    Chris Fogelklou
    Apr 20, 2004
  4. Robert Mark Bram
    Replies:
    0
    Views:
    709
    Robert Mark Bram
    Feb 4, 2007
  5. Kottiyath

    How complex is complex?

    Kottiyath, Mar 18, 2009, in forum: Python
    Replies:
    22
    Views:
    794
Loading...

Share This Page