DirectoryStream.st
author claus
Wed, 13 Oct 1993 01:19:00 +0100
changeset 3 24d81bf47225
parent 2 6526dde5f3ac
child 5 67342904af11
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 1989-93 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

FileStream subclass:#DirectoryStream
       instanceVariableNames:'dirPointer readAhead'
       classVariableNames:''
       poolDictionaries:''
       category:'Streams-External'
!

DirectoryStream comment:'

COPYRIGHT (c) 1989-93 by Claus Gittinger
              All Rights Reserved

$Header: /cvs/stx/stx/libbasic/DirectoryStream.st,v 1.3 1993-10-13 00:15:33 claus Exp $
'!

%{
#include <stdio.h>
#ifndef transputer
# include <sys/types.h>
# include <sys/stat.h>
# ifdef OPENDIR
#  include <sys/types.h>
#  ifdef NEXT
#   include <sys/dir.h>
#  else
#   include <dirent.h>
#  endif
# endif
#endif
%}

!DirectoryStream methodsFor:'instance release'!

closeFile
    "a directoryStream has been collected - close it"
%{
#ifdef OPENDIR
    closedir((DIR *)MKFD(_INST(dirPointer)));
#endif
%}
! !

!DirectoryStream class methodsFor:'instance creation'!

directoryNamed:dirName
    "return a DirectoryStream for directory named dirName, aString"

    |newStream|

    newStream := (self basicNew) pathName:dirName.
    newStream openForReading isNil ifTrue:[^nil].
    ^ newStream
! !

!DirectoryStream methodsFor:'access reading'!

nextLine
    "return the next filename as a string"

    |prevEntry nextEntry|
%{
#ifdef OPENDIR
    DIR *d;
#ifdef NEXT
    struct direct *dp;
#else
    struct dirent *dp;
#endif

    if (_INST(dirPointer) != nil) {
        d = (DIR *)MKFD(_INST(dirPointer));
        dp = readdir(d);
        if (dp != NULL) {
            nextEntry = _MKSTRING((char *)(dp->d_name) COMMA_CON);
        }
    }
#endif
%}
.
    prevEntry := readAhead.
    readAhead := nextEntry.
    ^ prevEntry
! !

!DirectoryStream methodsFor:'private'!

openForReading
    "open the file for readonly"

    |retVal|

    mode := #readonly.
%{
#ifdef OPENDIR
    DIR *d;
    OBJ path;
    extern OBJ ErrorNumber, ErrorString;
    extern errno;

    retVal = false;
    if (_INST(dirPointer) == nil) {
        path = _INST(pathName);
        if (_isString(path)) {
            d = opendir((char *) _stringVal(path));
            if (d == NULL) {
                /* ErrorString = _MKSTRING(perror("popen:") COMMA_CON); */
                ErrorNumber = _MKSMALLINT(errno);
            } else {
                _INST(dirPointer) = MKOBJ(d);
                retVal = true;
            }
        }
    }
#endif
%}
.
    retVal isNil ifTrue:[
        "opendir not avalable - use slow pipe"
        ^ PipeStream readingFrom:('cd ' , pathName , '; ls -a')
    ].
    (retVal == true) ifTrue:[
        lobby register:self.
        self nextLine. "read 1st entry into readAhead buffer"
        ^ self
    ].
    ^ nil
!

reOpen
    dirPointer := nil.
    super reOpen
! !

!DirectoryStream methodsFor:'testing'!

atEnd
    "return true, if position is at end"

    ^ readAhead == nil
! !

!DirectoryStream methodsFor:'closing'!

close
    "close the stream - tell operating system"

    dirPointer notNil ifTrue:[
        lobby unregister:self.
        self closeFile.
        dirPointer := nil
    ]
! !