LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Good CVI programming approach for char buffer handling

Hi,
    I have rewritten the InetTelnetRunScript function so I can use it with multiple threads at the same time. Doing so I am using the same TelnetScript structure. I've implemented the read, one char at a time, in a while function. For each char I read I add it to a buffer and then search the buffer for a string to mach (expected reply from the server). In certain cases I can receive a huge quantity of data before finding the string to match. Obviously if I simply create an arbitrarily sized array I will eventually exceed that buffer and have a fatal error.

    What I want to do:
    So the plan is to have a fixed size buffer of 1024 char. So while the buffer is not full, I add the newly read char to the end of the buffer with the strcat function. Whenever my buffer is full, I want to remove the first char of the array (the oldest one), shift all the chars by one position in the array and add the newly read char to the end, again with strcat.

    So what I've done is:
In my while loop after each read:

                   if (strlen(readBuffer) >= (READBUFFERSIZE -1) )
                    {
                        strcpy (readBuffer, readBuffer + 1);
                    }
                   strcat(readBuffer, tempReadBuffer);

where readbuffersize is the size of readBuffer (obviously ;-))
tempReadBuffer has a size of 2 (char + terminating char)

What I am wondering is: Is it a good idea to do a strcpy of readBuffer+1 to readBuffer? Am I exposing myself to possible bugs?


Thanks!

Louis
0 Kudos
Message 1 of 9
(4,816 Views)

Tiwi,

From the Labwindows function panel for strcpy:

"This function copies a source string (including the terminating ASCII NUL byte) into a target string.  If copying takes place between objects that overlap, the behavior is undefined."

From what this says you are exposing yourself to bugs with the code posted above.

0 Kudos
Message 2 of 9
(4,810 Views)
Is there a simple alternative to this?
0 Kudos
Message 3 of 9
(4,808 Views)

Tiwi,

Give the following a try:


char readBuffer[READBUFFERSIZE], my_Temp_Buffer;

           if (strlen(readBuffer) >= (READBUFFERSIZE -1) )
                    {
                         for (index = 0; index < READBUFFERSIZE - 1; index ++)

                         {

                                  my_Temp_Buffer = readBuffer[index +1];

                                 readBuffer[index] = my_Temp_Buffer;

                         }

                     readBuffer[READBUFFERSIZE-1] = 0;

                   }

                         strcat(readBuffer, tempReadBuffer);  


               

Message Edited by DaveC on 07-28-2005 01:00 PM

0 Kudos
Message 4 of 9
(4,806 Views)
Great thanks!
0 Kudos
Message 5 of 9
(4,799 Views)

Alternatively you could use the CVI function CopyString(). This does allow source and target strings to overlap.

JR

0 Kudos
Message 6 of 9
(4,789 Views)

The behaviour is not undefined, it is perfectly understandable. Copying characters backwards works OK, copying them forwards does not work OK, as you're modifying characters that have yet to be copied. Consider the following:

char Test1[30] = "Hello, World";
char Test2[30] = "Hello, World";
char Test3[30] = "Hello, World";
 
strcpy (Test1, &Test1[2]);
strncpy(&Test2[2], Test2, 28);
strcpy (&Test3[2], Test3);

Test1 will be "llo, World"
Test2 will be "HeHeHeHeHeHeHeHeHeHeHeHeHeHeHe"
Test3 will cause a GPF, because an endless string is copied. 

The way you (the OP) considered making your code would work perfectly, since it copies the characters backwards.

 

You could also consider a sliding index pointer which points at the first character. Something like the following:

 

char readBuffer[1024] = "";
int BufPtr = 0;

void AddCharsToCircularBuf(char *Chars, int NrOfChars)
{  
 int i;

 for (i=0; i < NrOfChars; i++) {
  readBuffer[BufPtr++] = Chars[i];
  if (BufPtr == 1024) BufPtr = 0;
 }
 // after this loop BufPtr points BEHIND the last char
 // which is also the BEGINNING of the circular buffer.
}

When you use some kind of start character in the buffer, you could start reading at index BufPtr and scan the buffer for the start character, and copy all characters until BufPtr-1 in a same kind of loop (jumping back from 1023 to 0). Or, you could maintain 2 pointers, one for the starting position (which would be modified by the reading routine) and one for the ending position (modified by the writing routine).

0 Kudos
Message 7 of 9
(4,742 Views)
To make the circular buffer easier to work with I've made an example routine which will do the trick. This is far more flexible and economical than copying the same characters around all the time.
Message 8 of 9
(4,731 Views)
Thanks for sharing with us, it's a great idea!
0 Kudos
Message 9 of 9
(4,717 Views)