diff options
author | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
commit | 302bf1b523012e11b60425d6eee1221ebc2724eb (patch) | |
tree | b191a895f8716efcbe42f454f37597a545a6f421 /db/mork/src/morkFile.cpp | |
parent | 21b3f6247403c06f85e1f45d219f87549862198f (diff) | |
download | UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.gz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.lz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.xz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.zip |
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
Diffstat (limited to 'db/mork/src/morkFile.cpp')
-rw-r--r-- | db/mork/src/morkFile.cpp | 874 |
1 files changed, 874 insertions, 0 deletions
diff --git a/db/mork/src/morkFile.cpp b/db/mork/src/morkFile.cpp new file mode 100644 index 000000000..040d1a8dc --- /dev/null +++ b/db/mork/src/morkFile.cpp @@ -0,0 +1,874 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MDB_ +#include "mdb.h" +#endif + +#ifndef _MORK_ +#include "mork.h" +#endif + +#ifndef _MORKNODE_ +#include "morkNode.h" +#endif + +#ifndef _MORKENV_ +#include "morkEnv.h" +#endif + +#ifndef _MORKFILE_ +#include "morkFile.h" +#endif + +#ifdef MORK_WIN +#include "io.h" +#include <windows.h> +#endif + +//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void +morkFile::CloseMorkNode(morkEnv* ev) // CloseFile() only if open +{ + if ( this->IsOpenNode() ) + { + this->MarkClosing(); + this->CloseFile(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkFile::~morkFile() // assert CloseFile() executed earlier +{ + MORK_ASSERT(mFile_Frozen==0); + MORK_ASSERT(mFile_DoTrace==0); + MORK_ASSERT(mFile_IoOpen==0); + MORK_ASSERT(mFile_Active==0); +} + +/*public non-poly*/ +morkFile::morkFile(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) +: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) +, mFile_Frozen( 0 ) +, mFile_DoTrace( 0 ) +, mFile_IoOpen( 0 ) +, mFile_Active( 0 ) + +, mFile_SlotHeap( 0 ) +, mFile_Name( 0 ) +, mFile_Thief( 0 ) +{ + if ( ev->Good() ) + { + if ( ioSlotHeap ) + { + nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mFile_SlotHeap); + if ( ev->Good() ) + mNode_Derived = morkDerived_kFile; + } + else + ev->NilPointerError(); + } +} + +NS_IMPL_ISUPPORTS_INHERITED(morkFile, morkObject, nsIMdbFile) +/*public non-poly*/ void +morkFile::CloseFile(morkEnv* ev) // called by CloseMorkNode(); +{ + if ( this->IsNode() ) + { + mFile_Frozen = 0; + mFile_DoTrace = 0; + mFile_IoOpen = 0; + mFile_Active = 0; + + if ( mFile_Name ) + this->SetFileName(ev, (const char*) 0); + + nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mFile_SlotHeap); + nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mFile_Thief); + + this->MarkShut(); + } + else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +/*static*/ morkFile* +morkFile::OpenOldFile(morkEnv* ev, nsIMdbHeap* ioHeap, + const char* inFilePath, mork_bool inFrozen) + // Choose some subclass of morkFile to instantiate, in order to read + // (and write if not frozen) the file known by inFilePath. The file + // returned should be open and ready for use, and presumably positioned + // at the first byte position of the file. The exact manner in which + // files must be opened is considered a subclass specific detail, and + // other portions or Mork source code don't want to know how it's done. +{ + return morkStdioFile::OpenOldStdioFile(ev, ioHeap, inFilePath, inFrozen); +} + +/*static*/ morkFile* +morkFile::CreateNewFile(morkEnv* ev, nsIMdbHeap* ioHeap, + const char* inFilePath) + // Choose some subclass of morkFile to instantiate, in order to read + // (and write if not frozen) the file known by inFilePath. The file + // returned should be created and ready for use, and presumably positioned + // at the first byte position of the file. The exact manner in which + // files must be opened is considered a subclass specific detail, and + // other portions or Mork source code don't want to know how it's done. +{ + return morkStdioFile::CreateNewStdioFile(ev, ioHeap, inFilePath); +} + +void +morkFile::NewMissingIoError(morkEnv* ev) const +{ + ev->NewError("file missing io"); +} + +/*static*/ void +morkFile::NonFileTypeError(morkEnv* ev) +{ + ev->NewError("non morkFile"); +} + +/*static*/ void +morkFile::NilSlotHeapError(morkEnv* ev) +{ + ev->NewError("nil mFile_SlotHeap"); +} + +/*static*/ void +morkFile::NilFileNameError(morkEnv* ev) +{ + ev->NewError("nil mFile_Name"); +} + +void +morkFile::SetThief(morkEnv* ev, nsIMdbFile* ioThief) +{ + nsIMdbFile_SlotStrongFile(ioThief, ev, &mFile_Thief); +} + +void +morkFile::SetFileName(morkEnv* ev, const char* inName) // inName can be nil +{ + nsIMdbHeap* heap = mFile_SlotHeap; + if ( heap ) + { + char* name = mFile_Name; + if ( name ) + { + mFile_Name = 0; + ev->FreeString(heap, name); + } + if ( ev->Good() && inName ) + mFile_Name = ev->CopyString(heap, inName); + } + else + this->NilSlotHeapError(ev); +} + +void +morkFile::NewFileDownError(morkEnv* ev) const +// call NewFileDownError() when either IsOpenAndActiveFile() +// is false, or when IsOpenActiveAndMutableFile() is false. +{ + if ( this->IsOpenNode() ) + { + if ( this->FileActive() ) + { + if ( this->FileFrozen() ) + { + ev->NewError("file frozen"); + } + else + ev->NewError("unknown file problem"); + } + else + ev->NewError("file not active"); + } + else + ev->NewError("file not open"); +} + +void +morkFile::NewFileErrnoError(morkEnv* ev) const +// call NewFileErrnoError() to convert std C errno into AB fault +{ + const char* errnoString = strerror(errno); + ev->NewError(errnoString); // maybe pass value of strerror() instead +} + +// ````` ````` ````` ````` newlines ````` ````` ````` ````` + +#if defined(MORK_MAC) + static const char morkFile_kNewlines[] = + "\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015"; +# define morkFile_kNewlinesCount 16 +#else +# if defined(MORK_WIN) + static const char morkFile_kNewlines[] = + "\015\012\015\012\015\012\015\012\015\012\015\012\015\012\015\012"; +# define morkFile_kNewlinesCount 8 +# else +# ifdef MORK_UNIX + static const char morkFile_kNewlines[] = + "\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012"; +# define morkFile_kNewlinesCount 16 +# endif /* MORK_UNIX */ +# endif /* MORK_WIN */ +#endif /* MORK_MAC */ + +mork_size +morkFile::WriteNewlines(morkEnv* ev, mork_count inNewlines) + // WriteNewlines() returns the number of bytes written. +{ + mork_size outSize = 0; + while ( inNewlines && ev->Good() ) // more newlines to write? + { + mork_u4 quantum = inNewlines; + if ( quantum > morkFile_kNewlinesCount ) + quantum = morkFile_kNewlinesCount; + + mork_size quantumSize = quantum * mork_kNewlineSize; + mdb_size bytesWritten; + this->Write(ev->AsMdbEnv(), morkFile_kNewlines, quantumSize, &bytesWritten); + outSize += quantumSize; + inNewlines -= quantum; + } + return outSize; +} + +NS_IMETHODIMP +morkFile::Eof(nsIMdbEnv* mev, mdb_pos* outPos) +{ + nsresult outErr = NS_OK; + mdb_pos pos = -1; + morkEnv *ev = morkEnv::FromMdbEnv(mev); + pos = Length(ev); + outErr = ev->AsErr(); + if ( outPos ) + *outPos = pos; + return outErr; +} + +NS_IMETHODIMP +morkFile::Get(nsIMdbEnv* mev, void* outBuf, mdb_size inSize, + mdb_pos inPos, mdb_size* outActualSize) +{ + nsresult rv = NS_OK; + morkEnv *ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + mdb_pos outPos; + Seek(mev, inPos, &outPos); + if ( ev->Good() ) + rv = Read(mev, outBuf, inSize, outActualSize); + } + return rv; +} + +NS_IMETHODIMP +morkFile::Put(nsIMdbEnv* mev, const void* inBuf, mdb_size inSize, + mdb_pos inPos, mdb_size* outActualSize) +{ + nsresult outErr = NS_OK; + *outActualSize = 0; + morkEnv *ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + mdb_pos outPos; + + Seek(mev, inPos, &outPos); + if ( ev->Good() ) + Write(mev, inBuf, inSize, outActualSize); + outErr = ev->AsErr(); + } + return outErr; +} + +// { ----- begin path methods ----- +NS_IMETHODIMP +morkFile::Path(nsIMdbEnv* mev, mdbYarn* outFilePath) +{ + nsresult outErr = NS_OK; + if ( outFilePath ) + outFilePath->mYarn_Fill = 0; + morkEnv *ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + ev->StringToYarn(GetFileNameString(), outFilePath); + outErr = ev->AsErr(); + } + return outErr; +} + +// } ----- end path methods ----- + +// { ----- begin replacement methods ----- + + +NS_IMETHODIMP +morkFile::Thief(nsIMdbEnv* mev, nsIMdbFile** acqThief) +{ + nsresult outErr = NS_OK; + nsIMdbFile* outThief = 0; + morkEnv *ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + outThief = GetThief(); + NS_IF_ADDREF(outThief); + outErr = ev->AsErr(); + } + if ( acqThief ) + *acqThief = outThief; + return outErr; +} + +// } ----- end replacement methods ----- + +// { ----- begin versioning methods ----- + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void +morkStdioFile::CloseMorkNode(morkEnv* ev) // CloseStdioFile() only if open +{ + if ( this->IsOpenNode() ) + { + this->MarkClosing(); + this->CloseStdioFile(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkStdioFile::~morkStdioFile() // assert CloseStdioFile() executed earlier +{ + if (mStdioFile_File) + CloseStdioFile(mMorkEnv); + MORK_ASSERT(mStdioFile_File==0); +} + +/*public non-poly*/ void +morkStdioFile::CloseStdioFile(morkEnv* ev) // called by CloseMorkNode(); +{ + if ( this->IsNode() ) + { + if ( mStdioFile_File && this->FileActive() && this->FileIoOpen() ) + { + this->CloseStdio(ev); + } + + mStdioFile_File = 0; + + this->CloseFile(ev); + this->MarkShut(); + } + else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +// compatible with the morkFile::MakeFile() entry point + +/*static*/ morkStdioFile* +morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap, + const char* inFilePath, mork_bool inFrozen) +{ + morkStdioFile* outFile = 0; + if ( ioHeap && inFilePath ) + { + const char* mode = (inFrozen)? "rb" : "rb+"; + outFile = new(*ioHeap, ev) + morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode); + + if ( outFile ) + { + outFile->SetFileFrozen(inFrozen); + } + } + else + ev->NilPointerError(); + + return outFile; +} + +/*static*/ morkStdioFile* +morkStdioFile::CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap, + const char* inFilePath) +{ + morkStdioFile* outFile = 0; + if ( ioHeap && inFilePath ) + { + const char* mode = "wb+"; + outFile = new(*ioHeap, ev) + morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode); + } + else + ev->NilPointerError(); + + return outFile; +} + + + +NS_IMETHODIMP +morkStdioFile::BecomeTrunk(nsIMdbEnv* ev) + // If this file is a file version branch created by calling AcquireBud(), + // BecomeTrunk() causes this file's content to replace the original + // file's content, typically by assuming the original file's identity. +{ + return Flush(ev); +} + +NS_IMETHODIMP +morkStdioFile::AcquireBud(nsIMdbEnv * mdbev, nsIMdbHeap* ioHeap, nsIMdbFile **acquiredFile) + // AcquireBud() starts a new "branch" version of the file, empty of content, + // so that a new version of the file can be written. This new file + // can later be told to BecomeTrunk() the original file, so the branch + // created by budding the file will replace the original file. Some + // file subclasses might initially take the unsafe but expedient + // approach of simply truncating this file down to zero length, and + // then returning the same morkFile pointer as this, with an extra + // reference count increment. Note that the caller of AcquireBud() is + // expected to eventually call CutStrongRef() on the returned file + // in order to release the strong reference. High quality versions + // of morkFile subclasses will create entirely new files which later + // are renamed to become the old file, so that better transactional + // behavior is exhibited by the file, so crashes protect old files. + // Note that AcquireBud() is an illegal operation on readonly files. +{ + NS_ENSURE_ARG(acquiredFile); + MORK_USED_1(ioHeap); + nsresult rv = NS_OK; + morkFile* outFile = 0; + morkEnv *ev = morkEnv::FromMdbEnv(mdbev); + + if ( this->IsOpenAndActiveFile() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { +//#ifdef MORK_WIN +// truncate(file, /*eof*/ 0); +//#else /*MORK_WIN*/ + char* name = mFile_Name; + if ( name ) + { + if ( MORK_FILECLOSE(file) >= 0 ) + { + this->SetFileActive(morkBool_kFalse); + this->SetFileIoOpen(morkBool_kFalse); + mStdioFile_File = 0; + + file = MORK_FILEOPEN(name, "wb+"); // open for write, discarding old content + if ( file ) + { + mStdioFile_File = file; + this->SetFileActive(morkBool_kTrue); + this->SetFileIoOpen(morkBool_kTrue); + this->SetFileFrozen(morkBool_kFalse); + } + else + this->new_stdio_file_fault(ev); + } + else + this->new_stdio_file_fault(ev); + } + else + this->NilFileNameError(ev); + +//#endif /*MORK_WIN*/ + + if ( ev->Good() && this->AddStrongRef(ev->AsMdbEnv()) ) + { + outFile = this; + AddRef(); + } + } + else if ( mFile_Thief ) + { + rv = mFile_Thief->AcquireBud(ev->AsMdbEnv(), ioHeap, acquiredFile); + } + else + this->NewMissingIoError(ev); + } + else this->NewFileDownError(ev); + + *acquiredFile = outFile; + return rv; +} + +mork_pos +morkStdioFile::Length(morkEnv * ev) const +{ + mork_pos outPos = 0; + + if ( this->IsOpenAndActiveFile() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { + long start = MORK_FILETELL(file); + if ( start >= 0 ) + { + long fore = MORK_FILESEEK(file, 0, SEEK_END); + if ( fore >= 0 ) + { + long eof = MORK_FILETELL(file); + if ( eof >= 0 ) + { + long back = MORK_FILESEEK(file, start, SEEK_SET); + if ( back >= 0 ) + outPos = eof; + else + this->new_stdio_file_fault(ev); + } + else this->new_stdio_file_fault(ev); + } + else this->new_stdio_file_fault(ev); + } + else this->new_stdio_file_fault(ev); + } + else if ( mFile_Thief ) + mFile_Thief->Eof(ev->AsMdbEnv(), &outPos); + else + this->NewMissingIoError(ev); + } + else this->NewFileDownError(ev); + + return outPos; +} + +NS_IMETHODIMP +morkStdioFile::Tell(nsIMdbEnv* ev, mork_pos *outPos) const +{ + nsresult rv = NS_OK; + NS_ENSURE_ARG(outPos); + morkEnv* mev = morkEnv::FromMdbEnv(ev); + if ( this->IsOpenAndActiveFile() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { + long where = MORK_FILETELL(file); + if ( where >= 0 ) + *outPos = where; + else + this->new_stdio_file_fault(mev); + } + else if ( mFile_Thief ) + mFile_Thief->Tell(ev, outPos); + else + this->NewMissingIoError(mev); + } + else this->NewFileDownError(mev); + + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Read(nsIMdbEnv* ev, void* outBuf, mork_size inSize, mork_num *outCount) +{ + nsresult rv = NS_OK; + morkEnv* mev = morkEnv::FromMdbEnv(ev); + if ( this->IsOpenAndActiveFile() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { + long count = (long) MORK_FILEREAD(outBuf, inSize, file); + if ( count >= 0 ) + { + *outCount = (mork_num) count; + } + else this->new_stdio_file_fault(mev); + } + else if ( mFile_Thief ) + mFile_Thief->Read(ev, outBuf, inSize, outCount); + else + this->NewMissingIoError(mev); + } + else this->NewFileDownError(mev); + + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Seek(nsIMdbEnv* mdbev, mork_pos inPos, mork_pos *aOutPos) +{ + mork_pos outPos = 0; + nsresult rv = NS_OK; + morkEnv *ev = morkEnv::FromMdbEnv(mdbev); + + if ( this->IsOpenOrClosingNode() && this->FileActive() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { + long where = MORK_FILESEEK(file, inPos, SEEK_SET); + if ( where >= 0 ) + outPos = inPos; + else + this->new_stdio_file_fault(ev); + } + else if ( mFile_Thief ) + mFile_Thief->Seek(mdbev, inPos, aOutPos); + else + this->NewMissingIoError(ev); + } + else this->NewFileDownError(ev); + + *aOutPos = outPos; + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Write(nsIMdbEnv* mdbev, const void* inBuf, mork_size inSize, mork_size *aOutSize) +{ + mork_num outCount = 0; + nsresult rv = NS_OK; + morkEnv *ev = morkEnv::FromMdbEnv(mdbev); + if ( this->IsOpenActiveAndMutableFile() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { + fwrite(inBuf, 1, inSize, file); + if ( !ferror(file) ) + outCount = inSize; + else + this->new_stdio_file_fault(ev); + } + else if ( mFile_Thief ) + mFile_Thief->Write(mdbev, inBuf, inSize, &outCount); + else + this->NewMissingIoError(ev); + } + else this->NewFileDownError(ev); + + *aOutSize = outCount; + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Flush(nsIMdbEnv* mdbev) +{ + morkEnv *ev = morkEnv::FromMdbEnv(mdbev); + if ( this->IsOpenOrClosingNode() && this->FileActive() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( file ) + { + MORK_FILEFLUSH(file); + + } + else if ( mFile_Thief ) + mFile_Thief->Flush(mdbev); + else + this->NewMissingIoError(ev); + } + else this->NewFileDownError(ev); + return NS_OK; +} + +// ````` ````` ````` ````` ````` ````` ````` ````` +//protected: // protected non-poly morkStdioFile methods + +void +morkStdioFile::new_stdio_file_fault(morkEnv* ev) const +{ + FILE* file = (FILE*) mStdioFile_File; + + int copyErrno = errno; // facilitate seeing error in debugger + + // bunch of stuff not ported here + if ( !copyErrno && file ) + { + copyErrno = ferror(file); + errno = copyErrno; + } + + this->NewFileErrnoError(ev); +} + +// ````` ````` ````` ````` ````` ````` ````` ````` +//public: // public non-poly morkStdioFile methods + + +/*public non-poly*/ +morkStdioFile::morkStdioFile(morkEnv* ev, + const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) +: morkFile(ev, inUsage, ioHeap, ioSlotHeap) +, mStdioFile_File( 0 ) +{ + if ( ev->Good() ) + mNode_Derived = morkDerived_kStdioFile; +} + +morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, + const char* inName, const char* inMode) + // calls OpenStdio() after construction +: morkFile(ev, inUsage, ioHeap, ioSlotHeap) +, mStdioFile_File( 0 ) +{ + if ( ev->Good() ) + this->OpenStdio(ev, inName, inMode); +} + +morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, + void* ioFile, const char* inName, mork_bool inFrozen) + // calls UseStdio() after construction +: morkFile(ev, inUsage, ioHeap, ioSlotHeap) +, mStdioFile_File( 0 ) +{ + if ( ev->Good() ) + this->UseStdio(ev, ioFile, inName, inFrozen); +} + +void +morkStdioFile::OpenStdio(morkEnv* ev, const char* inName, const char* inMode) + // Open a new FILE with name inName, using mode flags from inMode. +{ + if ( ev->Good() ) + { + if ( !inMode ) + inMode = ""; + + mork_bool frozen = (*inMode == 'r'); // cursory attempt to note readonly + + if ( this->IsOpenNode() ) + { + if ( !this->FileActive() ) + { + this->SetFileIoOpen(morkBool_kFalse); + if ( inName && *inName ) + { + this->SetFileName(ev, inName); + if ( ev->Good() ) + { + FILE* file = MORK_FILEOPEN(inName, inMode); + if ( file ) + { + mStdioFile_File = file; + this->SetFileActive(morkBool_kTrue); + this->SetFileIoOpen(morkBool_kTrue); + this->SetFileFrozen(frozen); + } + else + this->new_stdio_file_fault(ev); + } + } + else ev->NewError("no file name"); + } + else ev->NewError("file already active"); + } + else this->NewFileDownError(ev); + } +} + +void +morkStdioFile::UseStdio(morkEnv* ev, void* ioFile, const char* inName, + mork_bool inFrozen) + // Use an existing file, like stdin/stdout/stderr, which should not + // have the io stream closed when the file is closed. The ioFile + // parameter must actually be of type FILE (but we don't want to make + // this header file include the stdio.h header file). +{ + if ( ev->Good() ) + { + if ( this->IsOpenNode() ) + { + if ( !this->FileActive() ) + { + if ( ioFile ) + { + this->SetFileIoOpen(morkBool_kFalse); + this->SetFileName(ev, inName); + if ( ev->Good() ) + { + mStdioFile_File = ioFile; + this->SetFileActive(morkBool_kTrue); + this->SetFileFrozen(inFrozen); + } + } + else + ev->NilPointerError(); + } + else ev->NewError("file already active"); + } + else this->NewFileDownError(ev); + } +} + +void +morkStdioFile::CloseStdio(morkEnv* ev) + // Close the stream io if both and FileActive() and FileIoOpen(), but + // this does not close this instances (like CloseStdioFile() does). + // If stream io was made active by means of calling UseStdio(), + // then this method does little beyond marking the stream inactive + // because FileIoOpen() is false. +{ + if ( mStdioFile_File && this->FileActive() && this->FileIoOpen() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( MORK_FILECLOSE(file) < 0 ) + this->new_stdio_file_fault(ev); + + mStdioFile_File = 0; + this->SetFileActive(morkBool_kFalse); + this->SetFileIoOpen(morkBool_kFalse); + } +} + + +NS_IMETHODIMP +morkStdioFile::Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) + // If this file is a file version branch created by calling AcquireBud(), + // BecomeTrunk() causes this file's content to replace the original + // file's content, typically by assuming the original file's identity. +{ + morkEnv *mev = morkEnv::FromMdbEnv(ev); + if ( mStdioFile_File && FileActive() && FileIoOpen() ) + { + FILE* file = (FILE*) mStdioFile_File; + if ( MORK_FILECLOSE(file) < 0 ) + new_stdio_file_fault(mev); + + mStdioFile_File = 0; + } + SetThief(mev, ioThief); + return NS_OK; +} + + +#if defined(MORK_WIN) + +void mork_fileflush(FILE * file) +{ + fflush(file); +} + +#endif /*MORK_WIN*/ + + +//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |