/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * gdir.c: Simplified wrapper around the DIRENT functions.
 *
 * Copyright 2001 Hans Breuer
 * Copyright 2004 Tor Lillqvist
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>

#ifdef HAVE_DIRENT_H
#include <sys/types.h>
#include <dirent.h>
#endif

#include "gdir.h"

#include "gconvert.h"
#include "gfileutils.h"
#include "gstrfuncs.h"
#include "gtestutils.h"
#include "glibintl.h"

#if defined (_MSC_VER) && !defined (HAVE_DIRENT_H)
#include "dirent/dirent.h"
#endif

#include "glib-private.h" /* g_dir_open_with_errno, g_dir_new_from_dirp */

/**
 * GDir:
 *
 * An opaque structure representing an opened directory.
 */

struct _GDir
{
#ifdef G_OS_WIN32
  _WDIR *wdirp;
#else
  DIR *dirp;
#endif
#ifdef G_OS_WIN32
  /* maximum encoding of FILENAME_MAX UTF-8 characters, plus a nul terminator
   * (FILENAME_MAX is not guaranteed to include one) */
  gchar utf8_buf[FILENAME_MAX*4 + 1];
#endif
};

/*< private >
 * g_dir_open_with_errno:
 * @path: the path to the directory you are interested in.
 * @flags: Currently must be set to 0. Reserved for future use.
 *
 * Opens a directory for reading.
 *
 * This function is equivalent to g_dir_open() except in the error case,
 * errno will be set accordingly.
 *
 * This is useful if you want to construct your own error message.
 *
 * Returns: a newly allocated #GDir on success, or %NULL on failure,
 *   with errno set accordingly.
 *
 * Since: 2.38
 */
GDir *
g_dir_open_with_errno (const gchar *path,
                       guint        flags)
{
  GDir dir;
#ifdef G_OS_WIN32
  gint saved_errno;
  wchar_t *wpath;
#endif

  g_return_val_if_fail (path != NULL, NULL);

#ifdef G_OS_WIN32
  wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);

  g_return_val_if_fail (wpath != NULL, NULL);

  dir.wdirp = _wopendir (wpath);
  saved_errno = errno;
  g_free (wpath);
  errno = saved_errno;

  if (dir.wdirp == NULL)
    return NULL;
#else
  dir.dirp = opendir (path);

  if (dir.dirp == NULL)
    return NULL;
#endif

  return g_memdup2 (&dir, sizeof dir);
}

/**
 * g_dir_open:
 * @path: the path to the directory you are interested in. On Unix
 *         in the on-disk encoding. On Windows in UTF-8
 * @flags: Currently must be set to 0. Reserved for future use.
 * @error: return location for a #GError, or %NULL.
 *         If non-%NULL, an error will be set if and only if
 *         g_dir_open() fails.
 *
 * Opens a directory for reading. The names of the files in the
 * directory can then be retrieved using g_dir_read_name().  Note
 * that the ordering is not defined.
 *
 * Returns: a newly allocated #GDir on success, %NULL on failure.
 *   If non-%NULL, you must free the result with g_dir_close()
 *   when you are finished with it.
 **/
GDir *
g_dir_open (const gchar  *path,
            guint         flags,
            GError      **error)
{
  gint saved_errno;
  GDir *dir;

  dir = g_dir_open_with_errno (path, flags);

  if (dir == NULL)
    {
      gchar *utf8_path;

      saved_errno = errno;

      utf8_path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);

      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
                   _("Error opening directory “%s”: %s"), utf8_path, g_strerror (saved_errno));
      g_free (utf8_path);
    }

  return dir;
}

/*< private >
 * g_dir_new_from_dirp:
 * @dirp: a #DIR* created by opendir() or fdopendir()
 *
 * Creates a #GDir object from the DIR object that is created using
 * opendir() or fdopendir().  The created #GDir assumes ownership of the
 * passed-in #DIR pointer.
 *
 * @dirp must not be %NULL.
 *
 * This function never fails.
 *
 * Returns: a newly allocated #GDir, which should be closed using
 *     g_dir_close().
 *
 * Since: 2.38
 **/
GDir *
g_dir_new_from_dirp (gpointer dirp)
{
#ifdef G_OS_UNIX
  GDir *dir;

  g_return_val_if_fail (dirp != NULL, NULL);

  dir = g_new (GDir, 1);
  dir->dirp = dirp;

  return dir;
#else
  g_assert_not_reached ();

  return NULL;
#endif
}

/**
 * g_dir_read_name:
 * @dir: a #GDir* created by g_dir_open()
 *
 * Retrieves the name of another entry in the directory, or %NULL.
 * The order of entries returned from this function is not defined,
 * and may vary by file system or other operating-system dependent
 * factors.
 *
 * %NULL may also be returned in case of errors. On Unix, you can
 * check `errno` to find out if %NULL was returned because of an error.
 *
 * On Unix, the '.' and '..' entries are omitted, and the returned
 * name is in the on-disk encoding.
 *
 * On Windows, as is true of all GLib functions which operate on
 * filenames, the returned name is in UTF-8.
 *
 * Returns: (type filename): The entry's name or %NULL if there are no
 *   more entries. The return value is owned by GLib and
 *   must not be modified or freed.
 **/
const gchar *
g_dir_read_name (GDir *dir)
{
#ifdef G_OS_WIN32
  gchar *utf8_name;
  struct _wdirent *wentry;
#else
  struct dirent *entry;
#endif

  g_return_val_if_fail (dir != NULL, NULL);

#ifdef G_OS_WIN32
  while (1)
    {
      wentry = _wreaddir (dir->wdirp);
      while (wentry 
	     && (0 == wcscmp (wentry->d_name, L".") ||
		 0 == wcscmp (wentry->d_name, L"..")))
	wentry = _wreaddir (dir->wdirp);

      if (wentry == NULL)
	return NULL;

      utf8_name = g_utf16_to_utf8 (wentry->d_name, -1, NULL, NULL, NULL);

      if (utf8_name == NULL)
	continue;		/* Huh, impossible? Skip it anyway */

      strcpy (dir->utf8_buf, utf8_name);
      g_free (utf8_name);

      return dir->utf8_buf;
    }
#else
  entry = readdir (dir->dirp);
  while (entry 
         && (0 == strcmp (entry->d_name, ".") ||
             0 == strcmp (entry->d_name, "..")))
    entry = readdir (dir->dirp);

  if (entry)
    return entry->d_name;
  else
    return NULL;
#endif
}

/**
 * g_dir_rewind:
 * @dir: a #GDir* created by g_dir_open()
 *
 * Resets the given directory. The next call to g_dir_read_name()
 * will return the first entry again.
 **/
void
g_dir_rewind (GDir *dir)
{
  g_return_if_fail (dir != NULL);
  
#ifdef G_OS_WIN32
  _wrewinddir (dir->wdirp);
#else
  rewinddir (dir->dirp);
#endif
}

/**
 * g_dir_close:
 * @dir: a #GDir* created by g_dir_open()
 *
 * Closes the directory and deallocates all related resources.
 **/
void
g_dir_close (GDir *dir)
{
  g_return_if_fail (dir != NULL);

#ifdef G_OS_WIN32
  _wclosedir (dir->wdirp);
#else
  closedir (dir->dirp);
#endif
  g_free (dir);
}

#ifdef G_OS_WIN32

/* Binary compatibility versions. Not for newly compiled code. */

_GLIB_EXTERN GDir        *g_dir_open_utf8      (const gchar  *path,
                                                guint         flags,
                                                GError      **error);
_GLIB_EXTERN const gchar *g_dir_read_name_utf8 (GDir         *dir);

GDir *
g_dir_open_utf8 (const gchar  *path,
                 guint         flags,
                 GError      **error)
{
  return g_dir_open (path, flags, error);
}

const gchar *
g_dir_read_name_utf8 (GDir *dir)
{
  return g_dir_read_name (dir);
}

#endif
