?? stream.cc
字號:
/* * HT Editor * stream.cc * * Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <cerrno>#include <climits>#include <new>#include <cstring>#include <cstdio>#include <cstdlib>#include <fcntl.h>#include <sys/stat.h> /* for mode definitions */#include <sys/types.h> /* for mode definitions */#include <unistd.h>#include "htdebug.h"#include "except.h"#include "snprintf.h"#include "stream.h"#include "strtools.h"#include "tools.h"/* * Listener */#if 0class Listener: public Object {public: StreamEventListener *listener; StreamEvent notify_mask; Listener(StreamEventListener *l, StreamEvent nmask) { listener = l; notify_mask = nmask; }/* extends Object */ virtual int compareTo(const Object *obj) const { return ((Listener*)obj)->listener == listener ? 0 : 1; }};#endif/* * Stream */#define STREAM_COPYBUF_SIZE (64*1024)Stream::Stream(){ mAccessMode = IOAM_NULL;// mListeners = NULL;}/*Stream::~Stream(){// delete mListeners;}*//*void Stream::addEventListener(StreamEventListener *l, StreamEvent mask){ if (!mListeners) mListeners = new Array(true); *mListeners += new Listener(l, mask);}*/void Stream::checkAccess(IOAccessMode mask){ if ((mAccessMode & mask) != mask) throw IOException(EACCES);}/** * Copy (whole) stream to another (i.e. copy until EOF) * @param stream Stream to copy this Stream to * @returns number of bytes copied */FileOfs Stream::copyAllTo(Stream *stream){ byte *buf = new byte[STREAM_COPYBUF_SIZE]; FileOfs result = 0; uint r, t; do { uint k = STREAM_COPYBUF_SIZE; r = read(buf, k); assert(r <= k); t = stream->write(buf, r); assert(t <= r); result += t; if (t != k) break; } while (t); delete[] buf; return result;}/** * Copy (partial) stream to another * @param stream Stream to copy this Stream to * @param count maximum number of bytes to copy * @returns number of bytes copied */FileOfs Stream::copyTo(Stream *stream, FileOfs count){ byte *buf = new byte[STREAM_COPYBUF_SIZE]; FileOfs result = 0; while (count) { uint k = STREAM_COPYBUF_SIZE; if (k > count) k = count; uint r = read(buf, k); assert(r <= k); uint t = stream->write(buf, r); assert(t <= r); count -= t; result += t; if (t != k) break; } delete[] buf; return result;}/** * Get access-mode */IOAccessMode Stream::getAccessMode() const{ return mAccessMode;}/** * Get descriptive name */String &Stream::getDesc(String &result) const{ result = ""; return result;}/*void Stream::notifyListeners(StreamEvent event,...){ if (!mListeners) return; foreach(Listener, l, *mListeners, if (l->notify_mask & event) { va_list ap; va_start(ap, event); l->listener->handleEvent(event, ap); va_end(ap); } );}*//** * Set access-mode */int Stream::setAccessMode(IOAccessMode mode){ mAccessMode = mode; return 0;}/** * Set access-mode, throw IOException if unsuccessful */void Stream::setAccessModex(IOAccessMode mode){ int e = setAccessMode(mode); if (e) throw IOException(e);}/** * Read from stream. * Read up to <i>size</i> bytes from stream into <i>buf</i>. * If less than <i>size</i> bytes are read, the exact number is * returned and a (temporary) end-of-file (EOF) is encountered. * * @param buf pointer to bytes to read * @param size number of bytes to read * @returns number of bytes read * @throws IOException */uint Stream::read(void *buf, uint size){ return 0;}/** * Exact read from stream. * Read exactly <i>size</i> bytes from stream into <i>buf</i>. * If less than <i>size</i> bytes are read, IOException is thrown. * * @param buf pointer to bytes to read * @param size number of bytes to read * @throws IOException *///#include "snprintf.h" void Stream::readx(void *buf, uint size){// File *f = dynamic_cast<File*>(this);// FileOfs t = f ? f->tell() : 0; if (read(buf, size) != size) {// FileOfs sz = f ? f->getSize() : mkfofs(0);// ht_printf("readx failed, ofs = 0x%qx, size = %d (file size 0x%qx)\n", &t, size, &sz); throw EOFException(); } }/*void Stream::removeEventListener(StreamEventListener *l){ Listener t(l, SEV_NULL); bool b = (*mListeners -= &t); assert(b);}*//** * Write to stream. * Write up to <i>size</i> bytes from <i>buf</i> into stream. * If less than <i>size</i> bytes are written, the exact number is * returned and a (temporary) end-of-file (EOF) is encountered. * * @param buf pointer to bytes to write * @param size number of bytes to write * @returns number of bytes written * @throws IOException */uint Stream::write(const void *buf, uint size){ return 0;}/** * Exact write to stream. * Write exactly <i>size</i> bytes from <i>buf</i> into stream. * If less than <i>size</i> bytes are written, IOException is thrown. * * @param buf pointer to bytes to write * @param size number of bytes to write * @throws IOException */void Stream::writex(const void *buf, uint size){ if (write(buf, size) != size) throw EOFException();}// FIXME: more dynamical solution appreciated#define REASONABLE_STRING_LIMIT 1024 char *Stream::readstrz(){ /* get string size */ char buf[REASONABLE_STRING_LIMIT]; int z = 0; while (1) { readx(buf+z, 1); z++; if (z >= REASONABLE_STRING_LIMIT) { z = REASONABLE_STRING_LIMIT; break; } if (buf[z-1] == 0) break; } if (!z) return NULL; char *str = ht_malloc(z); if (!str) throw std::bad_alloc(); memcpy(str, buf, z-1); str[z-1] = 0; return str;}bool Stream::readStringz(String &s){ String r; try { while (1) { char c; readx(&c, 1); if (!c) break; r.appendChar(c); } s.grab(r); return true; } catch (const EOFException &) { return false; }}void Stream::writestrz(const char *str){ if (str) { writex(str, strlen(str)+1); } else { byte n = 0; writex(&n, 1); }}char *Stream::readstrp(){ uint8 l; readx(&l, 1); char *str = ht_malloc(l+1); if (!str) throw std::bad_alloc(); try { readx(str, l); } catch (...) { free(str); throw; } str[l] = 0; return str;}char *Stream::readstrl(){ uint32 l = 0; for (int i=0; i<4; i++) { uint8 b; readx(&b, 1); l <<= 7; l |= b & 0x7f; if (!(b & 0x80)) break; } char *str = ht_malloc(l+1); if (!str) throw std::bad_alloc(); try { readx(str, l); } catch (...) { free(str); throw; } str[l] = 0; return str;}void Stream::writestrl(const char *str){ uint8 b; uint32 len = strlen(str); if (!len) { b = 0; writex(&b, 1); return; } int i = 4; uint32 a = 0xfe000000; while (!(len & a)) { a >>= 7; i--; } len <<= (4-i)*7; while (i--) { a = i ? 0x80 : 0; b = ((len & 0xfe000000) >> (3 * 7)) | a; len <<= 7; writex(&b, 1); return; }}void Stream::writestrp(const char *str){ unsigned char l = str ? strlen(str) : 0; writex(&l, 1); writex(str, l);}char *Stream::readstrw(){ short t; byte lbuf[2]; readx(lbuf, 2); int l = lbuf[0] | lbuf[1] << 8; char *a = ht_malloc(l+1); if (!a) throw std::bad_alloc(); for (int i=0; i < l; i++) { // FIXME: this looks wrong readx(&t, 2); a[i] = (char)t; } a[l] = 0; return a;}void Stream::writestrw(const char *str){ /* FIXME: someone implement me ? */ throw NotImplementedException(HERE);}/* * StreamLayer */StreamLayer::StreamLayer(Stream *s, bool own) : Stream(){ mStream = s; mOwnStream = own;}StreamLayer::~StreamLayer(){ if (mOwnStream) delete mStream;}IOAccessMode StreamLayer::getAccessMode() const{ return mStream->getAccessMode();}String &StreamLayer::getDesc(String &result) const{ return mStream->getDesc(result);}int StreamLayer::setAccessMode(IOAccessMode mode){ return mStream->setAccessMode(mode);}uint StreamLayer::read(void *buf, uint size){ return mStream->read(buf, size);}uint StreamLayer::write(const void *buf, uint size){ return mStream->write(buf, size);}Stream *StreamLayer::getLayered() const{ return mStream;}void StreamLayer::setLayered(Stream *newLayered, bool ownNewLayered){ mStream = newLayered; mOwnStream = ownNewLayered;}/* * ObjectStream */ObjectStream::ObjectStream(Stream *s, bool own_s) : StreamLayer(s, own_s){}void ObjectStream::putCommentf(const char *comment_format, ...){ char buf[1024]; va_list arg; va_start(arg, comment_format); ht_vsnprintf(buf, sizeof buf, comment_format, arg); va_end(arg); putComment(buf);}/** * A object-stream-layer. */ObjectStreamLayer::ObjectStreamLayer(ObjectStream *aObjStream, bool own_ostream): ObjectStream(aObjStream, own_ostream){ mObjStream = aObjStream;}void ObjectStreamLayer::getBinary(void *buf, uint size, const char *desc){ return mObjStream->getBinary(buf, size, desc);}bool ObjectStreamLayer::getBool(const char *desc){ return mObjStream->getBool(desc);}uint64 ObjectStreamLayer::getInt(uint size, const char *desc){ return mObjStream->getInt(size, desc);}Object *ObjectStreamLayer::getObjectInternal(const char *name, ObjectID id){ return mObjStream->getObjectInternal(name, id);}char *ObjectStreamLayer::getString(const char *desc){ return mObjStream->getString(desc);}byte *ObjectStreamLayer::getLenString(int &len, const char *desc){ return mObjStream->getLenString(len, desc);}void ObjectStreamLayer::putBinary(const void *mem, uint size, const char *desc){ return mObjStream->putBinary(mem, size, desc);}void ObjectStreamLayer::putBool(bool b, const char *desc){ return mObjStream->putBool(b, desc);}void ObjectStreamLayer::putComment(const char *comment){ return mObjStream->putComment(comment);}void ObjectStreamLayer::putInt(uint64 i, uint size, const char *desc, uint int_fmt_hint){ return mObjStream->putInt(i, size, desc, int_fmt_hint);}void ObjectStreamLayer::putObject(const Object *object, const char *name, ObjectID id){ return mObjStream->putObject(object, name, id);}void ObjectStreamLayer::putSeparator(){ return mObjStream->putSeparator();}void ObjectStreamLayer::putString(const char *string, const char *desc){ return mObjStream->putString(string, desc);}void ObjectStreamLayer::putLenString(const byte *string, int len, const char *desc){ return mObjStream->putLenString(string, len, desc);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -