View Javadoc

1   /*
2    * Copyright (c) 2005 The University of Reading
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    * 1. Redistributions of source code must retain the above copyright
9    *    notice, this list of conditions and the following disclaimer.
10   * 2. Redistributions in binary form must reproduce the above copyright
11   *    notice, this list of conditions and the following disclaimer in the
12   *    documentation and/or other materials provided with the distribution.
13   * 3. Neither the name of the University of Reading, nor the names of the
14   *    authors or contributors may be used to endorse or promote products
15   *    derived from this software without specific prior written permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   */
28  
29  package uk.ac.rdg.resc.jstyx.client.callbacks;
30  
31  import uk.ac.rdg.resc.jstyx.client.StyxConnection;
32  import uk.ac.rdg.resc.jstyx.client.CStyxFile;
33  import uk.ac.rdg.resc.jstyx.client.MessageCallback;
34  
35  import uk.ac.rdg.resc.jstyx.messages.StyxMessage;
36  import uk.ac.rdg.resc.jstyx.messages.TreadMessage;
37  import uk.ac.rdg.resc.jstyx.messages.RreadMessage;
38  import uk.ac.rdg.resc.jstyx.messages.RopenMessage;
39  
40  import uk.ac.rdg.resc.jstyx.StyxUtils;
41  import uk.ac.rdg.resc.jstyx.types.ULong;
42  
43  /***
44   * Callback used when reading from a file (see CStyxFile.readAsync())
45   *
46   * @author jdb
47   * $Revision: 523 $
48   * $Date: 2005-12-07 08:51:14 +0000 (Wed, 07 Dec 2005) $
49   * $Log$
50   * Revision 1.2  2005/12/07 08:51:14  jonblower
51   * Added option to readAsync() to open file for reading and writing with truncation
52   *
53   * Revision 1.1  2005/08/05 13:46:40  jonblower
54   * Factored out all callback objects from CStyxFile into separate classes
55   *
56   */
57  
58  public class ReadCallback extends MessageCallback
59  {
60      private long offset;
61      private int bytesRequired;
62      private boolean openForWriting;
63      private MessageCallback callback;
64      private CStyxFile file;
65      private StyxConnection conn;
66  
67      public ReadCallback(CStyxFile file, long offset, int bytesRequired,
68          boolean openForWriting, MessageCallback callback)
69      {
70          this.file = file;
71          this.conn = this.file.getConnection();
72          this.offset = offset;
73          this.bytesRequired = bytesRequired;
74          this.openForWriting = openForWriting;
75          this.callback = callback;
76      }
77  
78      public void nextStage()
79      {
80          if (this.file.isOpen())
81          {
82              // The file is open. Check the mode
83              int rwx = this.file.getMode() & 3; // mask off last two bits to get OREAD, OWRITE, 
84                                                 // ORDWR or OEXEC (i.e. ignore OTRUNC/ORCLOSE)
85              if (rwx == StyxUtils.OREAD || rwx == StyxUtils.ORDWR)
86              {
87                  // Try to read the given number of bytes from the file
88                  TreadMessage tReadMsg = new TreadMessage(this.file.getFid(),
89                      new ULong(this.offset), this.bytesRequired < 0 ?
90                          this.file.getIoUnit() : this.bytesRequired);
91                  conn.sendAsync(tReadMsg, this);
92              }
93              else
94              {
95                  this.error("File " + this.file.getPath() + " is not open for reading", null);
96              }
97          }
98          else
99          {
100             // We need to open the file
101             if (this.openForWriting)
102             {
103                 // We need to open the file for reading and writing with truncation
104                 this.file.openAsync(StyxUtils.ORDWR | StyxUtils.OTRUNC, this);
105             }
106             else
107             {
108                 // Open the file read-only
109                 this.file.openAsync(StyxUtils.OREAD, this);
110             }
111         }
112     }
113 
114     public void replyArrived(StyxMessage rMessage, StyxMessage tMessage)
115     {
116         if (rMessage instanceof RopenMessage)
117         {
118             // This is the reponse from openAsync()
119             // We've just got the open fid for the file. Go to the next stage
120             // (i.e. read from the file)
121             this.nextStage();
122         }
123         else
124         {
125             // Must be an RreadMessage
126             if (this.callback != null)
127             {
128                 this.callback.replyArrived(rMessage, tMessage);
129             }
130             else
131             {
132                 this.file.fireDataArrived((TreadMessage)tMessage, (RreadMessage)rMessage);
133             }
134         }
135     }
136 
137     public void error(String message, StyxMessage tMessage)
138     {
139         String errMsg = "Error reading from " + this.file.getPath() + ": " + message;
140         if (this.callback != null)
141         {
142             this.callback.error(message, tMessage);
143         }
144         else
145         {
146             this.file.fireError(errMsg);
147         }
148     }
149 }