KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > net > tftp > TFTPRequestPacket


1 /*
2  * Copyright 2001-2005 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.net.tftp;
17
18 import java.net.DatagramPacket JavaDoc;
19 import java.net.InetAddress JavaDoc;
20
21 /***
22  * An abstract class derived from TFTPPacket definiing a TFTP Request
23  * packet type. It is subclassed by the
24  * {@link org.apache.commons.net.tftp.TFTPReadRequestPacket}
25  * and
26  * {@link org.apache.commons.net.tftp.TFTPWriteRequestPacket}
27  * classes.
28  * <p>
29  * Details regarding the TFTP protocol and the format of TFTP packets can
30  * be found in RFC 783. But the point of these classes is to keep you
31  * from having to worry about the internals. Additionally, only very
32  * few people should have to care about any of the TFTPPacket classes
33  * or derived classes. Almost all users should only be concerned with the
34  * {@link org.apache.commons.net.tftp.TFTPClient} class
35  * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
36  * and
37  * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
38  * methods.
39  * <p>
40  * <p>
41  * @author Daniel F. Savarese
42  * @see TFTPPacket
43  * @see TFTPReadRequestPacket
44  * @see TFTPWriteRequestPacket
45  * @see TFTPPacketException
46  * @see TFTP
47  ***/

48
49 public abstract class TFTPRequestPacket extends TFTPPacket
50 {
51     /***
52      * An array containing the string names of the transfer modes and indexed
53      * by the transfer mode constants.
54      ***/

55     static final String JavaDoc[] _modeStrings = { "netascii", "octet" };
56
57     /***
58      * A null terminated byte array representation of the ascii names of the
59      * transfer mode constants. This is convenient for creating the TFTP
60      * request packets.
61      ***/

62     static final byte[] _modeBytes[] = {
63                                            { (byte)'n', (byte)'e', (byte)'t', (byte)'a', (byte)'s', (byte)'c',
64                                              (byte)'i', (byte)'i', 0 },
65                                            { (byte)'o', (byte)'c', (byte)'t', (byte)'e', (byte)'t', 0 }
66                                        };
67
68     /*** The transfer mode of the request. ***/
69     int _mode;
70
71     /*** The filename of the request. ***/
72     String JavaDoc _filename;
73
74     /***
75      * Creates a request packet of a given type to be sent to a host at a
76      * given port with a filename and transfer mode request.
77      * <p>
78      * @param destination The host to which the packet is going to be sent.
79      * @param port The port to which the packet is going to be sent.
80      * @param type The type of the request (either TFTPPacket.READ_REQUEST or
81      * TFTPPacket.WRITE_REQUEST).
82      * @param filename The requested filename.
83      * @param mode The requested transfer mode. This should be on of the TFTP
84      * class MODE constants (e.g., TFTP.NETASCII_MODE).
85      ***/

86     TFTPRequestPacket(InetAddress JavaDoc destination, int port,
87                       int type, String JavaDoc filename, int mode)
88     {
89         super(type, destination, port);
90
91         _filename = filename;
92         _mode = mode;
93     }
94
95     /***
96      * Creates a request packet of a given type based on a received
97      * datagram. Assumes the datagram is at least length 4, else an
98      * ArrayIndexOutOfBoundsException may be thrown.
99      * <p>
100      * @param type The type of the request (either TFTPPacket.READ_REQUEST or
101      * TFTPPacket.WRITE_REQUEST).
102      * @param datagram The datagram containing the received request.
103      * @throws TFTPPacketException If the datagram isn't a valid TFTP
104      * request packet of the appropriate type.
105      ***/

106     TFTPRequestPacket(int type, DatagramPacket JavaDoc datagram)
107     throws TFTPPacketException
108     {
109         super(type, datagram.getAddress(), datagram.getPort());
110
111         byte[] data;
112         int index, length;
113         String JavaDoc mode;
114         StringBuffer JavaDoc buffer;
115
116         data = datagram.getData();
117
118         if (getType() != data[1])
119             throw new TFTPPacketException("TFTP operator code does not match type.");
120
121         buffer = new StringBuffer JavaDoc();
122
123         index = 2;
124         length = datagram.getLength();
125
126         while (index < length && data[index] != 0)
127         {
128             buffer.append((char)data[index]);
129             ++index;
130         }
131
132         _filename = buffer.toString();
133
134         if (index >= length)
135             throw new TFTPPacketException("Bad filename and mode format.");
136
137         buffer.setLength(0);
138         ++index; // need to advance beyond the end of string marker
139
while (index < length && data[index] != 0)
140         {
141             buffer.append((char)data[index]);
142             ++index;
143         }
144
145         mode = buffer.toString().toLowerCase();
146         length = _modeStrings.length;
147
148         for (index = 0; index < length; index++)
149         {
150             if (mode.equals(_modeStrings[index]))
151             {
152                 _mode = index;
153                 break;
154             }
155         }
156
157         if (index >= length)
158         {
159             throw new TFTPPacketException("Unrecognized TFTP transfer mode: " + mode);
160             // May just want to default to binary mode instead of throwing
161
// exception.
162
//_mode = TFTP.OCTET_MODE;
163
}
164     }
165
166
167     /***
168      * This is a method only available within the package for
169      * implementing efficient datagram transport by elminating buffering.
170      * It takes a datagram as an argument, and a byte buffer in which
171      * to store the raw datagram data. Inside the method, the data
172      * is set as the datagram's data and the datagram returned.
173      * <p>
174      * @param datagram The datagram to create.
175      * @param data The buffer to store the packet and to use in the datagram.
176      * @return The datagram argument.
177      ***/

178     final DatagramPacket JavaDoc _newDatagram(DatagramPacket JavaDoc datagram, byte[] data)
179     {
180         int fileLength, modeLength;
181
182         fileLength = _filename.length();
183         modeLength = _modeBytes[_mode].length;
184
185         data[0] = 0;
186         data[1] = (byte)_type;
187         System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
188         data[fileLength + 2] = 0;
189         System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
190                          modeLength);
191
192         datagram.setAddress(_address);
193         datagram.setPort(_port);
194         datagram.setData(data);
195         datagram.setLength(fileLength + modeLength + 3);
196         
197         return datagram;
198     }
199
200     /***
201      * Creates a UDP datagram containing all the TFTP
202      * request packet data in the proper format.
203      * This is a method exposed to the programmer in case he
204      * wants to implement his own TFTP client instead of using
205      * the {@link org.apache.commons.net.tftp.TFTPClient}
206      * class. Under normal circumstances, you should not have a need to call
207      * this method.
208      * <p>
209      * @return A UDP datagram containing the TFTP request packet.
210      ***/

211     public final DatagramPacket JavaDoc newDatagram()
212     {
213         int fileLength, modeLength;
214         byte[] data;
215
216         fileLength = _filename.length();
217         modeLength = _modeBytes[_mode].length;
218
219         data = new byte[fileLength + modeLength + 4];
220         data[0] = 0;
221         data[1] = (byte)_type;
222         System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
223         data[fileLength + 2] = 0;
224         System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
225                          modeLength);
226
227         return new DatagramPacket JavaDoc(data, data.length, _address, _port);
228     }
229
230     /***
231      * Returns the transfer mode of the request.
232      * <p>
233      * @return The transfer mode of the request.
234      ***/

235     public final int getMode()
236     {
237         return _mode;
238     }
239
240     /***
241      * Returns the requested filename.
242      * <p>
243      * @return The requested filename.
244      ***/

245     public final String JavaDoc getFilename()
246     {
247         return _filename;
248     }
249 }
250
Popular Tags