[zxio] Update to newest zxio_dirent_iterator API.

This CL has both versions of zxio_dirent_iterator usage to perform a
soft-migration.

Change-Id: Ie5c21ed6ff9e59e9c6cca3dbe8ed92aa476caa88
diff --git a/src/util/os_dirent.h b/src/util/os_dirent.h
index 5101e1c..b4f8c9a 100644
--- a/src/util/os_dirent.h
+++ b/src/util/os_dirent.h
@@ -35,6 +35,8 @@
    char d_name[];
 };
 
+#define OS_INO_UNKNOWN (0xFFFFFFFFFFFFFFFFul)
+
 typedef struct os_dir os_dir_t;
 
 os_dir_t* os_opendir(const char* path);
diff --git a/src/util/os_dirent_fuchsia.cpp b/src/util/os_dirent_fuchsia.cpp
index 7263cbb..56e1404 100644
--- a/src/util/os_dirent_fuchsia.cpp
+++ b/src/util/os_dirent_fuchsia.cpp
@@ -40,6 +40,68 @@
 static_assert(offsetof(struct os_dirent_impl, d_name) == offsetof(struct os_dirent, d_name),
               "d_ino offset mismatch");
 
+#ifndef ZXIO_DIRENT_ITERATOR_DEFAULT_BUFFER_SIZE
+
+class os_dir {
+public:
+   os_dir() {}
+
+   ~os_dir()
+   {
+      if (dir_iterator_init) {
+         zxio_dirent_iterator_destroy(&iterator);
+      }
+      if (dir_init) {
+         zxio_close(&io_storage.io);
+      }
+   }
+
+   // Always consumes |dir_channel|
+   bool Init(zx_handle_t dir_channel)
+   {
+      zx_status_t status = zxio_dir_init(&io_storage, dir_channel);
+      if (status != ZX_OK) {
+         FUCHSIA_DLOG("zxio_dir_init failed: %d", status);
+         return false;
+      }
+      dir_init = true;
+
+      status = zxio_dirent_iterator_init(&iterator, &io_storage.io);
+      if (status != ZX_OK) {
+         FUCHSIA_DLOG("zxio_dirent_iterator_init failed: %d", status);
+         return false;
+      }
+      dir_iterator_init = true;
+
+      return true;
+   }
+
+   struct os_dirent_impl* Next()
+   {
+      zxio_dirent_t* dirent;
+      zx_status_t status = zxio_dirent_iterator_next(&iterator, &dirent);
+      if (status != ZX_OK) {
+         FUCHSIA_DLOG("zxio_dirent_iterator_next failed: %d", status);
+         return nullptr;
+      }
+
+      entry.d_ino = dirent->has.id ? dirent->id : OS_INO_UNKNOWN;
+      strncpy(entry.d_name, dirent->name, dirent->name_length);
+      entry.d_name[dirent->name_length] = 0;
+
+      return &entry;
+   }
+
+private:
+   bool dir_init = false;
+   bool dir_iterator_init = false;
+   zxio_storage_t io_storage;
+   zxio_dirent_iterator_t iterator;
+   struct os_dirent_impl entry;
+};
+
+#else
+
 class os_dir {
 public:
    os_dir() { buffer = new char[buffer_size()]; }
@@ -97,6 +159,8 @@
    char* buffer = nullptr;
 };
 
+#endif
+
 os_dir_t* os_opendir(const char* path)
 {
    zx_handle_t dir_channel;