The best way of calculating and adding a block check character to a string
H J van Rooyen
mail at microcorp.co.za
Sun May 14 13:28:31 EDT 2006
Hi All
I am new to this language, and in using it to drive a serial port, I need to calculate classic block check characters - for the veterans amongst you - think "Burroughs Poll Select" or "Uniscope"...
This is a program fragment that puts the string in an array of Bytes - is there a better way to do this job? - the annotated action starts after the ascii definitions of the first 32 control characters...
# some ascii control character values defined
nul = '\x00' # null char
soh = '\x01' # start of header
stx = '\x02' # start of text
etx = '\x03' # end of text
eot = '\x04' # end of transmission
enq = '\x05' # enquiry
ack = '\x06' # ack
bel = '\x07' # bell char
bs = '\x08' # backspace
ht = '\x09' # horizontal tab
lf = '\x0a' # line feed - linux newline
vt = '\x0b' # vertical tab
ff = '\x0c' # form feed
cr = '\x0d' # carriage return
so = '\x0e' # shift out
si = '\x0f' # shift in
dle = '\x10' # data link escape
dc1 = '\x11' # data control 1 - aka xon
dc2 = '\x12' # data control 2
dc3 = '\x13' # data control 3 - aka xoff
dc4 = '\x14' # data control 4
nak = '\x15' # negative acknowledgement
syn = '\x16' # sync char
etb = '\x17' # end of transmission block
can = '\x18' # cancel
em = '\x19' # end of message
sub = '\x1a' # sub
esc = '\x1b' # escape
fs = '\x1c' # field separator
gs = '\x1d' # group separator
rs = '\x1e' # record separator
us = '\x1f' # unit separator
# some strings defined
poll = soh + 'P' + 'A' + stx + etx # rudimentary poll string
bcc = nul
# here starts the trouble:
ar = array.array('B', poll)
bccint = ar[0] # this is prolly dicey - what type and how big is this?
for x in ar[1:]:
bccint = bccint ^ x # this works, but is it the best way?
print repr(bccint)
ar.append(bccint)
# this seems so left-handed - we make a string, then we put it in an array,
# then we iterate over the array elements to calculate the
# bcc (block check character), then we add it to the array - then we should
# really make it all a string again to write it to the port...
# it would be nice to be able to write:
# nul = '\x00'
# bcc = nul
# poll = "some arbitrary string"
# bcc = bcc ^ (x for x in poll[0:]) # calculate and
# poll = poll + bcc # add the bcc to the string
# port.write(poll) # and write the lot to the port
# port.flush()
# and on the way in:
# numchars = 5 # some magic number depending on what we are expecting back
# response = port.read(numchars) # or a more complicated char at a time function
# bcc = nul
# bcc = bcc ^ (x for x in response[0:])
# if bcc != nul:
# error_routine(response)
# so we would stay working with strings - the stuff from the port
# coming in is a string, and we need a string to write again...
# *grin* but of course the xor and strong typing won't allow the
# string - to say nothing of the iterator...
# here is a loop, demonstrating getting an arbitrary lf terminated string in,
# and writing the fixed one with a bcc tagged on out as a response, along
# with some debug printing.
s = esc + '@' + esc + 'v' + lf # the line we are searching for
while True:
try:
buffer = port.readline() # read in as a string, (unblocked)
except KeyboardInterrupt:
print "\n^C - Returning to Shell - Error is:", KeyboardInterrupt
ret_val = 1 # ^C while waiting for input
return buffer, ret_val # go out on error
except IOError:
continue # IOError on input - no record available
if buffer == '': # empty string is rubbish - ignore it
continue
rawfile.write(buffer) # Keep the record as read
print repr(buffer) # show how python sees it
print repr(s) # show what our target looks like
if s == buffer:
print 'Bingo !!!'
ar.tofile(port) # luckily there is this method,
port.flush() # so we don't have to convert back to string...
This lot was cut and pasted from the little test program I am using to debug the port stuff - there may be tab issues - the question I suppose has to do with the types that the xor supports, and I suppose I am saying that it would be nice if a single byte string (also from an iterator) would be supported by the xor operator... ( maybe a single char string...there's a difference between ascii and unicode...)
As my program stands it works, but it seems long - winded and ugly....
- Hendrik van Rooyen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20060514/ea17ecff/attachment.html>
More information about the Python-list
mailing list