- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / libraries / nacl_io / getdents_helper.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "nacl_io/getdents_helper.h"
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <string.h>
10
11 #include <algorithm>
12
13 #include "sdk_util/macros.h"
14
15 namespace nacl_io {
16
17 GetDentsHelper::GetDentsHelper(ino_t curdir_ino, ino_t parentdir_ino)
18     : curdir_ino_(curdir_ino), parentdir_ino_(parentdir_ino) {
19   Initialize();
20 }
21
22 void GetDentsHelper::Reset() {
23   dirents_.clear();
24   Initialize();
25 }
26
27 void GetDentsHelper::Initialize() {
28   // Add the default entries: "." and ".."
29   AddDirent(curdir_ino_, ".", 1);
30   AddDirent(parentdir_ino_, "..", 2);
31 }
32
33 void GetDentsHelper::AddDirent(ino_t ino, const char* name, size_t namelen) {
34   assert(name != NULL);
35   dirents_.push_back(dirent());
36   dirent& entry = dirents_.back();
37   entry.d_ino = ino;
38   entry.d_off = sizeof(dirent);
39   entry.d_reclen = sizeof(dirent);
40
41   if (namelen == 0)
42     namelen = strlen(name);
43
44   size_t d_name_max = MEMBER_SIZE(dirent, d_name) - 1;  // -1 for \0.
45   size_t copylen = std::min(d_name_max, namelen);
46   strncpy(&entry.d_name[0], name, copylen);
47   entry.d_name[copylen] = 0;
48 }
49
50 Error GetDentsHelper::GetDents(size_t offs,
51                                dirent* pdir,
52                                size_t size,
53                                int* out_bytes) const {
54   *out_bytes = 0;
55
56   // If the buffer pointer is invalid, fail
57   if (NULL == pdir)
58     return EINVAL;
59
60   // If the buffer is too small, fail
61   if (size < sizeof(dirent))
62     return EINVAL;
63
64   // Force size to a multiple of dirent
65   size -= size % sizeof(dirent);
66
67   size_t max = dirents_.size() * sizeof(dirent);
68   if (offs >= max) {
69     // OK, trying to read past the end.
70     return 0;
71   }
72
73   if (offs + size >= max)
74     size = max - offs;
75
76   memcpy(pdir, reinterpret_cast<const char*>(dirents_.data()) + offs, size);
77   *out_bytes = size;
78   return 0;
79 }
80
81 }  // namespace nacl_io