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