Source for gnu.inet.gopher.DirectoryListing

   1: /*
   2:  * DirectoryListing.java
   3:  * Copyright (C) 2003 The Free Software Foundation
   4:  * 
   5:  * This file is part of GNU inetlib, a library.
   6:  * 
   7:  * GNU inetlib is free software; you can redistribute it and/or modify
   8:  * it under the terms of the GNU General Public License as published by
   9:  * the Free Software Foundation; either version 2 of the License, or
  10:  * (at your option) any later version.
  11:  * 
  12:  * GNU inetlib is distributed in the hope that it will be useful,
  13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15:  * GNU General Public License for more details.
  16:  * 
  17:  * You should have received a copy of the GNU General Public License
  18:  * along with this library; if not, write to the Free Software
  19:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20:  *
  21:  * Linking this library statically or dynamically with other modules is
  22:  * making a combined work based on this library.  Thus, the terms and
  23:  * conditions of the GNU General Public License cover the whole
  24:  * combination.
  25:  *
  26:  * As a special exception, the copyright holders of this library give you
  27:  * permission to link this library with independent modules to produce an
  28:  * executable, regardless of the license terms of these independent
  29:  * modules, and to copy and distribute the resulting executable under
  30:  * terms of your choice, provided that you also meet, for each linked
  31:  * independent module, the terms and conditions of the license of that
  32:  * module.  An independent module is a module which is not derived from
  33:  * or based on this library.  If you modify this library, you may extend
  34:  * this exception to your version of the library, but you are not
  35:  * obliged to do so.  If you do not wish to do so, delete this
  36:  * exception statement from your version.
  37:  */
  38: 
  39: package gnu.inet.gopher;
  40: 
  41: import java.io.InputStream;
  42: import java.io.IOException;
  43: import java.net.ProtocolException;
  44: import java.util.Iterator;
  45: import java.util.NoSuchElementException;
  46: 
  47: import gnu.inet.util.LineInputStream;
  48: 
  49: /**
  50:  * A gopher directory listing.
  51:  *
  52:  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  53:  */
  54: public final class DirectoryListing
  55:   implements Iterator
  56: {
  57: 
  58:   private static final String DOT = ".";
  59: 
  60:   private LineInputStream in;
  61:   private boolean doneRead = false;
  62:   private DirectoryEntry current;
  63: 
  64:   DirectoryListing(InputStream in)
  65:   {
  66:     this.in = new LineInputStream(in);
  67:   }
  68:   
  69:   /**
  70:    * Indicates whether this listing contains more entries.
  71:    */
  72:   public boolean hasNext()
  73:   {
  74:     try
  75:       {
  76:         fetch();
  77:       }
  78:     catch (IOException e)
  79:       {
  80:         return false;
  81:       }
  82:     return (current != null);
  83:   }
  84: 
  85:   /**
  86:    * @see #nextEntry
  87:    */
  88:   public Object next()
  89:   {
  90:     try
  91:       {
  92:         return nextEntry();
  93:       }
  94:     catch (IOException e)
  95:       {
  96:         throw new NoSuchElementException("I/O error: " + e.getMessage());
  97:       }
  98:   }
  99:   
 100:   /**
 101:    * This iterator is read-only.
 102:    */
 103:   public void remove()
 104:   {
 105:     throw new UnsupportedOperationException();
 106:   }
 107:   
 108:   /**
 109:    * Returns the next entry in the directory listing.
 110:    */
 111:   public DirectoryEntry nextEntry()
 112:     throws IOException
 113:   {
 114:     fetch();
 115:     if (current == null)
 116:       {
 117:         throw new NoSuchElementException();
 118:       }
 119:     doneRead = false;
 120:     return current;
 121:   }
 122:   
 123:   void fetch()
 124:     throws IOException
 125:   {
 126:     if (doneRead)
 127:       {
 128:         return;
 129:       }
 130:     String line = in.readLine();
 131:     if (DOT.equals(line))
 132:       {
 133:         current = null;
 134:       }
 135:     else
 136:       {
 137:         // Parse line
 138:         int type = DirectoryEntry.ERROR;
 139:         switch(line.charAt(0))
 140:           {
 141:           case '0':
 142:             type = DirectoryEntry.FILE;
 143:             break;
 144:           case '1':
 145:             type = DirectoryEntry.DIRECTORY;
 146:             break;
 147:           case '2':
 148:             type = DirectoryEntry.CSO_PHONE_BOOK;
 149:             break;
 150:           case '3':
 151:             type = DirectoryEntry.ERROR;
 152:             break;
 153:           case '4':
 154:             type = DirectoryEntry.BINHEX;
 155:             break;
 156:           case '5':
 157:             type = DirectoryEntry.DOS_ARCHIVE;
 158:             break;
 159:           case '6':
 160:             type = DirectoryEntry.UUENCODED;
 161:             break;
 162:           case '7':
 163:             type = DirectoryEntry.INDEX_SEARCH;
 164:             break;
 165:           case '8':
 166:             type = DirectoryEntry.TELNET;
 167:             break;
 168:           case '9':
 169:             type = DirectoryEntry.BINARY;
 170:             break;
 171:           case '+':
 172:             type = DirectoryEntry.REDUNDANT;
 173:             break;
 174:           case 'T':
 175:             type = DirectoryEntry.TN3270;
 176:             break;
 177:           case 'g':
 178:             type = DirectoryEntry.GIF;
 179:             break;
 180:           case 'I':
 181:             type = DirectoryEntry.IMAGE;
 182:             break;
 183:           }
 184:         int start = 1;
 185:         int end = line.indexOf('\t', start);
 186:         if (end == -1)
 187:           {
 188:             throw new ProtocolException("Invalid directory entry: " + line);
 189:           }
 190:         String title = line.substring(start, end);
 191:         start = end + 1;
 192:         end = line.indexOf('\t', start);
 193:         if (end == -1)
 194:           {
 195:             throw new ProtocolException("Invalid directory entry: " + line);
 196:           }
 197:         String selector = line.substring(start, end);
 198:         start = end + 1;
 199:         end = line.indexOf('\t', start);
 200:         if (end == -1)
 201:           {
 202:             throw new ProtocolException("Invalid directory entry: " + line);
 203:           }
 204:         String hostname = line.substring(start, end);
 205:         start = end + 1;
 206:         int port = Integer.parseInt(line.substring(start));
 207:         current = new DirectoryEntry(type, title, selector, hostname, port);
 208:       }
 209:   }
 210:   
 211: }