home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.tar / ftp.whtech.com / club100 / ref / binary.doc < prev    next >
Text File  |  2006-10-19  |  4KB  |  76 lines

  1. _Using .DO files to store 8-bit binary data_ 
  2. by Tracy Allen, 5/8/89
  3. released through Club 100 to the public domain, except for for-profit
  4. publication.
  5. .
  6. I often need to store 8-bit data in .DO files on the M100/102/200.  This
  7. data comes from sensors (temperature, etc.) and takes on byte values in
  8. the range of 0 to 255.  If it is stored in its ascii form it takes a lot
  9. more room in memory than it does when it is stored in binary.  For
  10. example, a temperature of 212 degrees Celsius stored as ascii takes three
  11. bytes "2"  "1"  "2" plus a space or a tab to separate it from the next
  12. datum.  The same datum stored as binary takes only one byte, and no space
  13. or tab is needed, because _all_ data take only one byte with a binary
  14. range of 0 to 255.  It is efficient data compression.
  15. .
  16. The problem is that 5 out of the 256 possible byte values have special
  17. meaning to the M100/102/200.  These special ascii byte values are:   0
  18. (zero, null), 10 (line-feed), 13 (carriage return), 26 (end-of-file) and
  19. 127 (delete).  Of those, the the 0 or the 127 cannot be entered in a file
  20. using normal PRINT# statements.  The 26 means end-of-file and you will get
  21. an error message if you try to read past it using normal INPUT#
  22. statements, and the operating system sooner or later will zap anything
  23. that follows the 26.  The 10 and the 13 can be stored and retreived from
  24. the files, but carriage return and linefeed  have special significance to
  25. the LINEINPUT# statement.  I like to use LINEINPUT# to retrieve groups of
  26. readings.  I store groups of hourly readings on lines terminated by a
  27. carriage return, and doing so helps to maintain the integrity of the data
  28. should a reading happen to be lost.  The line-feed caharacter is special
  29. only because of a peculiarity of the LINEINPUT# command.  If line-feed
  30. precedes carriage-return, the LINEINPUT# command does not recognize the
  31. carriage-return as the end-of-line character and will instead read it in
  32. as data up to the next carriage return that is not preceded by line-feed. 
  33. Line-feeds that immediately follow a carriage return are treated as part
  34. of the end-of-line.  So you canUt have LF as part of data either directly
  35. before or directly after a CR.  
  36. .
  37. An approach that gets around this is to map the five special characters up
  38. to characters 251->255.  I can discard those high values, because the
  39. temperatures and other data never get so high:
  40. .               If D%>250 then D%=250
  41. .where D% is the datum to be stored.  Map the characters as follows:
  42. .               If D%=0 then D%=255
  43. .               If D%=10 then D%=254
  44. .               If D%=13 then D%=253
  45. .               If D%=26 then D%=252
  46. .               If D%=127 then D%=251
  47. At this point the data contain none of the offending characters.  Write it:
  48. .               PRINT#1,D%;
  49. And when it's time to end a line of data, put in a CR:
  50. .               PRINT#1,CHR$(13);
  51. That's it for storing the data.
  52.  
  53. Reading in the data is exactly the opposite process.  Let's say you want
  54. to send the data (TAB-delimitd) over the modem to another computer: 
  55. .              MAXFILES=2
  56. .              OPEN "DATA.DO" FOR INPUT AS 1
  57. .              OPEN "MDM:8N1E" FOR OUTPUT AS 2
  58. .LOOP:         IF EOF(1) THEN PRINT#2,CHR$(26):CLOSE:END
  59. .              LINEINPUT#1,A$
  60. .              FOR I=1 TO LEN(A$)
  61. .              D%=VAL(MID$(A$,I,1))          'get the I'th ascii chr in
  62. line
  63. .              IF D%=255 THEN D%=0           'reverse mapping
  64. .              IF D%=254 THEN D%=10
  65. .              IF D%=253 THEN D%=13
  66. .              IF D%=252 THEN D%=26
  67. .              IF D%=251 THEN D%=127
  68. .              PRINT#2,D%;
  69. .              IF I<LEN(A%) THEN PRINT#2,CHR$(9);      'TAB-delimit
  70. .              NEXT I
  71. .              GOTO LOOP
  72. .
  73. That's it!  -- Tracy
  74.  
  75.  
  76.