DirectoryReader.hxx 3.38 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2015 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * http://www.musicpd.org
 *
 * 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 2 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef MPD_FS_DIRECTORY_READER_HXX
#define MPD_FS_DIRECTORY_READER_HXX

#include "check.h"
24
#include "Path.hxx"
25

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
#ifdef WIN32

#include <windows.h>
#include <tchar.h>

/**
 * Reader for directory entries.
 */
class DirectoryReader {
	const HANDLE handle;
	WIN32_FIND_DATA data;
	bool first;

	class MakeWildcardPath {
		PathTraitsFS::pointer path;

	public:
		MakeWildcardPath(PathTraitsFS::const_pointer _path) {
			auto l = _tcslen(_path);
			path = new PathTraitsFS::value_type[l + 3];
			_tcscpy(path, _path);
			path[l] = _T('\\');
			path[l + 1] = _T('*');
			path[l + 2] = 0;
		}

		~MakeWildcardPath() {
			delete[] path;
		}

		operator PathTraitsFS::const_pointer() const {
			return path;
		}
	};

public:
	/**
	 * Creates new directory reader for the specified #dir.
	 */
	explicit DirectoryReader(Path dir)
		:handle(FindFirstFile(MakeWildcardPath(dir.c_str()), &data)),
		 first(true) {}

	DirectoryReader(const DirectoryReader &other) = delete;
	DirectoryReader &operator=(const DirectoryReader &other) = delete;

	/**
	 * Destroys this instance.
	 */
	~DirectoryReader() {
		if (!HasFailed())
			FindClose(handle);
	}

	/**
	 * Checks if directory failed to open.
	 */
	bool HasFailed() const {
		return handle == INVALID_HANDLE_VALUE;
	}

	/**
	 * Reads next directory entry.
	 */
	bool ReadEntry() {
		if (first) {
			first = false;
			return true;
		}

		return FindNextFile(handle, &data) != 0;
	}

	/**
	 * Extracts directory entry that was previously read by #ReadEntry.
	 */
	Path GetEntry() const {
		return Path::FromFS(data.cFileName);
	}
};

#else

109 110 111 112 113 114 115 116 117 118 119 120
#include <dirent.h>

/**
 * Reader for directory entries.
 */
class DirectoryReader {
	DIR *const dirp;
	dirent *ent;
public:
	/**
	 * Creates new directory reader for the specified #dir.
	 */
121
	explicit DirectoryReader(Path dir)
122 123 124 125 126 127 128 129 130 131 132
		: dirp(opendir(dir.c_str())),
		  ent(nullptr) {
	}

	DirectoryReader(const DirectoryReader &other) = delete;
	DirectoryReader &operator=(const DirectoryReader &other) = delete;

	/**
	 * Destroys this instance.
	 */
	~DirectoryReader() {
133
		if (!HasFailed())
134 135 136 137 138 139
			closedir(dirp);
	}

	/**
	 * Checks if directory failed to open. 
	 */
140
	bool HasFailed() const {
141 142 143 144 145 146 147
		return dirp == nullptr;
	}

	/**
	 * Checks if directory entry is available.
	 */
	bool HasEntry() const {
148
		assert(!HasFailed());
149 150 151 152 153 154 155
		return ent != nullptr;
	}

	/**
	 * Reads next directory entry.
	 */
	bool ReadEntry() {
156
		assert(!HasFailed());
157 158 159 160 161 162 163
		ent = readdir(dirp);
		return HasEntry();
	}

	/**
	 * Extracts directory entry that was previously read by #ReadEntry.
	 */
164
	Path GetEntry() const {
165
		assert(HasEntry());
166
		return Path::FromFS(ent->d_name);
167 168 169 170
	}
};

#endif
171 172

#endif