home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 339.lha / requester.library_v1.5 / BasicFileIO (.txt) < prev    next >
AmigaBASIC Source Code  |  1990-01-24  |  15KB  |  332 lines

  1.  'As you probably already know; AmigaBasic SUCKS! It can't handle structures.
  2.  'Yet another shoddy Microsoft product. Actually, this is about the fifth
  3.  'basic program I've ever written. The other four were done in a 15 week
  4.  'course some years back in college. I'm an assembly programmer, and usually
  5.  'I don't touch this crap, but someone had to write an example. The code is
  6.  'probably not too efficient, but it's the first basic program I've written
  7.  'in years, the first in AmigaBasic, and was done in about 2 hours (I had to
  8.  'read the AmigaBasic instruction book. Really.) I cannot begin to tell you
  9.  'how excruciating the AmigaBasic editor is to an assembly programmer.
  10.  
  11.  CLS
  12.  LOCATE 1,8
  13.  PRINT "Demo AmigaBasic program using the FileIO requester library."
  14.  LOCATE 2,11
  15.  PRINT "Literally hacked together by Jeff Glatt (dissidents)"
  16.  
  17.  DEFLNG a-Z  'IMPORTANT! All variables are longs (for the library calls)
  18.  
  19.  'requester.bmap and exec.bmap must be in the current directory
  20.  LIBRARY "requester.library"
  21.  LIBRARY "exec.library"
  22.  
  23.  DECLARE FUNCTION AllocMem() LIBRARY
  24.  
  25.  DECLARE FUNCTION DoFileIOWindow() LIBRARY  'These are in the FileIO lib.
  26.  DECLARE FUNCTION GetFullPathname() LIBRARY 'Other functions in the lib do
  27.  DECLARE FUNCTION GetFileIO() LIBRARY       'not return values, and so do not
  28.  DECLARE FUNCTION AutoFileMessage() LIBRARY 'need declaring
  29.  DECLARE FUNCTION AutoPrompt3() LIBRARY
  30.  DECLARE FUNCTION TypeFilename() LIBRARY
  31.  DECLARE FUNCTION UserEntry() LIBRARY
  32.  DECLARE FUNCTION PromptUserEntry() LIBRARY
  33.  DECLARE FUNCTION GetRawkey() LIBRARY
  34.  DECLARE FUNCTION DecodeRawkey() LIBRARY
  35.  
  36.  'First we must get a buffer for the pathname. The FileIO's DoFileIOWindow()
  37.  'will copy the complete pathname there. The complete path looks just like
  38.  'a CLI line:
  39.  
  40.  '  Diskname:TopDrawer/SubDrawer...etc...BottomDrawer/Filename
  41.  
  42.  'Of course, the user may only select a disk or drawer, but no filename, and
  43.  'so the final "/Filename" will not be there. Also, the Filename might not
  44.  'be in any drawers, and so it will appear directly after the diskname. If
  45.  'this format looks weird to you, you need to learn about the CLI.
  46.  'We'll get our buffer from Exec via AllocMem(). 
  47.   
  48.  MEMF.PUBLIC = 1 : MEMF.CLEAR = 65536 : BUFSIZE = 194
  49.  BufferPtr=AllocMem(BUFSIZE,MEMF.PUBLIC+MEMF.CLEAR) 'A buffer to copy the pathname to
  50.  IF BufferPtr = 0 THEN GOTO CloseUp 
  51.  
  52.  FileIO=GetFileIO(0)  'Get the address of the FileIO structure
  53.                        'Actually you don't need to pass the 0, but AmigaBasic seems to want something...
  54.  
  55.  IF FileIO = 0 THEN GOTO CloseUp1 '0 means that you don't have a FileIO.
  56.  
  57.  'Set the FileIO's Buffer field to our allocated PathBuffer's address
  58.  POKEL FileIO+248,BufferPtr
  59.  
  60.  'Set the title that will displayed in the FileIO window. This can be changed
  61.  'for each call so that you might have the title read "Save File" during a
  62.  'save routine, for example.
  63.  
  64.  WindowTitle$ = "FileIO Basic Example"
  65.  POKEL FileIO+244,SADD(WindowTitle$)
  66.  
  67.  'Set the fore pen, back pen, and draw mode for title bar routines to some
  68.  'defaults. We always need to do this in case the requester is in use by
  69.  'another program and we get automatic title bar file entry. To demo this,
  70.  'run this program twice simultaneously with one of them having the file
  71.  'requester displayed. Note that the title bar entry appears in the 2nd
  72.  'window. This is because only 1 task can be displaying the FileIO requester
  73.  'at a time. Other simultaneous calls get redirected to the title bar entry.
  74.  
  75.  POKE  FileIO+261,1  'JAM2 DrawMode
  76.  POKE  FileIO+262,1  'PenA = Color1
  77.  POKE  FileIO+263,0  'PenB = Color0
  78.  DIM   Pathname$(192)
  79.  DIM   Filename$(64)
  80.  DIM   VolName$(64)
  81.  DIM   DrawerName$(64)
  82.   
  83. Again:
  84.  
  85.  'First I'll demo 2 things you can do with the Flags field of the FileIO. The
  86.  'FileIO is a structure, and our variable name FileIO is just the start (base)
  87.  'of that structure (block of memory). We can access any field of the FileIO
  88.  'by PEEKing and POKEing various fields. You should POKE a value into the
  89.  'FileIO, and retreive a value by PEEKing. Some fields are larger than 1 byte
  90.  'and you must use PEEKW, PEEKL, POKEW, POKEL. You need to know how far away
  91.  'the field is from the base of the structure. The flags field is one byte
  92.  'away, so to access it we PEEK or POKE to FileIO+1. The previous initialization
  93.  'we did for the window title was at an offset of 244 from the base, and was
  94.  'a LONGWORD (4 bytes). That's why I added the L to POKE.
  95.  
  96.  'Since the user can always set these features up for himself via the 10
  97.  'functions keys (see the doc), normally you wouldn't bother with the Flags
  98.  'field unless you had something particular in mind...but for a demo...
  99.  
  100.  LOCATE 3,1
  101.  'See if the user wants only those filenames that end in a certain extention
  102.  'Actually this feature is dangerous to use via basic because of the way
  103.  'strings exist. If the user were to press function key 4 while we had
  104.  'EXTENTION MATCH enabled, he would then be editing EXT$ and the code that 
  105.  'may be about to execute. Not very good. The way EXTENTION MATCH feature was
  106.  'implemented makes it only work well on lower level languages.
  107.  INPUT "Do you want only those filenames with a certain extention (y or n)";Ans$
  108.  IF Ans$ <> "y" THEN GOTO SkipExt
  109.  INPUT "Type the extention to match (for example, .device)";EXT$
  110.  extsize=LEN(EXT$)
  111.  IF extsize = 0 THEN GOTO SkipExt
  112. 'Enable the extention match feature of the FileIO
  113.   POKE  FileIO+1,4            'Turn on extention match feature only
  114.   POKEW FileIO+226,extsize    'Get the length of the string
  115.   POKEL FileIO+222,SADD(EXT$) 'Set the address of the extention string
  116.   GOTO   DoIO
  117.   
  118. SkipExt:  'Otherwise, at least suppress the .info files
  119.   POKE  FileIO+1,128
  120.   
  121. DoIO:
  122.  Result=DoFileIOWindow(FileIO,0)  'do the FileIO selection on WB screen  
  123.  
  124.  IF Result <> -1 THEN GOTO CheckError    '-1 means the user selected CANCEL.
  125.  message$ = "User selected CANCEL."+CHR$(0)
  126.  CALL AutoMessageLen(SADD(message$),WINDOW(7),21) '21 is the number of chars in Message$ not counting the CHR$(0)
  127.  GOTO CloseUp2
  128.  
  129. CheckError:
  130.  '0 means the FileIO window couldn't open due (probably due to lack of mem).
  131.  'Too bad! You'll have to get the filename some other way. Maybe an INPUT statement?
  132.  IF Result <> 0 THEN GOTO GotPathname              
  133.  'Message number 0 in the FileIO lib says "Out of memory for this operation" 
  134.  Result=AutoFileMessage(0,WINDOW(7))
  135.  GOTO CloseUp2
  136.  
  137. GotPathname:       'We got a selection from the user!
  138.  'Now, our PathBuffer$ has the complete pathname. The FileIO's Filename
  139.  'buffer has just the Filename separated from the disk and drawer names
  140.  '(which are also separated into their own FileIO buffers). Let's copy out
  141.  'each of these buffers so that we can print the separate pieces, plus copy
  142.  'the complete path.
  143.  
  144.  Pathname$ = ""
  145.  FOR i = 0 TO 192
  146.     value = PEEK(BufferPtr+i)
  147.     IF value = 0 THEN GOTO CopyFN
  148.     char$ = CHR$(value)
  149.     Pathname$ = Pathname$+char$    
  150.  NEXT i 
  151.  
  152. CopyFN:
  153.   Filename$ = ""
  154.  'Copy out the Filename to Filename$.
  155.  FOR i = 0 TO 64
  156.     value = PEEK(FileIO+2+i)
  157.     IF value = 0 THEN GOTO CopyDrawer
  158.     char$ = CHR$(value)
  159.     Filename$ = Filename$+char$    
  160.  NEXT i
  161.  
  162. CopyDrawer: 'Copy out all the drawers 
  163.  DrawerName$ = ""
  164.  FOR i = 0 TO 64
  165.     value = PEEK(FileIO+66+i)
  166.     IF value = 0 THEN GOTO CopyVol
  167.     char$ = CHR$(value)
  168.     DrawerName$ = DrawerName$+char$    
  169.  NEXT i
  170.  
  171. CopyVol: 'Copy out the diskname 
  172.  VolName$ = ""
  173.  FOR i = 0 TO 64
  174.     value = PEEK(FileIO+130+i)
  175.     IF value = 0 THEN GOTO PrintPath
  176.     char$ = CHR$(value)
  177.     VolName$ = VolName$+char$    
  178.  NEXT i
  179.  
  180. PrintPath:   'Print out all the info available in the FileIO
  181.  LOCATE 7,1
  182.  
  183. noExt:
  184.  CALL AutoMessage(SADD(Pathname$),WINDOW(7)) 'display our complete path in a
  185.                                              'requester first
  186.  
  187.  PRINT
  188.  'Let's print out the disk, drawers, and filename.
  189.  PRINT "The Diskname is ",VolName$
  190.  PRINT "The Drawernames are ",DrawerName$
  191.  PRINT "The Filename is ",Filename$ 'Note that there is no Filename if the
  192.                                     'user selected only a disc or drawer.
  193.   
  194.  'Let's get the amount of free disk space on the disk that the user chose.
  195.  'This could be important if we were trying to save something to this disk
  196.  'and there wasn't enough room. Also, if the user typed in a disc or drawer
  197.  'that didn't exist or he refused to place that disc in the drive, the
  198.  'returned default disc is ":" which is the current directory.
  199.  PRINT "Free disk space: ",PEEKL(FileIO+236)," bytes."
  200.  
  201.  'Now if this is a loadable file, the FileIO has it's size. If it's only a
  202.  'disc name or dir, or the file doesn't exist, then the size = 0.
  203.  extsize=LEN(Filename$)  'Did the user finally select a file?
  204.  IF extsize = 0 THEN GOTO DiscOrDir         'Must be a disk or drawer only 
  205.  IF PEEKL(FileIO+240) = 0 THEN GOTO NoExist 'Aha! User typed in a Filename that doesn't yet exist
  206.  PRINT "Size of file:    ",PEEKL(FileIO+240)," bytes."
  207.  
  208.  ' Now, you might want to do a load or save routine using this user selected
  209.  ' pathname. You can check the FileIO's FILE.BYTESIZE (FileIO+240) field to see if the
  210.  ' user actually selected an existing file, or typed in a new, non-existant
  211.  ' name. For example, say that the user selected a directory but not a file
  212.  ' within the directory. The returned pathname might be
  213.  '            DF0:SomeDrawerName
  214.  ' In this case, the FILE.BYTESIZE field would be 0 and if you tried to "load"
  215.  ' the file, you would get a DOS error message. Likewise, if the user types
  216.  ' in a non-existant file name, this field is also 0, but you can open the
  217.  ' file for writing (save). If the user's selected pathname is the name of
  218.  ' an object file (not just a dir or disk), then this is the only time that
  219.  ' FILE.BYTESIZE will not be 0. In fact, it will be the size of the file. In
  220.  ' conclusion, if you were doing a load routine, you would do the following
  221.  ' steps at this point:
  222.  ' 1). Check if there is some name in the FileIO's Filename field. If not,
  223.  '     this means that the user selected a disk or drawer only. Abort the load.
  224.  ' 2). Check to see if the FILE.BYTESIZE field is 0. If it is 0, then the
  225.  '     user has typed in a file that doesn't exist (in whichever dir that he
  226.  '     finally chose). Display a message that says "File doesn't exist".
  227.  ' 3). If the FILE.BYTESIZE is not 0, then you can open the file for reading
  228.  '     and copy this many bytes into memory. Since AmigaBasic doesn't have a
  229.  '     facility for loading blocks of bytes, I recommend the DOS library.
  230.  '
  231.  '    LIBRARY "dos.library"
  232.  '    DECLARE  FUNCTION  Open() LIBRARY
  233.  '    DECLARE  FUNCTION  Read() LIBRARY
  234.  '    DECLARE  FUNCTION  Write() LIBRARY 
  235.  '    Filehandle=Open(BufferPtr,1005&)
  236.  '    IF Filehandle <> 0 THEN GOTO GotIt 
  237.  '        Message$ = "Cannot locate this file!"+CHR$(0) 'Oops Can't find it.
  238.  '        CALL AutoMessageLen(SADD(Message$),WINDOW(7),24&)
  239.  '        GOTO BadLoad
  240.  'GotIt:
  241.  '    Bytes=PEEKL(FileIO+240)
  242.  '    DIM DataBuffer(Bytes)   'read the file into this 1-D array
  243.  '    Error=Read(Filehandle,VARPTR(DataBuffer(0)),Bytes)
  244.  '    CALL Close(Filehandle)
  245.  '    IF Error = Bytes THEN GOTO GoodLoad 
  246.  '      boolean=AutoFileMessage(2&,WINDOW(7)) 'tell the user that an error occured
  247.  '      GOTO BadLoad
  248.  'GoodLoad:
  249.  
  250.  '    You can now "pull out" data from DataBuffer as you need it (like we
  251.  '    extracted data from FileIO except perhaps you might not want to
  252.  '    convert the value to ascii via CHR$).
  253.   
  254.  ' If you were doing a save routine to disk, you would do the following:
  255.  ' 1). Check if there is some name in the FileIO's Filename field. If not,
  256.  '     this means that the user selected a disk or drawer only. Abort the save.
  257.  ' 2). Check if FILE.BYTESIZE is not 0. If not 0, inform the user that this
  258.  '     file already exists and if you save using this name, you will write
  259.  '     over the other file. Ask the user if he wants to do the save anyway.
  260.  ' 3). If FILE.BYTESIZE is 0, this file doesn't already exist. Check that the
  261.  '     free disk space is greater than the number of bytes that we want to
  262.  '     save, or else we'll run out of room during the save.
  263.  '
  264.  '  Let's say that you stored the data in a big 1-D array called DataTank
  265.  '  and the number of bytes you want to save is 32.
  266.  '
  267.  '  Bytes=32&
  268.  '  Filehandle=Open(BufferPtr,1006&)
  269.  '  IF Filehandle <> 0 THEN GOTO CreateIt 
  270.  '        Message$ = "Cannot create the file!"+CHR$(0) 'Oops Can't save it.
  271.  '        CALL AutoMessageLen(SADD(Message$),WINDOW(7),23&)
  272.  '        GOTO BadSave
  273.  '  Error=Write(Filehandle,VARPTR(DataTank(0)),Bytes)
  274.  '  CALL Close(Filehandle)
  275.  '  IF Error = Bytes THEN GOTO GoodSave
  276.  '      boolean=AutoFileMessage(2&,WINDOW(7)) 'tell the user that an error occured
  277.  '      GOTO BadSave
  278.  'GoodSave:
  279.  
  280. Retry:
  281.  message$  = "This has been a test of the FileIO library." + CHR$(0)
  282.  Message2$ = "Do you want to retry?" + CHR$(0)
  283.  boolean=AutoPrompt3(SADD(message$),SADD(Message2$),0,WINDOW(7))
  284.  CLS
  285.  IF boolean = 1 THEN GOTO Again
  286.  
  287.  'Note how the lib automatically spaces these messages symmetrically
  288.  
  289.  message$ = "Example program and asm lib by Jeff Glatt" + CHR$(0)
  290.  Message2$ = "(dissidents)" + CHR$(0)
  291.  Message3$ = "Original FileIO by RJ Mical" + CHR$(0)
  292.  boolean=AutoPrompt3(SADD(message$),SADD(Message2$),SADD(Message3$),WINDOW(7))  
  293.  
  294. CloseUp2: 
  295.  
  296.  CALL ResetTitle(FileIO,WINDOW(7)) 'Maybe we changed it for the error msgs.
  297.  CALL ReleaseFileIO(FileIO)        'Free the FileIO structure
  298.   
  299. CloseUp1:
  300.  
  301.  CALL  FreeMem(BufferPtr,BUFSIZE)
  302.  
  303. CloseUp: 
  304.  LIBRARY CLOSE
  305.  END
  306.  
  307.  ' For these 2 errors, let's see how the SetTitle function works. This will
  308.  ' display in the window's title bar string1 followed by string2, but unlike
  309.  ' a requester, returns control back to the program. When we finally call
  310.  ' ResetTitle, the original title is restored. We can call SetTitle without
  311.  ' needing a ResetTitle inbetween and vica versa. Notice how this message
  312.  ' appears in the window and requester title bars. Subsequent calls to these
  313.  ' error routines (answer "Yes" to the again requester and cause another
  314.  ' error) will change the title bar further. Yet, when we finally call
  315.  ' ResetTitle upon exit, the initial title is restored. As you can see, these
  316.  ' routines are good for posting error msgs that don't halt the program (like
  317.  ' requesters) but remain visible for as long as they are needed.
  318.  
  319. DiscOrDir:
  320.   message$ = "Dir only - "+CHR$(0)
  321.  'String2 will be our Pathname
  322.   CALL SetTitle(SADD(message$),SADD(Pathname$),FileIO,WINDOW(7))
  323.   GOTO Retry
  324.  
  325. NoExist:
  326.   message$ = "This file doesn't exist."+CHR$(0)
  327.   'Note how we indicate that we don't want String2. You must have string1
  328.   'though, even it were just a space.
  329.   CALL SetTitle(SADD(message$),0,FileIO,WINDOW(7))
  330.   GOTO Retry
  331.  
  332.