39 #endif |
39 #endif |
40 |
40 |
41 using namespace std; |
41 using namespace std; |
42 |
42 |
43 const TUint KBytesPerEntry = 13 ; |
43 const TUint KBytesPerEntry = 13 ; |
|
44 |
|
45 static inline bool is_a_long_file_name_char(unsigned char ch){ |
|
46 return ( ch >= ' ' && ch != '"' && ch != '*' && ch != ':' && ch != '<' \ |
|
47 && ch != '>' && ch != '?' && ch != '|' && ch != 127) ; |
|
48 |
|
49 } |
44 // |
50 // |
45 TFSNode::TFSNode(TFSNode* aParent, const char* aFileName, TUint8 aAttrs, const char* aPCSideName) : |
51 TFSNode::TFSNode(TFSNode* aParent, const char* aFileName, TUint8 aAttrs, const char* aPCSideName) : |
46 iParent(aParent),iFirstChild(0),iSibling(0),iAttrs(aAttrs), iPCSideName(0), iWideName(0){ |
52 iParent(aParent),iFirstChild(0),iSibling(0),iAttrs(aAttrs), iPCSideName(0), iWideName(0){ |
47 |
53 |
48 // According to the FAT specification, short name should be inited with empty string (' ' string) |
54 // According to the FAT specification, short name should be inited with empty string (' ' string) |
49 memset(iShortName,0x20,11); |
55 memset(iShortName,0x20,11); |
50 iShortName[11] = 0 ; |
56 iShortName[11] = 0 ; |
51 if(aFileName) { |
57 if(aFileName) { |
52 iFileName = strdup(aFileName); |
58 const unsigned char* ptr = reinterpret_cast<const unsigned char*>(aFileName); |
|
59 bool allSpaces = true ; |
|
60 while(*ptr){ |
|
61 if( !is_a_long_file_name_char(*ptr)) |
|
62 throw "Illegal filename or dir name! \n"; |
|
63 if(*ptr != ' ') |
|
64 allSpaces = false ; |
|
65 ptr++ ; |
|
66 } |
|
67 if(allSpaces) |
|
68 throw "Illegal filename or dir name(all spaces)!\n"; |
|
69 iFileName = strdup(aFileName); |
53 GenerateBasicName() ; |
70 GenerateBasicName() ; |
54 } |
71 } |
55 if(aPCSideName) { |
72 if(aPCSideName) { |
56 iPCSideName = strdup(aPCSideName); |
73 iPCSideName = strdup(aPCSideName); |
57 } |
74 } |
82 delete iSibling ; |
99 delete iSibling ; |
83 if(iFileName) |
100 if(iFileName) |
84 free(iFileName) ; |
101 free(iFileName) ; |
85 if(iWideName) |
102 if(iWideName) |
86 delete iWideName; |
103 delete iWideName; |
87 } |
104 if(iPCSideName) |
|
105 free(iPCSideName); |
|
106 } |
|
107 |
88 TFSNode* TFSNode::CreateFromFolder(const char* aPath,TFSNode* aParent) { |
108 TFSNode* TFSNode::CreateFromFolder(const char* aPath,TFSNode* aParent) { |
89 static char fileName[2048]; |
109 |
90 int len = strlen(aPath); |
110 int len = strlen(aPath); |
91 #ifdef __LINUX__ |
111 #ifdef __LINUX__ |
92 DIR* dir = opendir(aPath); |
112 DIR* dir = opendir(aPath); |
93 if(dir == NULL) { |
113 if(dir == NULL) { |
94 cout << aPath << " does not contain any subfolder/file.\n"; |
114 cout << aPath << " does not contain any subfolder/file.\n"; |
95 return aParent; |
115 return aParent; |
96 } |
116 } |
97 if(!aParent) |
117 if(!aParent) |
98 aParent = new TFSNode(NULL,"/",ATTR_VOLUME_ID); |
118 aParent = new TFSNode(NULL,"/",ATTR_DIRECTORY); |
99 dirent* entry; |
119 dirent* entry; |
100 struct stat statbuf ; |
120 struct stat statbuf ; |
|
121 char* fileName = new(nothrow) char[len + 200]; |
|
122 if(!fileName) return NULL ; |
|
123 memcpy(fileName,aPath,len); |
|
124 fileName[len] = SPLIT_CHAR; |
101 while ((entry = readdir(dir)) != NULL) { |
125 while ((entry = readdir(dir)) != NULL) { |
102 if(entry->d_name[0] == '.') continue ; |
126 if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) |
103 memcpy(fileName,aPath,len); |
127 continue ; |
104 fileName[len] = SPLIT_CHAR; |
128 strcpy(&fileName[len+1],entry->d_name); |
105 strcpy(&fileName[len+1],entry->d_name); |
129 stat(fileName , &statbuf); |
106 stat(fileName , &statbuf); |
130 TFSNode* pNewItem = new TFSNode(aParent,fileName,S_ISDIR(statbuf.st_mode) ? ATTR_DIRECTORY : 0); |
107 TFSNode* pNewItem = new TFSNode(aParent,fileName,S_ISDIR(statbuf.st_mode) ? ATTR_DIRECTORY : 0); |
131 pNewItem->Init(statbuf.st_ctime,statbuf.st_atime,statbuf.st_mtime,statbuf.st_size); |
108 pNewItem->Init(statbuf.st_ctime,statbuf.st_atime,statbuf.st_mtime,statbuf.st_size); |
132 if(S_ISDIR(statbuf.st_mode)){ |
109 if(S_ISDIR(statbuf.st_mode)){ |
133 CreateFromFolder(fileName,pNewItem); |
110 CreateFromFolder(fileName,pNewItem); |
134 } |
111 } |
135 } |
112 } |
136 delete []fileName ; |
113 closedir(dir); |
137 closedir(dir); |
114 #else |
138 #else |
115 struct _finddata_t data ; |
139 struct _finddata_t data ; |
116 memset(&data, 0, sizeof(data)); |
140 memset(&data, 0, sizeof(data)); |
117 char* pattern = new char[len + 4] ; |
141 char* fileName = new(nothrow) char[len + 200]; |
118 memcpy(pattern,aPath,len); |
142 if(!fileName) return NULL ; |
119 pattern[len] = SPLIT_CHAR; |
143 memcpy(fileName,aPath,len); |
120 pattern[len+1] = '*'; |
144 fileName[len] = SPLIT_CHAR; |
121 pattern[len+2] = 0; |
145 fileName[len+1] = '*'; |
122 |
146 fileName[len+2] = 0; |
123 intptr_t hFind = _findfirst(pattern,&data); |
147 intptr_t hFind = _findfirst(fileName,&data); |
124 delete []pattern ; |
|
125 |
148 |
126 if(hFind == (intptr_t)-1 ) { |
149 if(hFind == (intptr_t)-1 ) { |
127 cout << aPath << " does not contain any subfolder/file.\n"; |
150 cout << aPath << " does not contain any subfolder/file.\n"; |
|
151 delete []fileName; |
128 return aParent; |
152 return aParent; |
129 } |
153 } |
130 if(!aParent) |
154 if(!aParent) |
131 aParent = new TFSNode(NULL,"/",ATTR_VOLUME_ID); |
155 aParent = new TFSNode(NULL,"/",ATTR_DIRECTORY); |
|
156 |
132 do { |
157 do { |
133 if(data.name[0] == '.') |
158 if(strcmp(data.name,".") == 0 || strcmp(data.name,"..") == 0) |
134 continue ; |
159 continue ; |
135 memcpy(fileName,aPath,len); |
160 |
136 fileName[len] = SPLIT_CHAR; |
|
137 strcpy(&fileName[len+1],data.name); |
161 strcpy(&fileName[len+1],data.name); |
138 TUint8 attr = 0; |
162 TUint8 attr = 0; |
139 if(data.attrib & _A_SUBDIR) |
163 if(data.attrib & _A_SUBDIR) |
140 attr |= ATTR_DIRECTORY; |
164 attr |= ATTR_DIRECTORY; |
141 if(data.attrib & _A_RDONLY) |
165 if(data.attrib & _A_RDONLY) |
144 attr |= ATTR_HIDDEN ; |
168 attr |= ATTR_HIDDEN ; |
145 if(data.attrib & _A_SYSTEM) |
169 if(data.attrib & _A_SYSTEM) |
146 attr |= ATTR_SYSTEM ; |
170 attr |= ATTR_SYSTEM ; |
147 if(data.attrib & _A_ARCH) |
171 if(data.attrib & _A_ARCH) |
148 attr |= ATTR_ARCHIVE; |
172 attr |= ATTR_ARCHIVE; |
149 TFSNode* pNewItem = new TFSNode(aParent,fileName,attr); |
173 TFSNode* pNewItem = new TFSNode(aParent,data.name,attr,fileName); |
150 pNewItem->Init(data.time_create,data.time_access,data.time_write,data.size); |
174 pNewItem->Init(data.time_create,data.time_access,data.time_write,data.size); |
151 if(data.attrib & _A_SUBDIR){ |
175 if(data.attrib & _A_SUBDIR){ |
152 CreateFromFolder(fileName,pNewItem); |
176 CreateFromFolder(fileName,pNewItem); |
153 } |
177 } |
154 |
178 |
155 } while(-1 != _findnext(hFind, &data)); |
179 } while(-1 != _findnext(hFind, &data)); |
|
180 delete []fileName ; |
156 _findclose(hFind); |
181 _findclose(hFind); |
157 #endif |
182 #endif |
158 |
183 |
159 return aParent; |
184 return aParent; |
160 } |
185 } |
161 |
186 |
162 |
|
163 |
|
164 static const char* lbasename(const char* aFullName) { |
|
165 const char* retval = aFullName ; |
|
166 while(*aFullName) { |
|
167 if('\\' == *aFullName || '/' == *aFullName ) |
|
168 retval = ++aFullName ; |
|
169 else |
|
170 aFullName ++ ; |
|
171 } |
|
172 return retval ; |
|
173 } |
|
174 /** GenerateBasicName : Generate the short name according to long name |
187 /** GenerateBasicName : Generate the short name according to long name |
175 * |
188 * |
176 * algorithm : |
189 * algorithm : |
177 * |
190 * |
178 * 1. The UNICODE name passed to the file system is converted to upper case. |
191 * 1. The UNICODE name passed to the file system is converted to upper case. |
302 if(iSibling) |
309 if(iSibling) |
303 iSibling->PrintTree(nTab); |
310 iSibling->PrintTree(nTab); |
304 } |
311 } |
305 #endif |
312 #endif |
306 bool TFSNode::IsDirectory() const { |
313 bool TFSNode::IsDirectory() const { |
307 return 0 != (iAttrs & ATTR_DIRECTORY); |
314 return (0 != (iAttrs & ATTR_DIRECTORY) || ATTR_VOLUME_ID == iAttrs) ; |
308 } |
315 } |
309 int TFSNode::GetWideNameLength() const { |
316 int TFSNode::GetWideNameLength() const { |
310 if(!iWideName) |
317 if(!iWideName) |
311 return 0 ; |
318 return 0 ; |
312 return iWideName->length() ; |
319 return iWideName->length() ; |
313 } |
320 } |
314 TUint TFSNode::GetSize() const { |
321 TUint TFSNode::GetSize() const { |
315 |
322 |
316 if( 0 == (iAttrs & ATTR_DIRECTORY)) |
323 if( !IsDirectory()) |
317 return iFileSize ; |
324 return iFileSize ; |
318 TUint retVal = sizeof(TShortDirEntry) ; // the tailed entry |
325 TUint retVal = sizeof(TShortDirEntry) ; // the tailed entry |
319 if(iParent) |
326 if(iParent) |
320 retVal += sizeof(TShortDirEntry) * 2 ; |
327 retVal += sizeof(TShortDirEntry) * 2 ; |
321 TFSNode* child = iFirstChild ; |
328 TFSNode* child = iFirstChild ; |