From 7fb94ed43a814788cda019c1e77314abc1626339 Mon Sep 17 00:00:00 2001 From: Fritz Elfert Date: Mon, 31 Jul 2000 03:12:38 +0000 Subject: Applied mjg-0.6 patch. Started adding kdoc compliant documentation comments. Added PsiTime --- lib/rfsv16.cc | 432 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 304 insertions(+), 128 deletions(-) (limited to 'lib/rfsv16.cc') diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc index 9ee24f2..f71be9f 100644 --- a/lib/rfsv16.cc +++ b/lib/rfsv16.cc @@ -37,6 +37,8 @@ #include "ppsocket.h" #include "bufferarray.h" +#define RFSV16_MAXDATALEN 852 // 640 + rfsv16::rfsv16(ppsocket *_skt) : serNum(0) { skt = _skt; @@ -57,7 +59,6 @@ rfsv16::~rfsv16() void rfsv16:: reconnect() { -cerr << "rfsv16::reconnect" << endl; skt->closeSocket(); skt->reconnect(); serNum = 0; @@ -68,7 +69,6 @@ cerr << "rfsv16::reconnect" << endl; void rfsv16:: reset() { -cerr << "rfsv16::reset" << endl; bufferStore a; status = E_PSI_FILE_DISC; a.addStringT(getConnectName()); @@ -91,7 +91,7 @@ getStatus() const char *rfsv16:: getConnectName() { - return "SYS$RFSV.*"; + return "SYS$RFSV"; } int rfsv16:: @@ -148,14 +148,10 @@ fopen(long attr, const char *name, long &handle) return E_PSI_FILE_DISC; long res = getResponse(a); - // cerr << "fopen, getword 0 is " << hex << setw(2) << a.getWord(0) << endl; - // cerr << "fopen, getlen is " << hex << setw(2) << a.getLen() << endl; - // cerr << "fopen, res is " << hex << setw(2) << res << endl; - if (!res && a.getLen() == 4 && a.getWord(0) == 0) { - handle = (long)a.getWord(2); + if (res == 0) { + handle = (long)a.getWord(0); return 0; } - // cerr << "fopen: Unknown response (" << attr << "," << name << ") " << a < 16) { int version = a.getWord(0); if (version != 2) { @@ -242,7 +248,7 @@ dir(const char *dirName, bufferArray * files) temp.addDWord(size); temp.addDWord((long)status); temp.addStringT(s); - files->pushBuffer(temp); + files->append(temp); } } if ((short int)res == E_PSI_FILE_EOF) @@ -300,15 +306,13 @@ cerr << "rfsv16::fgetmtime" << endl; return E_PSI_FILE_DISC; long res = getResponse(a); - if (res != 0) + if (res != 0) { + cerr << "fgetmtime: Error " << res << " on file " << name << endl; return res; - if (a.getLen() == 2) { - cerr << "fgetmtime: Error " << a.getWord(0) << " on file " << name << endl; - return 1; } - else if (a.getLen() == 18 && a.getWord(0) == 0) { - *mtime = a.getDWord(10); - return a.getWord(0); + else if (a.getLen() == 16) { + *mtime = a.getDWord(8); + return res; } cerr << "fgetmtime: Unknown response (" << name << ") " << a < 16) { int version = a.getWord(0); if (version != 2) { @@ -475,7 +475,7 @@ devlist(long *devbits) // Find the drive to FOPEN char name[4] = { 'x', ':', '\\', '\0' } ; - a.discardFirstBytes(8); // Result, fsys, dev, path, file, file, ending, flag + a.discardFirstBytes(6); // Result, fsys, dev, path, file, file, ending, flag /* This leaves R E M : : M : \ */ name[0] = (char) a.getByte(5); // the M long status = fopen(P_FDEVICE, name, fileHandle); @@ -491,7 +491,6 @@ devlist(long *devbits) res = getResponse(a); if (res) break; - a.discardFirstBytes(2); // Result int version = a.getWord(0); if (version != 2) { cerr << "devlist: not version 2" << endl; @@ -551,7 +550,6 @@ devinfo(int devnum, long *vfree, long *vtotal, long *vattr, // cerr << "devinfo STATUSDEVICE res is " << dec << (signed short int) res << endl; return NULL; } - a.discardFirstBytes(2); // Result int type = a.getWord(2); int changeable = a.getWord(4); long size = a.getDWord(6); @@ -571,14 +569,24 @@ devinfo(int devnum, long *vfree, long *vtotal, long *vattr, bool rfsv16:: sendCommand(enum commands cc, bufferStore & data) { + if (status == E_PSI_FILE_DISC) { + reconnect(); + if (status == E_PSI_FILE_DISC) + return FALSE; + } + bool result; bufferStore a; a.addWord(cc); a.addWord(data.getLen()); a.addBuff(data); result = skt->sendBufferStore(a); + if (!result) { + reconnect(); + result = skt->sendBufferStore(a); if (!result) status = E_PSI_FILE_DISC; + } return result; } @@ -589,17 +597,22 @@ getResponse(bufferStore & data) // getWord(2) is the size field // which is the body of the response not counting the command (002a) and // the size word. - if (skt->getBufferStore(data) == 1 && - data.getWord(0) == 0x2a && + if (skt->getBufferStore(data) != 1) { + cerr << "rfsv16::getResponse: duff response. " + "getBufferStore failed." << endl; + } else if (data.getWord(0) == 0x2a && data.getWord(2) == data.getLen()-4) { - data.discardFirstBytes(4); - long ret = data.getWord(0); + long ret = (short)data.getWord(4); + data.discardFirstBytes(6); return ret; - } else - status = E_PSI_FILE_DISC; + } else { cerr << "rfsv16::getResponse: duff response. Size field:" << -data.getWord(2) << " Frame size:" << data.getLen()-4 << " Result field:" << -data.getWord(4) << endl; + data.getWord(2) << " Frame size:" << + data.getLen()-4 << " Result field:" << + data.getWord(4) << endl; + } + + status = E_PSI_FILE_DISC; return status; } @@ -614,61 +627,88 @@ cerr << "rfsv16::opErr 0x" << hex << setfill('0') << setw(4) long rfsv16:: fread(long handle, unsigned char *buf, long len) { -cerr << "rfsv16::fread ***" << endl; + long res; + long count = 0; + + while (count < len) { bufferStore a; - long remaining = len; - // Read in blocks of 291 bytes; the maximum payload for an RFSV frame. - // ( As seen in traces ) - this isn't optimal: RFSV can handle - // fragmentation of frames, where only the first FREAD RESPONSE frame - // has a RESPONSE (00 2A), SIZE and RESULT field. Every subsequent frame + + // Read in blocks of 291 bytes; the maximum payload for + // an RFSV frame. ( As seen in traces ) - this isn't optimal: + // RFSV can handle fragmentation of frames, where only the + // first FREAD RESPONSE frame has a RESPONSE (00 2A), SIZE + // and RESULT field. Every subsequent frame // just has data, 297 bytes (or less) of it. - const int maxblock = 291; - long readsofar = 0; - while (remaining) { - long thisblock = (remaining > maxblock) ? maxblock : remaining; -cerr << "fread: " << dec << remaining << " bytes remain. This block is " << thisblock -<< " bytes." << endl; - a.init(); a.addWord(handle); - a.addWord(thisblock); + a.addWord((len - count) > RFSV16_MAXDATALEN + ? RFSV16_MAXDATALEN + : (len - count)); sendCommand(FREAD, a); - long res = getResponse(a); - remaining -= a.getLen(); -// copy the data to buf + res = getResponse(a); -cerr << "fread getResponse returned " << dec<< (signed short int) res << " data: " << a << dec < RFSV16_MAXDATALEN + ? RFSV16_MAXDATALEN + : (len - count); + a.addWord(handle); + a.addBytes(buf, nbytes); + sendCommand(FWRITE, a); + res = getResponse(a); + if (res != 0) + return res; + + count += nbytes; + buf += nbytes; + } + return count; } long rfsv16:: copyFromPsion(const char *from, const char *to, cpCallback_t cb) { -cerr << "rfsv16::copyFromPsion" << endl; long handle; long res; long len; if ((res = fopen(P_FSHARE | P_FSTREAM, from, handle)) != 0) return res; -cerr << "fopen response is " << dec << (signed short int)res << endl; ofstream op(to); if (!op) { fclose(handle); return -1; } do { - unsigned char buf[2000]; + unsigned char buf[RFSV_SENDLEN]; if ((len = fread(handle, buf, sizeof(buf))) > 0) op.write(buf, len); if (cb) { @@ -681,13 +721,12 @@ cerr << "fopen response is " << dec << (signed short int)res << endl; fclose(handle); op.close(); - return len; + return len == E_PSI_FILE_EOF ? 0 : len; } long rfsv16:: copyToPsion(const char *from, const char *to, cpCallback_t cb) { -cerr << "rfsv16::copyToPsion" << endl; long handle; long res; @@ -701,50 +740,30 @@ cerr << "rfsv16::copyToPsion" << endl; return res; } unsigned char *buff = new unsigned char[RFSV_SENDLEN]; - int total = 0; - while (ip && !ip.eof()) { + while (res >= 0 && ip && !ip.eof()) { ip.read(buff, RFSV_SENDLEN); - bufferStore tmp(buff, ip.gcount()); - int len = tmp.getLen(); - total += len; - if (len == 0) - break; - bufferStore a; - a.addDWord(handle); - a.addBuff(tmp); - if (!sendCommand(FWRITE, a)) { // FIXME: need to check params - fclose(handle); - ip.close(); - delete[]buff; - return E_PSI_FILE_DISC; + res = fwrite(handle, buff, ip.gcount()); + if (cb) + if (!cb(res)) { + res = E_PSI_FILE_CANCEL; } - res = getResponse(a); - if (res) { - fclose(handle); - ip.close(); - delete[]buff; - return res; } - if (cb) { - if (!cb(len)) { - fclose(handle); - ip.close(); + delete[]buff; - return E_PSI_FILE_CANCEL; - } - } - } fclose(handle); ip.close(); - delete[]buff; return 0; } long rfsv16:: fsetsize(long handle, long size) { -cerr << "rfsv16::fsetsize ***" << endl; - return 0; + bufferStore a; + a.addWord(handle); + a.addDWord(size); + if (!sendCommand(FSETEOF, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } /* @@ -755,8 +774,92 @@ cerr << "rfsv16::fsetsize ***" << endl; long rfsv16:: fseek(long handle, long pos, long mode) { -cerr << "rfsv16::fseek ***" << endl; - return 0; + bufferStore a; + long res; + long savpos = 0; + long realpos; + long calcpos = 0; + +/* + seek-parameter for psion: + dword position + dword handle + dword mode + 1 = from start + 2 = from current pos + 3 = from end + ??no more?? 4 = sense recpos + ??no more?? 5 = set recpos + ??no more?? 6 = text-rewind + */ + + if ((mode < PSI_SEEK_SET) || (mode > PSI_SEEK_END)) + return E_PSI_GEN_ARG; + + if ((mode == PSI_SEEK_CUR) && (pos >= 0)) { + /* get and save current position */ + a.init(); + a.addWord(handle); + a.addDWord(0); + a.addWord(PSI_SEEK_CUR); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != 0) + return res; + savpos = a.getDWord(0); + if (pos == 0) + return savpos; + } + if ((mode == PSI_SEEK_END) && (pos >= 0)) { + /* get and save end position */ + a.init(); + a.addWord(handle); + a.addDWord(0); + a.addWord(PSI_SEEK_END); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != 0) + return res; + savpos = a.getDWord(0); + if (pos == 0) + return savpos; + } + /* Now the real seek */ + a.addWord(handle); + a.addDWord(pos); + a.addWord(mode); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != 0) + return res; + realpos = a.getDWord(0); + switch (mode) { + case PSI_SEEK_SET: + calcpos = pos; + break; + case PSI_SEEK_CUR: + calcpos = savpos + pos; + break; + case PSI_SEEK_END: + return realpos; + break; + } + if (calcpos > realpos) { + /* Beyond end of file */ + res = fsetsize(handle, calcpos); + if (res != 0) + return res; + a.init(); + a.addWord(handle); + a.addDWord(calcpos); + a.addWord(PSI_SEEK_SET); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != 0) + return res; + realpos = a.getDWord(0); + } + return realpos; } long rfsv16:: @@ -771,11 +874,11 @@ mkdir(const char* dirName) // and this needs sending in the length word. sendCommand(MKDIR, a); long res = getResponse(a); - if (!res && a.getLen() == 2) { + if (!res) { // Correct response - return a.getWord(0); + return res; } - cerr << "Unknown response from mkdir "<< a <