001: /* jcifs smb client library in Java
002: * Copyright (C) 2003 "Michael B. Allen" <jcifs at samba dot org>
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package jcifs.smb;
020:
021: import java.io.DataInput;
022: import java.io.DataOutput;
023: import java.io.DataInputStream;
024: import java.io.DataOutputStream;
025: import java.io.IOException;
026: import java.net.MalformedURLException;
027: import java.net.UnknownHostException;
028: import jcifs.util.Encdec;
029:
030: public class SmbRandomAccessFile implements DataOutput, DataInput {
031:
032: private static final int WRITE_OPTIONS = 0x0842;
033:
034: private SmbFile file;
035: private long fp;
036: private int openFlags, readSize, writeSize, ch, options = 0;
037: private byte[] tmp = new byte[8];
038: private SmbComWriteAndXResponse write_andx_resp = null;
039:
040: public SmbRandomAccessFile(String url, String mode, int shareAccess)
041: throws SmbException, MalformedURLException,
042: UnknownHostException {
043: this (new SmbFile(url, "", null, shareAccess), mode);
044: }
045:
046: public SmbRandomAccessFile(SmbFile file, String mode)
047: throws SmbException, MalformedURLException,
048: UnknownHostException {
049: this .file = file;
050: if (mode.equals("r")) {
051: this .openFlags = SmbFile.O_CREAT | SmbFile.O_RDONLY;
052: } else if (mode.equals("rw")) {
053: this .openFlags = SmbFile.O_CREAT | SmbFile.O_RDWR
054: | SmbFile.O_APPEND;
055: write_andx_resp = new SmbComWriteAndXResponse();
056: options = WRITE_OPTIONS;
057: } else {
058: throw new IllegalArgumentException("Invalid mode");
059: }
060: file.open(openFlags, SmbFile.ATTR_NORMAL, options);
061: readSize = file.tree.session.transport.rcv_buf_size - 70;
062: writeSize = file.tree.session.transport.snd_buf_size - 70;
063: fp = 0L;
064: }
065:
066: public int read() throws SmbException {
067: if (read(tmp, 0, 1) == -1) {
068: return -1;
069: }
070: return tmp[0] & 0xFF;
071: }
072:
073: public int read(byte b[]) throws SmbException {
074: return read(b, 0, b.length);
075: }
076:
077: public int read(byte b[], int off, int len) throws SmbException {
078: if (len <= 0) {
079: return 0;
080: }
081: long start = fp;
082:
083: // ensure file is open
084: if (file.isOpen() == false) {
085: file.open(openFlags, SmbFile.ATTR_NORMAL, options);
086: }
087:
088: int r, n;
089: SmbComReadAndXResponse response = new SmbComReadAndXResponse(b,
090: off);
091: do {
092: r = len > readSize ? readSize : len;
093: file.send(new SmbComReadAndX(file.fid, fp, r, null),
094: response);
095: if ((n = response.dataLength) <= 0) {
096: return (int) ((fp - start) > 0L ? fp - start : -1);
097: }
098: fp += n;
099: len -= n;
100: response.off += n;
101: } while (len > 0 && n == r);
102:
103: return (int) (fp - start);
104: }
105:
106: public final void readFully(byte b[]) throws SmbException {
107: readFully(b, 0, b.length);
108: }
109:
110: public final void readFully(byte b[], int off, int len)
111: throws SmbException {
112: int n = 0, count;
113:
114: do {
115: count = this .read(b, off + n, len - n);
116: if (count < 0)
117: throw new SmbException("EOF");
118: n += count;
119: fp += count;
120: } while (n < len);
121: }
122:
123: public int skipBytes(int n) throws SmbException {
124: if (n > 0) {
125: fp += n;
126: return n;
127: }
128: return 0;
129: }
130:
131: public void write(int b) throws SmbException {
132: tmp[0] = (byte) b;
133: write(tmp, 0, 1);
134: }
135:
136: public void write(byte b[]) throws SmbException {
137: write(b, 0, b.length);
138: }
139:
140: public void write(byte b[], int off, int len) throws SmbException {
141: if (len <= 0) {
142: return;
143: }
144:
145: // ensure file is open
146: if (file.isOpen() == false) {
147: file.open(openFlags, SmbFile.ATTR_NORMAL, options);
148: }
149:
150: int w;
151: do {
152: w = len > writeSize ? writeSize : len;
153: file.send(new SmbComWriteAndX(file.fid, fp, len - w, b,
154: off, w, null), write_andx_resp);
155: fp += write_andx_resp.count;
156: len -= write_andx_resp.count;
157: off += write_andx_resp.count;
158: } while (len > 0);
159: }
160:
161: public long getFilePointer() throws SmbException {
162: return fp;
163: }
164:
165: public void seek(long pos) throws SmbException {
166: fp = pos;
167: }
168:
169: public long length() throws SmbException {
170: return file.length();
171: }
172:
173: public void setLength(long newLength) throws SmbException {
174: // ensure file is open
175: if (file.isOpen() == false) {
176: file.open(openFlags, SmbFile.ATTR_NORMAL, options);
177: }
178: SmbComWriteResponse rsp = new SmbComWriteResponse();
179: file.send(new SmbComWrite(file.fid,
180: (int) (newLength & 0xFFFFFFFFL), 0, tmp, 0, 0), rsp);
181: }
182:
183: public void close() throws SmbException {
184: file.close();
185: }
186:
187: public final boolean readBoolean() throws SmbException {
188: if ((read(tmp, 0, 1)) < 0) {
189: throw new SmbException("EOF");
190: }
191: return tmp[0] != (byte) 0x00;
192: }
193:
194: public final byte readByte() throws SmbException {
195: if ((read(tmp, 0, 1)) < 0) {
196: throw new SmbException("EOF");
197: }
198: return tmp[0];
199: }
200:
201: public final int readUnsignedByte() throws SmbException {
202: if ((read(tmp, 0, 1)) < 0) {
203: throw new SmbException("EOF");
204: }
205: return tmp[0] & 0xFF;
206: }
207:
208: public final short readShort() throws SmbException {
209: if ((read(tmp, 0, 2)) < 0) {
210: throw new SmbException("EOF");
211: }
212: return Encdec.dec_uint16be(tmp, 0);
213: }
214:
215: public final int readUnsignedShort() throws SmbException {
216: if ((read(tmp, 0, 2)) < 0) {
217: throw new SmbException("EOF");
218: }
219: return Encdec.dec_uint16be(tmp, 0);
220: }
221:
222: public final char readChar() throws SmbException {
223: if ((read(tmp, 0, 2)) < 0) {
224: throw new SmbException("EOF");
225: }
226: return (char) Encdec.dec_uint16be(tmp, 0);
227: }
228:
229: public final int readInt() throws SmbException {
230: if ((read(tmp, 0, 4)) < 0) {
231: throw new SmbException("EOF");
232: }
233: return Encdec.dec_uint32be(tmp, 0);
234: }
235:
236: public final long readLong() throws SmbException {
237: if ((read(tmp, 0, 8)) < 0) {
238: throw new SmbException("EOF");
239: }
240: return Encdec.dec_uint64be(tmp, 0);
241: }
242:
243: public final float readFloat() throws SmbException {
244: if ((read(tmp, 0, 4)) < 0) {
245: throw new SmbException("EOF");
246: }
247: return Encdec.dec_floatbe(tmp, 0);
248: }
249:
250: public final double readDouble() throws SmbException {
251: if ((read(tmp, 0, 8)) < 0) {
252: throw new SmbException("EOF");
253: }
254: return Encdec.dec_doublebe(tmp, 0);
255: }
256:
257: public final String readLine() throws SmbException {
258: StringBuffer input = new StringBuffer();
259: int c = -1;
260: boolean eol = false;
261:
262: while (!eol) {
263: switch (c = read()) {
264: case -1:
265: case '\n':
266: eol = true;
267: break;
268: case '\r':
269: eol = true;
270: long cur = fp;
271: if (read() != '\n') {
272: fp = cur;
273: }
274: break;
275: default:
276: input.append((char) c);
277: break;
278: }
279: }
280:
281: if ((c == -1) && (input.length() == 0)) {
282: return null;
283: }
284:
285: return input.toString();
286: }
287:
288: public final String readUTF() throws SmbException {
289: int size = readUnsignedShort();
290: byte[] b = new byte[size];
291: read(b, 0, size);
292: try {
293: return Encdec.dec_utf8(b, 0, size);
294: } catch (IOException ioe) {
295: throw new SmbException("", ioe);
296: }
297: }
298:
299: public final void writeBoolean(boolean v) throws SmbException {
300: tmp[0] = (byte) (v ? 1 : 0);
301: write(tmp, 0, 1);
302: }
303:
304: public final void writeByte(int v) throws SmbException {
305: tmp[0] = (byte) v;
306: write(tmp, 0, 1);
307: }
308:
309: public final void writeShort(int v) throws SmbException {
310: Encdec.enc_uint16be((short) v, tmp, 0);
311: write(tmp, 0, 2);
312: }
313:
314: public final void writeChar(int v) throws SmbException {
315: Encdec.enc_uint16be((short) v, tmp, 0);
316: write(tmp, 0, 2);
317: }
318:
319: public final void writeInt(int v) throws SmbException {
320: Encdec.enc_uint32be(v, tmp, 0);
321: write(tmp, 0, 4);
322: }
323:
324: public final void writeLong(long v) throws SmbException {
325: Encdec.enc_uint64be(v, tmp, 0);
326: write(tmp, 0, 8);
327: }
328:
329: public final void writeFloat(float v) throws SmbException {
330: Encdec.enc_floatbe(v, tmp, 0);
331: write(tmp, 0, 4);
332: }
333:
334: public final void writeDouble(double v) throws SmbException {
335: Encdec.enc_doublebe(v, tmp, 0);
336: write(tmp, 0, 8);
337: }
338:
339: public final void writeBytes(String s) throws SmbException {
340: byte[] b = s.getBytes();
341: write(b, 0, b.length);
342: }
343:
344: public final void writeChars(String s) throws SmbException {
345: int clen = s.length();
346: int blen = 2 * clen;
347: byte[] b = new byte[blen];
348: char[] c = new char[clen];
349: s.getChars(0, clen, c, 0);
350: for (int i = 0, j = 0; i < clen; i++) {
351: b[j++] = (byte) (c[i] >>> 8);
352: b[j++] = (byte) (c[i] >>> 0);
353: }
354: write(b, 0, blen);
355: }
356:
357: public final void writeUTF(String str) throws SmbException {
358: int len = str.length();
359: int ch, size = 0;
360: byte[] dst;
361:
362: for (int i = 0; i < len; i++) {
363: ch = str.charAt(i);
364: size += ch > 0x07F ? (ch > 0x7FF ? 3 : 2) : 1;
365: }
366: dst = new byte[size];
367: writeShort(size);
368: try {
369: Encdec.enc_utf8(str, dst, 0, size);
370: } catch (IOException ioe) {
371: throw new SmbException("", ioe);
372: }
373: write(dst, 0, size);
374: }
375: }
|