YSTest  PreAlpha_b400_20130424
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
NativeAPI.cpp
浏览该文件的文档.
1 /*
2  Copyright by FrankHB 2009 - 2013.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #include "YCLib/NativeAPI.h"
29 #include <ydef.h>
30 #include <cstdlib>
31 #include <cstdio>
32 #include <cstring>
33 #include "CHRLib/chrproc.h"
34 
35 using namespace CHRLib;
36 
37 namespace
38 {
39 }
40 
41 #if YCL_DS
42 
43 static int t; //object file place holder;
44 
45 #elif YCL_MINGW32
46 
47 extern "C"
48 {
49 
50 DIR*
51 opendir(const char* name)
52 {
53  static_assert(sizeof(wchar_t) == sizeof(ucs2_t), "Wrong character type!");
54 
55  yassume(name);
56 // yassume(name[std::strlen(name) - 1] != '\\');
57 
58  const auto wstr(reinterpret_cast<wchar_t*>(ucsdup(name)));
59 
60  if(!wstr)
61  return nullptr;
62 
63  const auto r(::GetFileAttributesW(wstr));
64 
65  std::free(wstr);
66  if(r != INVALID_FILE_ATTRIBUTES && r & FILE_ATTRIBUTE_DIRECTORY)
67  {
68  const auto dir(static_cast<DIR*>(std::malloc(sizeof(DIR))));
69 
70  yassume(std::strlen(name) + 2 < sizeof(dir->Name));
71 
72  dir->WinDir = ::WIN32_FIND_DATAW();
73  yunseq(std::sprintf(dir->Name, "%s\\*", name), dir->hNode = nullptr,
74  dir->POSIXDir.lpWinDir = &dir->WinDir);
75  return dir;
76  }
77  return nullptr;
78 }
79 
80 dirent*
81 readdir(DIR* dir)
82 {
83  static_assert(sizeof(wchar_t) == sizeof(ucs2_t), "Wrong character type!");
84 
85  if(!dir->hNode)
86  {
87  // NOTE: See MSDN "FindFirstFile function" for details.
88  yconstraint(dir->Name);
89  yconstraint(*dir->Name != char());
90  yconstraint(dir->Name[std::strlen(dir->Name) - 1] != '\\');
91 
92  const auto wstr(reinterpret_cast<wchar_t*>(ucsdup(dir->Name)));
93 
94  if(!wstr)
95  return nullptr;
96  if((dir->hNode = ::FindFirstFileW(wstr, &dir->WinDir))
97  == INVALID_HANDLE_VALUE)
98  dir->hNode = nullptr;
99  std::free(wstr);
100  }
101  else if(!::FindNextFileW(dir->hNode, &dir->WinDir))
102  {
103  FindClose(dir->hNode);
104  dir->hNode = nullptr;
105  }
106  if(dir->hNode && dir->hNode != INVALID_HANDLE_VALUE)
107  {
108  yassume(dir->WinDir.cFileName);
109 
110  const auto str(static_cast<char*>(std::malloc(
111  std::wcslen(dir->WinDir.cFileName) << 2)));
112 
113  UCS2ToMBCS(str, reinterpret_cast<const ucs2_t*>(dir->WinDir.cFileName));
114 
115  // NOTE: See http://pubs.opengroup.org/onlinepubs/009695399/basedefs/
116  // dirent.hNode.html for details.
117  yassume(std::strlen(str) < sizeof(dir->POSIXDir.d_name));
118 
119  std::strcpy(dir->POSIXDir.d_name, str);
120  std::free(str);
121  dir->POSIXDir.d_reclen = std::strlen(dir->POSIXDir.d_name);
122  yunseq(dir->POSIXDir.d_off = 0, dir->POSIXDir.d_ino = 0);
123  }
124  return !dir->hNode ? nullptr : &dir->POSIXDir;
125 }
126 
127 void
128 rewinddir(DIR* dir)
129 {
130  if(dir->hNode)
131  {
132  ::FindClose(dir->hNode);
133  dir->hNode = nullptr;
134  }
135 }
136 
137 int
138 closedir(DIR* dir)
139 {
140  if(dir)
141  {
142  if(dir->hNode)
143  ::FindClose(dir->hNode);
144  std::free(dir);
145  return 0;
146  }
147  return -1;
148 }
149 
150 } // extern "C";
151 
152 #endif
153 
154 namespace platform
155 {
156 }
157