/* Put a string to the file. This will put the file into buffered mode. */ PUBLIC ssize mprPutFileString(MprFile *file, cchar *str) { MprBuf *bp; ssize total, bytes, count; char *buf; assert(file); count = slen(str); /* Buffer output and flush when full. */ if (file->buf == 0) { file->buf = mprCreateBuf(ME_MAX_BUFFER, 0); if (file->buf == 0) { return MPR_ERR_CANT_ALLOCATE; } } bp = file->buf; if (mprGetBufLength(bp) > 0 && mprGetBufSpace(bp) < count) { mprFlushFile(file); } total = 0; buf = (char*) str; while (count > 0) { bytes = mprPutBlockToBuf(bp, buf, count); if (bytes < 0) { return MPR_ERR_CANT_ALLOCATE; } else if (bytes == 0) { if (mprFlushFile(file) < 0) { return MPR_ERR_CANT_WRITE; } continue; } count -= bytes; buf += bytes; total += bytes; file->pos += (MprOff) bytes; } return total; }
PUBLIC MprOff mprSeekFile(MprFile *file, int seekType, MprOff pos) { MprFileSystem *fs; assert(file); fs = file->fileSystem; if (file->buf) { if (! (seekType == SEEK_CUR && pos == 0)) { /* Discard buffering as we may be seeking outside the buffer. OPT. Could be smarter about this and preserve the buffer. */ if (file->mode & (O_WRONLY | O_RDWR)) { if (mprFlushFile(file) < 0) { return MPR_ERR_CANT_WRITE; } } if (file->buf) { mprFlushBuf(file->buf); } } } if (seekType == SEEK_SET) { file->pos = pos; } else if (seekType == SEEK_CUR) { file->pos += pos; } else { file->pos = fs->seekFile(file, SEEK_END, 0); } if (fs->seekFile(file, SEEK_SET, file->pos) != file->pos) { return MPR_ERR; } if (file->mode & (O_WRONLY | O_RDWR)) { if (file->pos > file->size) { file->size = file->pos; } } return file->pos; }
PUBLIC ssize mprWriteFile(MprFile *file, cvoid *buf, ssize count) { MprFileSystem *fs; MprBuf *bp; ssize bytes, written; assert(file); if (file == 0) { return MPR_ERR_BAD_HANDLE; } fs = file->fileSystem; bp = file->buf; written = 0; while (count > 0) { if (bp == 0) { if ((bytes = fs->writeFile(file, buf, count)) < 0) { return bytes; } } else { if ((bytes = mprPutBlockToBuf(bp, buf, count)) < 0) { return bytes; } if (bytes != count) { mprFlushFile(file); } } count -= bytes; written += bytes; buf = (char*) buf + bytes; } file->pos += (MprOff) written; if (file->pos > file->size) { file->size = file->pos; } return written; }
/* Close the file and free up all associated resources. function close(): void */ static EjsObj *closeFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv) { if (fp->mode & EJS_FILE_OPEN && fp->mode & EJS_FILE_WRITE) { if (mprFlushFile(fp->file) < 0) { if (ejs) { ejsThrowIOError(ejs, "Cannot flush file data"); } return 0; } } if (fp->file) { mprCloseFile(fp->file); fp->file = 0; } #if ME_CC_MMU && FUTURE if (fp->mapped) { unmapFile(fp); fp->mapped = 0; } #endif fp->mode = 0; fp->modeString = 0; return 0; }
PUBLIC void mprDisableFileBuffering(MprFile *file) { mprFlushFile(file); file->buf = 0; }