//-----------------------------------------------------------------------
	bool FileSystemArchive::exists(const String& filename)
	{
        String full_path = concatenate_path(mName, filename);

        struct stat tagStat;
        bool ret = (stat(full_path.c_str(), &tagStat) == 0);

		// stat will return true if the filename is absolute, but we need to check
		// the file is actually in this archive
        if (ret && is_absolute_path(filename.c_str()))
		{
			// only valid if full path starts with our base
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
			// case insensitive on windows
			String lowerCaseName = mName;
			StringUtil::toLowerCase(lowerCaseName);
			ret = Ogre::StringUtil::startsWith(full_path, lowerCaseName, true);
#else
			// case sensitive
			ret = Ogre::StringUtil::startsWith(full_path, mName, false);
#endif
		}

		return ret;
	}
	//---------------------------------------------------------------------
	DataStreamPtr FileSystemArchive::create(const String& filename) const
	{
		if (isReadOnly())
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
				"Cannot create a file in a read-only archive", 
				"FileSystemArchive::remove");
		}

		String full_path = concatenate_path(mName, filename);

		// Always open in binary mode
		// Also, always include reading
		std::ios::openmode mode = std::ios::out | std::ios::binary;
		std::fstream* rwStream = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)();
		rwStream->open(full_path.c_str(), mode);

		// Should check ensure open succeeded, in case fail for some reason.
		if (rwStream->fail())
		{
			OGRE_DELETE_T(rwStream, basic_fstream, MEMCATEGORY_GENERAL);
			OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
				"Cannot open file: " + filename,
				"FileSystemArchive::create");
		}

		/// Construct return stream, tell it to delete on destroy
		FileStreamDataStream* stream = OGRE_NEW FileStreamDataStream(filename,
				rwStream, 0, true);

		return DataStreamPtr(stream);
	}
示例#3
0
    //-----------------------------------------------------------------------
    DataStreamPtr FileSystemArchive::open(const String& filename) const
    {
#if (_MSC_VER >= 1400)
		//	std::locale langLocale("");
		//	std::locale::global(langLocale);
		setlocale( LC_CTYPE, "" );
#endif
        String full_path = concatenate_path(mName, filename);

        // Use filesystem to determine size 
        // (quicker than streaming to the end and back)
        struct stat tagStat;
	int ret = stat(full_path.c_str(), &tagStat);
        assert(ret == 0 && "Problem getting file size" );

        // Always open in binary mode
        std::ifstream *origStream = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL)();
        origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);

        // Should check ensure open succeeded, in case fail for some reason.
        if (origStream->fail())
        {
            OGRE_DELETE_T(origStream, basic_ifstream, MEMCATEGORY_GENERAL);
            OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
                "Cannot open file: " + filename,
                "FileSystemArchive::open");
        }

        /// Construct return stream, tell it to delete on destroy
        FileStreamDataStream* stream = OGRE_NEW FileStreamDataStream(filename,
            origStream, tagStat.st_size, true);
        return DataStreamPtr(stream);
    }
示例#4
0
    //-----------------------------------------------------------------------
    DataStreamPtr FileSystemArchive::open(const String& filename, bool readOnly) const
    {
        String full_path = concatenate_path(mName, filename);

        // Use filesystem to determine size
        // (quicker than streaming to the end and back)
        struct stat tagStat;
		stat(full_path.c_str(), &tagStat);

        // Always open in binary mode
        std::ifstream *origStream = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL)();
        origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);

        // Should check ensure open succeeded, in case fail for some reason.
        if (origStream->fail())
        {
            OGRE_DELETE_T(origStream, basic_ifstream, MEMCATEGORY_GENERAL);
			OGRE_EXCEPT(Ogre::Exception::ERR_FILE_NOT_FOUND,
                "Cannot open file: " + filename,
                "FileSystemArchive::open");
        }

        // Construct return stream, tell it to delete on destroy
        FileStreamDataStream* stream = OGRE_NEW FileStreamDataStream(filename,
            origStream, tagStat.st_size, true);
        return DataStreamPtr(stream);
    }
    DataStreamPtr WriteableFileSystemArchive::open(const String& filename) const
    {
        String full_path = concatenate_path(mName, filename);

        // Use filesystem to determine size 
        // (quicker than streaming to the end and back)
        struct stat tagStat;
	int ret = stat(full_path.c_str(), &tagStat);
        assert(ret == 0 && "Problem getting file size" );

        // Always open in binary mode
        std::fstream *origStream = new std::fstream();
        origStream->open(full_path.c_str(), std::ios::in | std::ios::out | std::ios::binary);

        // Should check ensure open succeeded, in case fail for some reason.
        if (origStream->fail())
        {
            delete origStream;
            OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
                "Cannot open file: " + filename,
                "WriteableFileSystemArchive::open");
        }

        /// Construct return stream, tell it to delete on destroy
        WriteableFileStreamDataStream* stream = new WriteableFileStreamDataStream(filename,
            origStream, tagStat.st_size, true);
        return DataStreamPtr(stream);
    }
Ogre::DataStreamPtr OMEFileSystemArchive::open(const Ogre::String& filename, bool readOnly) const
{
    Ogre::String full_path = concatenate_path(mName, filename);

    // Use filesystem to determine size
    // (quicker than streaming to the end and back)
    struct stat tagStat;
    int ret = stat(full_path.c_str(), &tagStat);
    assert(ret == 0 && "Problem getting file size" );
    (void)ret;  // Silence warning

    // Always open in binary mode
    // Also, always include reading
    std::ios::openmode mode = std::ios::in | std::ios::binary;
    std::istream* baseStream = 0;
    std::ifstream* roStream = 0;
    std::fstream* rwStream = 0;

    if (!readOnly && isReadOnly())
    {
        mode |= std::ios::out;
        rwStream = OGRE_NEW_T(std::fstream, Ogre::MEMCATEGORY_GENERAL)();
        rwStream->open(full_path.c_str(), mode);
        baseStream = rwStream;
    }
    else
    {
        roStream = OGRE_NEW_T(std::ifstream, Ogre::MEMCATEGORY_GENERAL)();
        roStream->open(full_path.c_str(), mode);
        baseStream = roStream;
    }


    // Should check ensure open succeeded, in case fail for some reason.
    if (baseStream->fail())
    {
        OGRE_DELETE_T(roStream, basic_ifstream, Ogre::MEMCATEGORY_GENERAL);
        OGRE_DELETE_T(rwStream, basic_fstream, Ogre::MEMCATEGORY_GENERAL);
        OGRE_EXCEPT(Ogre::Exception::ERR_FILE_NOT_FOUND,
                    "Cannot open file: " + filename,
                    "FileSystemArchive::open");
    }

    /// Construct return stream, tell it to delete on destroy
    Ogre::FileStreamDataStream* stream = 0;
    if (rwStream)
    {
        // use the writeable stream
        stream = OGRE_NEW Ogre::FileStreamDataStream(filename,
                                               rwStream, (size_t)tagStat.st_size, true);
    }
    else
    {
        // read-only stream
        Ogre::String newName = mName + ":" + filename;
        stream = OGRE_NEW Ogre::FileStreamDataStream(newName,
                                               roStream, (size_t)tagStat.st_size, true);
    }
    return Ogre::DataStreamPtr(stream);
}
	//---------------------------------------------------------------------
	void FileSystemArchive::remove(const String& filename) const
	{
		if (isReadOnly())
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
				"Cannot remove a file from a read-only archive", 
				"FileSystemArchive::remove");
		}
		String full_path = concatenate_path(mName, filename);
		::remove(full_path.c_str());

	}
    //-----------------------------------------------------------------------
    void FileSystemArchive::load()
    {
		OGRE_LOCK_AUTO_MUTEX
        // test to see if this folder is writeable
		String testPath = concatenate_path(mName, "__testwrite.ogre");
		std::ofstream writeStream;
		writeStream.open(testPath.c_str());
		if (writeStream.fail())
			mReadOnly = true;
		else
		{
			mReadOnly = false;
			writeStream.close();
			::remove(testPath.c_str());
		}
    }
	//---------------------------------------------------------------------
	time_t FileSystemArchive::getModifiedTime(const String& filename)
	{
		String full_path = concatenate_path(mName, filename);

		struct stat tagStat;
		bool ret = (stat(full_path.c_str(), &tagStat) == 0);

		if (ret)
		{
			return tagStat.st_mtime;
		}
		else
		{
			return 0;
		}

	}
示例#10
0
    //-----------------------------------------------------------------------
	bool FileSystemArchive::exists(const String& filename)
	{
        String full_path = concatenate_path(mName, filename);

        struct stat tagStat;
        bool ret = (stat(full_path.c_str(), &tagStat) == 0);

		// stat will return true if the filename is absolute, but we need to check
		// the file is actually in this archive
        if (ret && is_absolute_path(filename.c_str()))
		{
			// only valid if full path starts with our base
			ret = Ogre::StringUtil::startsWith(full_path, mName);
		}

		return ret;
	}
    //-----------------------------------------------------------------------
    void FileSystemArchive::findFiles(const String& pattern, bool recursive, 
        bool dirs, StringVector* simpleList, FileInfoList* detailList) const
    {
        intptr_t lHandle, res;
        struct _finddata_t tagData;

        // pattern can contain a directory name, separate it from mask
        size_t pos1 = pattern.rfind ('/');
        size_t pos2 = pattern.rfind ('\\');
        if (pos1 == pattern.npos || ((pos2 != pattern.npos) && (pos1 < pos2)))
            pos1 = pos2;
        String directory;
        if (pos1 != pattern.npos)
            directory = pattern.substr (0, pos1 + 1);

        String full_pattern = concatenate_path(mName, pattern);

        lHandle = _findfirst(full_pattern.c_str(), &tagData);
        res = 0;
        while (lHandle != -1 && res != -1)
        {
            if ((dirs == ((tagData.attrib & _A_SUBDIR) != 0)) &&
				( !msIgnoreHidden || (tagData.attrib & _A_HIDDEN) == 0 ) &&
                (!dirs || !is_reserved_dir (tagData.name)))
            {
                if (simpleList)
                {
                    simpleList->push_back(directory + tagData.name);
                }
                else if (detailList)
                {
                    FileInfo fi;
                    fi.archive = this;
                    fi.filename = directory + tagData.name;
                    fi.basename = tagData.name;
                    fi.path = directory;
                    fi.compressedSize = tagData.size;
                    fi.uncompressedSize = tagData.size;
                    detailList->push_back(fi);
                }
            }
            res = _findnext( lHandle, &tagData );
        }
        // Close if we found any files
        if(lHandle != -1)
            _findclose(lHandle);

        // Now find directories
        if (recursive)
        {
            String base_dir = mName;
            if (!directory.empty ())
            {
                base_dir = concatenate_path(mName, directory);
                // Remove the last '/'
                base_dir.erase (base_dir.length () - 1);
            }
            base_dir.append ("/*");

            // Remove directory name from pattern
            String mask ("/");
            if (pos1 != pattern.npos)
                mask.append (pattern.substr (pos1 + 1));
            else
                mask.append (pattern);

            lHandle = _findfirst(base_dir.c_str (), &tagData);
            res = 0;
            while (lHandle != -1 && res != -1)
            {
                if ((tagData.attrib & _A_SUBDIR) &&
					( !msIgnoreHidden || (tagData.attrib & _A_HIDDEN) == 0 ) &&
                    !is_reserved_dir (tagData.name))
                {
                    // recurse
                    base_dir = directory;
                    base_dir.append (tagData.name).append (mask);
                    findFiles(base_dir, recursive, dirs, simpleList, detailList);
                }
                res = _findnext( lHandle, &tagData );
            }
            // Close if we found any files
            if(lHandle != -1)
                _findclose(lHandle);
        }
    }
示例#12
0
    //-----------------------------------------------------------------------
    void FileSystemArchive::findFiles(const String& pattern, bool recursive,
        bool dirs, StringVector* simpleList, FileInfoList* detailList) const
    {
        long lHandle, res;
        struct _finddata_t tagData;
        // pattern can contain a directory name, separate it from mask
        size_t pos1 = pattern.rfind ('/');
        size_t pos2 = pattern.rfind ('\\');
        if (pos1 == pattern.npos || ((pos2 != pattern.npos) && (pos1 < pos2)))
            pos1 = pos2;
        String directory;
        if (pos1 != pattern.npos)
            directory = pattern.substr (0, pos1 + 1);

		String base_dir = mName;
		if (!directory.empty ())
		{
			base_dir = concatenate_path(mName, directory);
			// Remove the last '/'
			base_dir.erase (base_dir.length () - 1);
		}

		//if there's a file with the name "norecurse" we shouldn't recurse further
		std::ifstream norecurseFile((base_dir + "/norecurse").c_str());
		if (!norecurseFile.fail()) {
			return;
		}

		base_dir.append ("/*");


        String full_pattern = concatenate_path(mName, pattern);

        lHandle = _findfirst(full_pattern.c_str(), &tagData);
        res = 0;
        while (lHandle != -1 && res != -1)
        {
            if ((dirs == ((tagData.attrib & _A_SUBDIR) != 0)) &&
                (!dirs || !is_reserved_dir (tagData.name)))
            {

                if (simpleList)
                {
                    simpleList->push_back(directory + tagData.name);
                }
                else if (detailList)
                {
                    FileInfo fi;
                    fi.archive = this;
                    fi.filename = directory + tagData.name;
                    fi.basename = tagData.name;
                    fi.path = directory;
                    fi.compressedSize = tagData.size;
                    fi.uncompressedSize = tagData.size;
                    detailList->push_back(fi);

                }
            }
            res = _findnext( lHandle, &tagData );
        }
        // Close if we found any files
        if(lHandle != -1)
            _findclose(lHandle);


        // Now find directories
        if (recursive)
        {


            // Remove directory name from pattern
            String mask ("/");
            if (pos1 != pattern.npos)
                mask.append (pattern.substr (pos1 + 1));
            else
                mask.append (pattern);

            lHandle = _findfirst(base_dir.c_str (), &tagData);
            res = 0;
            while (lHandle != -1 && res != -1)
            {
        		//if the name of the directory is "source" we should ignore it, since these are directories
        		//containing raw source materials (.psd files, .blend files etc) which we don't want to bring
        		//into the client (they tend to be rather large)
                if ((tagData.attrib & _A_SUBDIR) &&
                    !is_reserved_dir (tagData.name) && !(tagData.attrib & _A_HIDDEN) &&
                    std::strcmp(tagData.name, "source") != 0)
                {
                    // recurse
                    base_dir = directory;
                    base_dir.append (tagData.name).append (mask);
                    findFiles(base_dir, recursive, dirs, simpleList, detailList);
                }
                res = _findnext( lHandle, &tagData );
            }
            // Close if we found any files
            if(lHandle != -1)
                _findclose(lHandle);
        }
    }