imgtools/romtools/rofsbuild/fsnode.cpp
changeset 617 3a747a240983
parent 605 122d2b873fd1
child 647 53d1ab72f5bc
equal deleted inserted replaced
616:24e4ef208cca 617:3a747a240983
    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.
   203 	*     	}
   216 	*     	}
   204 	*     }
   217 	*     }
   205   *
   218   *
   206   */
   219   */
   207 void TFSNode::GenerateBasicName() { 
   220 void TFSNode::GenerateBasicName() { 
   208 	const char* filename = lbasename(iFileName);	 
   221 	const char* filename =  iFileName ;	 
   209 	TUint length = strlen(filename);
   222 	TUint length = strlen(filename);
   210 	if(0 == length)
   223 	if(0 == length)
   211 	    return ;
   224 	    return ;
   212 	if(0 == strcmp(filename,".")){
   225 	if(0 == strcmp(filename,".")){
   213         iShortName[0] = '.' ;
   226         iShortName[0] = '.' ;
   215 	}
   228 	}
   216 	if(0 == strcmp(filename,"..")){
   229 	if(0 == strcmp(filename,"..")){
   217         iShortName[0] = '.' ;
   230         iShortName[0] = '.' ;
   218         iShortName[1] = '.' ;
   231         iShortName[1] = '.' ;
   219         return ;
   232         return ;
   220 	}	
   233 	} 
   221 #ifdef _DEBUG
       
   222 		cout << "GenericBasicName: \"" << filename ;
       
   223 #endif	
       
   224 	iWideName = new UTF16String(filename,length); // The unicode string
   234 	iWideName = new UTF16String(filename,length); // The unicode string
   225 	char base[10];
   235 	char base[10];
   226 	const char* ext = filename + length;
   236 	const char* ext = filename + length;
   227 	
   237 	
   228 	//Strip all leading periods and spaces from the long name.
   238 	//Strip all leading periods and spaces from the long name.
   284 			ext[e] == '^' || ext[e] == '#' || ext[e] == '&' ||ext[e] == '\'')
   294 			ext[e] == '^' || ext[e] == '#' || ext[e] == '&' ||ext[e] == '\'')
   285 			iShortName[ei++] = ext[e] ;
   295 			iShortName[ei++] = ext[e] ;
   286 	}
   296 	}
   287  
   297  
   288 	if(iParent) 
   298 	if(iParent) 
   289 		iParent->MakeUniqueShortName(iShortName,bl);
   299 		iParent->MakeUniqueShortName(iShortName,bl); 
   290 #ifdef _DEBUG
       
   291 		cout << "\" => \"" << iShortName << "\"\n";
       
   292 #endif	
       
   293 }
   300 }
   294 
   301 
   295 #ifdef _DEBUG
   302 #ifdef _DEBUG
   296 void TFSNode::PrintTree(int nTab) {
   303 void TFSNode::PrintTree(int nTab) {
   297 	for( int i = 0 ; i < nTab ; i++ )
   304 	for( int i = 0 ; i < nTab ; i++ )
   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 ;
   366 	if(iFATEntry){
   373 	if(iFATEntry){
   367 		*((TUint16*)iFATEntry->DIR_FstClusHI) = (aStartIndex >> 16) ;
   374 		*((TUint16*)iFATEntry->DIR_FstClusHI) = (aStartIndex >> 16) ;
   368 		*((TUint16*)iFATEntry->DIR_FstClusLO) = (aStartIndex & 0xFFFF) ;
   375 		*((TUint16*)iFATEntry->DIR_FstClusLO) = (aStartIndex & 0xFFFF) ;
   369 	}
   376 	}
   370 	 
   377 	 
   371 	if(iAttrs & ATTR_DIRECTORY) { // Directory , write dir entries ; 
   378 	if(IsDirectory()) { // Directory , write dir entries ; 
   372 		TShortDirEntry* entry = reinterpret_cast<TShortDirEntry*>(aClusterData);
   379 		TShortDirEntry* entry = reinterpret_cast<TShortDirEntry*>(aClusterData);
   373 		if(iParent != NULL) {
   380 		if(iParent != NULL) {
   374 			//Make 
   381 			//Make 
   375 			GetShortEntry(entry); 
   382 			GetShortEntry(entry); 
   376 			//TODO: Add comments to avoid mistaken deleting.			
   383 			//TODO: Add comments to avoid mistaken deleting.