Console.ReadLine and getqueuestr

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Console.ReadLine and getqueuestr

Post by sturgessb »

Hi Guys

Am I missing something or is it not possible to use Console.ReadLine on a com port other than Com1?

getqueuestr is not as useful in my application as I want to easily read complete lines terminated by LF.

Cheers

Ben
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Re: Console.ReadLine and getqueuestr

Post by mikep »

The console functions and Debug.Print are restricted to Com1 (the system queues) and are provided as a convenience. You will need to do your own parsing of the data on other COM ports.
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Console.ReadLine and getqueuestr

Post by dkinzer »

sturgessb wrote:I want to easily read complete lines terminated by LF.
The function shown below extracts characters from a queue and transfers them to a line accumulation queue. When a linefeed is transferred, the contents of the line accumulation queue is returned as a string and the accumulation queue is cleared. A zero length string is returned on all calls before the linefeed is seen. The downside of this method is that it incurs the additional storage for the line accumulation queue.

Code: Select all

Function GetQueueLine(ByRef iq() as Byte, ByRef lq() as Byte) as String
  GetQueueLine = ""
  Do While (StatusQueue(iq))
    Dim b as Byte
    Call GetQueue(iq, b, SizeOf(b))
    Call PutQueueByte(lq, b)
    If (b = &H0a) Then
      ' extract the accumulated line from the queue and clear it
      GetQueueLine = GetQueueStr(lq)
      Call ClearQueue(lq)
      Exit Do
    End If
  Loop
End Function
A second alternative is to use knowledge of the structure of a queue in order to detect when the queue contains a linefeed. The code below, written in C, returns the length of the first line in the queue or zero if the queue is empty or does not yet contain a linefeed. When the function returns a non-zero value, use that value as the second parameter to GetQueueStr() to extract the line from the queue.

Generally speaking, using code that is dependent on implementation details is not recommended. However, it is unlikely that the details of the queue implementation will change.

Code: Select all

#c
/*
 ** GetQueueLineLength
 *
 * This function returns the number of bytes up to and including
 * the first linefeed in a given queue.  If the queue is empty or
 * does not yet contain a linefeed, zero is returned.
 *
 * Interrupts are disable during the scanning process.
 *
 */
uint16_t
GetQueueLineLength(uint8_t *q)
{
  uint16_t len = 0;
  Queue *qp = (Queue *)q;
  if (qp != NULL)
  {
    uint8_t sreg = SREG;
    cli();
    uint16_t cnt = qp->cnt;
    uint16_t idx = qp->tail;
    while (cnt--)
    {
      if (++idx >= qp->cap)
        idx = 0;
      if (qp->queue[idx] == 0x0a)
      {
        // found a linefeed, compute line length
        len = qp->cnt - cnt;
        break;
      }
    }
    SREG = sreg;
  }
  return(len);
}
#endc

Declare Function GetQueueLineLength(ByRef q() as Byte) as UnsignedInteger
- Don Kinzer
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Thanks Don I will implement this.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Console.ReadLine and getqueuestr

Post by dkinzer »

sturgessb wrote:I want to easily read complete lines terminated by LF.
This topic got me to thinking that it might be useful to have a function that will search a queue for an arbitrary character, returning the "index" of the first occurrence. The API could be something like this:

Code: Select all

Function FindQueue(ByRef q() as Byte, ByVal val as Byte) as UnsignedInteger
A return value of zero would mean that the byte value is not present. Otherwise, the value would indicate how many bytes are in the queue up to and including the sought value. As with the example code in my earlier post, the return value could be used with GetQueueStr() or GetQueue() to retrieve the data preceding and or including the sought value.
- Don Kinzer
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

That would be very useful yes.
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Code: Select all

Function GetQueueLine(ByRef iq() as Byte, ByRef lq() as Byte) as String
  GetQueueLine = ""
  Do While (StatusQueue(iq))
  debug.print "1"
    Dim b as Byte
	debug.print "2"
    Call GetQueue(iq, b, SizeOf(b))
	debug.print "3"
    Call PutQueueByte(lq, b)
	debug.print "4"
    If (b = &H0a) Then
      ' extract the accumulated line from the queue and clear it
      GetQueueLine = GetQueueStr(lq)
      Call ClearQueue(lq)
      Exit Do
    End If
  Loop
End Function
Im running the function above, and its stopping at Call PutQueueByte(lq, b), any ideas why?

I know that 'b' has a value at that point and the lq queue exists

If I change it so that its saving the data into a string rather than a queue it works, odd.

Cheers

Ben
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

hmm when i said it worked with string i was jumping the gun a bit, here is the output.

Code: Select all

T,1,11.34

C,1412,1590,1522,1540,0,0,0,0
S,443,222,0,28,0
G,0,90.0,0.0,137.0,0,0,0




G,0,90.0,0.0,137.0,0,0,0
.34

C,1412,1590,1522,1540,0,0,0,0
,443,221,0,29,0
As you can see its bit of a mess, each line should begin with a letter, so it seems im missing data[/code]
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

sturgessb wrote:Im running the function above, and its stopping at Call PutQueueByte(lq, b), any ideas why?
My conjecture is that the queue you're attempting to insert into hasn't been initialized (using OpenQueue()).

Using a String is a good alternative, perhaps slightly slower.
- Don Kinzer
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

right you are!
Post Reply