/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "hsFiles.h" #include #include "hsUtils.h" #include "hsExceptions.h" #if HS_BUILD_FOR_MAC #define kDirChar ':' #elif HS_BUILD_FOR_WIN32 #define kDirChar '\\' #else #define kDirChar '/' #endif static const char* FindNameInPath(const char path[]) { const char* name = ::strrchr(path, kDirChar); if (name == nil) name = path; return name; } /////////////////////////////////////////////////////////////////////// #if !HS_BUILD_FOR_PS2 hsFile::hsFile() : fPathAndName(nil), fFILE(nil) { } hsFile::hsFile(const char pathAndName[]) : fPathAndName(nil), fFILE(nil) { if (pathAndName) fPathAndName = hsStrcpy(pathAndName); } hsFile::~hsFile() { this->SetPathAndName(nil); } const char* hsFile::GetPathAndName() { return fPathAndName; } void hsFile::SetPathAndName(const char pathAndName[]) { this->Close(); if (fPathAndName) { delete[] fPathAndName; fPathAndName = nil; } if (pathAndName) fPathAndName = hsStrcpy(pathAndName); } const char* hsFile::GetName() { return FindNameInPath(this->GetPathAndName()); } FILE* hsFile::OpenFILE(const char mode[], hsBool throwIfFailure) { this->Close(); // We call the virtual method here rather than using // fPathAndName directly, allowing a subclass to construct // the name if necessary // const char* name = this->GetPathAndName(); if (name) fFILE = ::fopen(name, mode); hsThrowIfTrue(throwIfFailure && fFILE == nil); return fFILE; } hsStream* hsFile::OpenStream(const char mode[], hsBool throwIfFailure) { FILE* file = this->OpenFILE(mode, throwIfFailure); if (file) { hsUNIXStream* stream = TRACKED_NEW hsUNIXStream; stream->SetFILE(file); return stream; } return nil; } void hsFile::Close() { if (fFILE) { int err = ::fflush(fFILE); hsIfDebugMessage(err != 0, "fflush failed", err); err = ::fclose(fFILE); hsIfDebugMessage(err != 0, "fclose failed", err); fFILE = nil; } } #endif /////////////////////////////////////////////////////////////////////// hsBool hsFolderIterator::NextFileSuffix(const char suffix[]) { while (this->NextFile()) { const char* fileSuffix = ::strrchr(this->GetFileName(), '.'); if (fileSuffix != nil && stricmp(fileSuffix, suffix) == 0) return true; } return false; } int hsFolderIterator::GetPathAndName(char pathandname[]) { const char* name = this->GetFileName(); int pathLen = hsStrlen(fPath); // add 1 for null terminator int totalLen = pathLen + sizeof(kDirChar) + hsStrlen(name) + 1; hsAssert(totalLen <= kFolderIterator_MaxPath, "Overrun kFolderIterator_MaxPath"); if (pathandname) { hsStrcpy(pathandname, fPath); if (pathLen > 0 && pathandname[pathLen - 1] != kDirChar) pathandname[pathLen++] = kDirChar; hsStrcpy(pathandname + pathLen, name); } return totalLen; } FILE* hsFolderIterator::OpenFILE(const char mode[]) { char fileName[kFolderIterator_MaxPath]; (void)this->GetPathAndName(fileName); return ::fopen(fileName, mode); }