1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fslow_Path.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 26078 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FSLOW_FSLOW_PATH_H_
17 #define NN_FSLOW_FSLOW_PATH_H_
18 
19 #include <nn/util/util_NonCopyable.h>
20 #include <nn/util/util_StaticAssert.h>
21 #include <memory>
22 #include <cstring>
23 #include <cwchar>
24 
25 namespace nn { namespace fslow {
26 
27 enum PathType
28 {
29     PATH_TYPE_INVALID = 0,
30     PATH_TYPE_EMPTY = 1,
31     PATH_TYPE_BINARY = 2,
32     PATH_TYPE_STRING = 3,
33     PATH_TYPE_WSTRING = 4
34 };
35 
36 template <class TStringPath, class TWStringPath>
37 class LowPath
38 {
39 public:
40 
41     typedef TWStringPath WStringPath;
42     typedef TStringPath StringPath;
43 
44 private:
45 
46     bit32 m_PathType;
47     const void* m_Data;
48     size_t m_BinarySize;
49 
GetBinarySize()50     size_t GetBinarySize() const { return m_BinarySize; }
51 
52 public:
53 
PRINT()54     void PRINT() const
55     {
56 #if 1
57         switch (GetPathType())
58         {
59             case PATH_TYPE_INVALID:
60             {
61                 nn::dbg::detail::TPrintf("PATH_TYPE_INVALID\n");
62                 break;
63             }
64             case PATH_TYPE_EMPTY:
65             {
66                 nn::dbg::detail::TPrintf("PATH_TYPE_EMPTY\n");
67                 break;
68             }
69             case PATH_TYPE_BINARY:
70             {
71                 if (GetBinarySize() == 1) { nn::dbg::detail::TPrintf("PATH_TYPE_BINARY(1 byte) %d\n", *(static_cast<const bit8*>(m_Data))); }
72                 else if (GetBinarySize() == 2) { nn::dbg::detail::TPrintf("PATH_TYPE_BINARY(2 byte) %d\n", *(static_cast<const bit16*>(m_Data))); }
73                 else if (GetBinarySize() == 4) { nn::dbg::detail::TPrintf("PATH_TYPE_BINARY(4 byte) %d\n", *(static_cast<const bit32*>(m_Data))); }
74                 else if (GetBinarySize() == 8) { nn::dbg::detail::TPrintf("PATH_TYPE_BINARY(8 byte) %lld\n", *(static_cast<const bit64*>(m_Data))); }
75                 else
76                 {
77                     nn::dbg::detail::TPrintf("PATH_TYPE_BINARY(%d byte) ", GetBinarySize());
78                     for (int i = 0; i < GetBinarySize(); i++)
79                     {
80                         nn::dbg::detail::TPrintf("%2X ", *(static_cast<const bit8*>(m_Data) + i));
81                     }
82                     nn::dbg::detail::TPrintf("\n");
83                 }
84                 break;
85             }
86             case PATH_TYPE_STRING:
87             {
88                 nn::dbg::detail::TPrintf("PATH_TYPE_STRING \"%s\"\n", static_cast<const char*>(m_Data));
89                 break;
90             }
91             case PATH_TYPE_WSTRING:
92             {
93                 char buf[256];
94                 std::wcstombs(buf, static_cast<const wchar_t*>(m_Data), 256);
95                 nn::dbg::detail::TPrintf("PATH_TYPE_WSTRING \"%s\"\n", buf);
96                 break;
97             }
98             default:
99             {
100                 nn::dbg::detail::TPrintf("PATH_TYPE_unknown \n");
101                 break;
102             }
103         }
104 #endif
105     }
106 
LowPath(bit32 pathType,const void * data,size_t size)107     LowPath(bit32 pathType, const void* data, size_t size)
108     {
109         NN_TASSERT_(data != 0);
110         this->m_PathType = pathType;
111         this->m_Data = data;
112         this->m_BinarySize = size;
113         // TODO: 必要な assert
114     }
115 
LowPath()116     LowPath()
117     {
118         this->m_PathType = PATH_TYPE_EMPTY;
119         // TODO: 本来は以下は 0 にすべき
120         this->m_Data = &m_Data;
121         this->m_BinarySize = 1;
122     }
123 
124     template <typename T>
SetBinary(const T * p)125     void SetBinary(const T* p)
126     {
127         this->m_PathType = PATH_TYPE_BINARY;
128         this->m_Data = p;
129         this->m_BinarySize = sizeof(T);
130     }
131 
132     template <typename T>
Make(const T * p)133     static LowPath Make(const T* p)
134     {
135         LowPath ret;
136         ret.SetBinary(p);
137         return ret;
138     }
139 
LowPath(const char * path)140     LowPath(const char* path)
141     {
142         // TODO: サイズなどのチェック
143         this->m_PathType = PATH_TYPE_STRING;
144         this->m_Data = path;
145         this->m_BinarySize = (std::strlen(path) + 1) * sizeof(*path);
146     }
147 
LowPath(const wchar_t * path)148     LowPath(const wchar_t* path)
149     {
150         // TODO: サイズなどのチェック
151         this->m_PathType = PATH_TYPE_WSTRING;
152         this->m_Data = path;
153         this->m_BinarySize = (std::wcslen(path) + 1) * sizeof(*path);
154     }
155 
IsEmptyPath()156     bool IsEmptyPath() const
157     {
158         return GetPathType() == PATH_TYPE_EMPTY;
159     }
160 
161     struct BinaryProxy
162     {
163         friend class LowPath;
164     private:
165 
166         const LowPath* m_Path;
167 
BinaryProxyBinaryProxy168         explicit BinaryProxy(const LowPath* path) : m_Path(path) {}
169 
170     public:
171 
172         template <class T>
173         operator const T*() const
174         {
175             if (m_Path->GetPathType() == PATH_TYPE_BINARY && m_Path->GetBinarySize() == sizeof(T))
176             {
177                 return static_cast<const T*>(m_Path->m_Data);
178             }
179             else
180             {
181                 return 0;
182             }
183         }
184 
185     };
186     friend struct BinaryProxy;
187 
GetBinary()188     const BinaryProxy GetBinary() const
189     {
190         return BinaryProxy(this);
191     }
192 
GetString()193     StringPath GetString() const
194     {
195         if (GetPathType() == PATH_TYPE_STRING)
196         {
197             return StringPath(static_cast<const char*>(m_Data));
198         }
199         if (GetPathType() == PATH_TYPE_WSTRING)
200         {
201             return StringPath(static_cast<const wchar_t*>(m_Data));
202         }
203         return StringPath();
204     }
205 
GetStringRaw()206     const char* GetStringRaw() const
207     {
208         if (GetPathType() == PATH_TYPE_STRING)
209         {
210             return static_cast<const char*>(m_Data);
211         }
212         else
213         {
214             return 0;
215         }
216     }
217 
GetWString()218     WStringPath GetWString() const
219     {
220         if (GetPathType() == PATH_TYPE_WSTRING)
221         {
222             return WStringPath(static_cast<const wchar_t*>(m_Data));
223         }
224         if (GetPathType() == PATH_TYPE_STRING)
225         {
226             return WStringPath(static_cast<const char*>(m_Data));
227         }
228         return WStringPath();
229     }
230 
GetWStringRaw()231     const wchar_t* GetWStringRaw() const
232     {
233         if (GetPathType() == PATH_TYPE_WSTRING)
234         {
235             return static_cast<const wchar_t*>(m_Data);
236         }
237         else
238         {
239             return 0;
240         }
241     }
242 
GetPathType()243     bit32 GetPathType() const { return m_PathType; }
244 
GetDataBuffer()245     const bit8* GetDataBuffer() const
246     {
247         return static_cast<const bit8*>(m_Data);
248     }
249 
GetDataSize()250     size_t GetDataSize() const
251     {
252         return m_BinarySize;
253     }
254 
255 };
256 
257 }}
258 
259 #endif
260