⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fio.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  				*des++ = '\r';
  				extraCR_num++;
  			}
  			
			// when there are less equal one empty byte in the current block
  			if ((des+1) >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE))
	  		{
  				// Note: curBlock could move to the next only once because 
  				//	the maximum value of freeSize is RD_BLOCK_SIZE
  			
  				// we'll create a new block when
	  			// (1) the capacity of the current block is already full
  				//    or
  				// (2) there are only one empty byte left in the current block and
  				//	this loop will still go on at least 1 time
  			
	  			if (des >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE) || \
  					(i+1) < RD_BLOCK_SIZE)
  				{
	  				// move on to the next block
  					curBlock = curBlock->nextBlock;
	  				if (curBlock == NULL)
		  			{
						// a new block is needed, go get it
						curBlock = RD_getBlock((unsigned long)RD_BLOCK_SIZE);
						if (curBlock == NULL)
						{
							pfile->currentBlock = NULL;
							pfile->blockfpos = 0;
							RDerrno = ERROR_ALLOC_BLOCK;

							sc_getTime(&now);
							(pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + \
								now.second / 2;
							(pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;

							pfile->fpos += (i + extraCR_num);
					
  							RD_writeBlockChecksum(prevBlock);
							
							return (writeCount + i);
						}
						
						// link the new block to the file block link
						curBlock->prevBlock = prevBlock;
						prevBlock->nextBlock = curBlock;

						// new block is of course uncompressed
						curBlock->status = BLOCK_UNCOMPRESSED;
						
						curBlock->userCount = 0;
				#ifdef RAMDISK_COMPRESS_USE_ZLIB
						// one handle is using this block
						curBlock->userCount++;
				#endif
	  				}
  					else
  					{
						// a block other than the current block is found
						pfile->currentBlock = curBlock;
					#ifdef RAMDISK_COMPRESS_USE_ZLIB
						// one more file handle is using this block
						(pfile->currentBlock)->userCount++;

						// uncompress the block if necessary
						if (uncompressCurrentBlock(pfile) == -1)
						{
							pfile->currentBlock = NULL;
							pfile->blockfpos = 0;

							sc_getTime(&now);
							(pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + now.second / 2;
							(pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;

 							RD_writeBlockChecksum(prevBlock);
  							
							return (writeCount + i);
						}
						curBlock = pfile->currentBlock;
					#endif
  					
	  				}
  	  				
  					if (des >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE))
  						des = (unsigned char *)((unsigned long)curBlock + B_HEADER);
  					else
	  				{
  						// there is still one byte left in the previous block, so go back!
  						curBlock = prevBlock;
  					}
  				}
	  		}

			*des++ = *buffer++;
		}
	}
	else // binary mode
	{
		// if both buffers are 4 byte-aligned
		if ((long)des % 4 == 0 && (long)buffer % 4 == 0)
		{
			for (i = 0; i < RD_BLOCK_SIZE / 4; i++)
			{
				*((int*)des) = *((int*)buffer);
				des += 4;
				buffer += 4;
			}
			
			for (i = 0; i < RD_BLOCK_SIZE % 4; i++)
				*des++ = *buffer++;
		}
		else if ((long)des % 2 == 0 && (long)buffer % 2 == 0)// if both buffers are 2 byte-aligned
		{
			for (i = 0; i < RD_BLOCK_SIZE / 2; i++)
			{
				*((short*)des) = *((short*)buffer);
				des += 2;
				buffer += 2;
			}
			
			for (i = 0; i < RD_BLOCK_SIZE % 2; i++)
				*des++ = *buffer++;
		}
		else if ((long)des % 2 == 1 && (long) buffer % 2 == 1)
		{
			// move 1 byte first to make both des & buffer located on even addresses
			*des++ = *buffer++;
			
			if ((long)des % 4 == 0 && (long)buffer % 4 == 0)
			{
				for (i = 0; i < (RD_BLOCK_SIZE-1) / 4; i++)
				{
					*((int*)des) = *((int*)buffer);
					des += 4;
					buffer += 4;
				}
			
				for (i = 0; i < (RD_BLOCK_SIZE-1) % 4; i++)
					*des++ = *buffer++;
			}
			else
			{
				for (i = 0; i < (RD_BLOCK_SIZE-1) / 2; i++)
				{
					*((short*)des) = *((short*)buffer);
					des += 2;
					buffer += 2;
				}
			
				for (i = 0; i < (RD_BLOCK_SIZE-1) % 2; i++)
					*des++ = *buffer++;
			}
		}
		else
		{
  			for (i = 0; i < RD_BLOCK_SIZE; i++)
				*des++ = *buffer++;
		}
	}
   
	remains -= RD_BLOCK_SIZE;
	pfile->fpos += (RD_BLOCK_SIZE + extraCR_num);
	
	if (pfile->fpos > (pfile->dirEntry)->fsize)
	{
		// file size grows
		(pfile->dirEntry)->fsize = pfile->fpos;
	}
	
	if (prevBlock == curBlock)
	{
		curBlock->actualSize = RD_BLOCK_SIZE;
		curBlock->dataSize = RD_BLOCK_SIZE;
	}
	else
	{
		prevBlock->actualSize = RD_BLOCK_SIZE;
		prevBlock->dataSize = RD_BLOCK_SIZE;
		
  		RD_writeBlockChecksum(prevBlock);
  		
		curBlock->actualSize = pfile->fpos - pfile->blockfpos - RD_BLOCK_SIZE;
		curBlock->dataSize = pfile->fpos - pfile->blockfpos - RD_BLOCK_SIZE;
		
		// if the capacity of curBlock is full, we compress the prevBlock( = pfile->currentBlock)
		if (curBlock->actualSize >= RD_BLOCK_SIZE)
		{
			// compress the previous block if necessary
		#ifdef RAMDISK_COMPRESS_USE_ZLIB
			pfile->currentBlock = prevBlock;
			compressCurrentBlock(pfile);
//			prevBlock = pfile->currentBlock;
			// one less file handle is using this block
			(pfile->currentBlock)->userCount--;

		#endif
			// move pfile->currentBlock to the new block we just created in the last data-copy loop
			pfile->currentBlock = curBlock;
			pfile->blockfpos += RD_BLOCK_SIZE;
			extraCR_num = 0;
		}
		else
		{
			// restore curBlock for part2 processing
			pfile->currentBlock = curBlock = prevBlock;
		}

	}
	writeCount += RD_BLOCK_SIZE;
  }

  // part 3: transfer data from the last block to user buffer
  
  // update the file position of the 1st byte of the current block
  pfile->blockfpos += RD_BLOCK_SIZE;

  // get next block
  prevBlock = curBlock;
  curBlock = curBlock->nextBlock;

  // compress the previous block if necessary
#ifdef RAMDISK_COMPRESS_USE_ZLIB
  compressCurrentBlock(pfile);
  prevBlock = pfile->currentBlock;

  // one less file handle is using this block
  (pfile->currentBlock)->userCount--;
#endif

  if (curBlock == NULL)
  {
	// a new block is needed, go get it
	curBlock = RD_getBlock((unsigned long)RD_BLOCK_SIZE);
	if (curBlock == NULL)
	{
		pfile->currentBlock = NULL;
		pfile->blockfpos = 0;
		RDerrno = ERROR_ALLOC_BLOCK;

		sc_getTime(&now);
		(pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + now.second / 2;
		(pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;

		RD_writeBlockChecksum(prevBlock);
		
		return writeCount;
	}

	// link the new block to the file block link
	curBlock->prevBlock = prevBlock;
	if (prevBlock != NULL)
		prevBlock->nextBlock = curBlock;

	// new block is of course uncompressed
	curBlock->status = BLOCK_UNCOMPRESSED;
	// no handle is originally using this block
	curBlock->userCount = 0;
  }
  
  RD_writeBlockChecksum(prevBlock);

  // the current block is the new block
  pfile->currentBlock = curBlock;

#ifdef RAMDISK_COMPRESS_USE_ZLIB
  // one more file handle is using this block
  (pfile->currentBlock)->userCount++;

  // uncompress the block if necessary
  if (uncompressCurrentBlock(pfile) == -1)
  {
	pfile->currentBlock = NULL;
	pfile->blockfpos = 0;

	sc_getTime(&now);
	(pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + now.second / 2;
	(pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;

 	RD_writeBlockChecksum(curBlock);
	return writeCount;
	
  }
  curBlock = pfile->currentBlock;
#endif

  des = (unsigned char *)((unsigned long)curBlock + B_HEADER + extraCR_num);
  
  prevBlock = curBlock;
  extraCR_num = 0;  
  
  if ((pfile->fileFlag & O_TEXT) == O_TEXT)
  {
	for (i = 0; i < remains; i++)
  	{
  		if (des >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE))
  		{
  			curBlock = curBlock->nextBlock;
  			des = (unsigned char *)((unsigned long)curBlock + B_HEADER);
  		}
  		
  		if (*buffer == '\n')
 		{
  			// stuff a '\r' in the file
  			*des++ = '\r';
	  		extraCR_num++;
	  	}
	  	
		// when there are less equal one empty byte in the current block
  		if ((des+1) >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE))
  		{
  			// Note: curBlock could move to the next only once because 
  			//	the maximum value of freeSize is RD_BLOCK_SIZE
  			
  			// we'll create a new block when
  			// (1) the capacity of the current block is already full
  			//    or
  			// (2) there are only one empty byte left in the current block and
  			//	this loop will still go on at least 1 time
  			
  			if (des >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE) || \
  				(i+1) < remains)
  			{
	  			// move on to the next block
  				curBlock = curBlock->nextBlock;
  				if (curBlock == NULL)
	  			{
					// a new block is needed, go get it
					curBlock = RD_getBlock((unsigned long)RD_BLOCK_SIZE);
					if (curBlock == NULL)
					{
						pfile->currentBlock = NULL;
						pfile->blockfpos = 0;
						RDerrno = ERROR_ALLOC_BLOCK;

						sc_getTime(&now);
						(pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + \
							now.second / 2;
						(pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;

						pfile->fpos += (i + extraCR_num);
					
  						RD_writeBlockChecksum(prevBlock);
						
						return (writeCount + i);
					}
					
					// link the new block to the file block link
					curBlock->prevBlock = prevBlock;
					prevBlock->nextBlock = curBlock;

					// new block is of course uncompressed
					curBlock->status = BLOCK_UNCOMPRESSED;
					
					curBlock->userCount = 0;
			#ifdef RAMDISK_COMPRESS_USE_ZLIB
					// one handle is using this block
					curBlock->userCount++;
			#endif
					
  				}
 				else
  				{
					// a block other than the current block is found
					pfile->currentBlock = curBlock;
				#ifdef RAMDISK_COMPRESS_USE_ZLIB
					// one more file handle is using this block
					(pfile->currentBlock)->userCount++;

					// uncompress the block if necessary
					if (uncompressCurrentBlock(pfile) == -1)
					{
						pfile->currentBlock = NULL;
						pfile->blockfpos = 0;
						
						sc_getTime(&now);
						(pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + now.second / 2;
						(pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;

 						RD_writeBlockChecksum(prevBlock);
  						
						return (writeCount + i);
					}
					curBlock = pfile->currentBlock;
				#endif
  					
	  			}

  			
  				if (des >= ((unsigned char*)curBlock + B_HEADER + RD_BLOCK_SIZE))
  					des = (unsigned char *)((unsigned long)curBlock + B_HEADER);
  				else
  				{
  					// there is still one byte left in the previous block, so go back!
  					curBlock = prevBlock;
  				}
  			}
  		}

		*des++ = *buffer++;
  	}
  }
  else // binary mode
  {
	// if both buffers are 4 byte-aligned
		
	if ((long)des % 4 == 0 && (long)buffer % 4 == 0)
	{
		for (i = 0; i < remains / 4; i++)
		{
			*((int*)des) = *((int*)buffer);
			des += 4;
			buffer += 4;
		}
			
		for (i = 0; i < remains % 4; i++)
			*des++ = *buffer++;
	}
	else if ((long)des % 2 == 0 && (long)buffer % 2 == 0)// if both buffers are 2 byte-aligned
	{
		for (i = 0; i < remains / 2; i++)
		{
			*((short*)des) = *((short*)buffer);
			des += 2;
			buffer += 2;
		}
			
		for (i = 0; i < remains % 2; i++)
			*des++ = *buffer++;
	}
	else if ((long) des % 2 == 1 && (long) buffer % 2 == 1)
	{
		// move one byte first to make both des & buffer located on even addresses
		*des++ = *buffer++;
		
		if ((long)des % 4 == 0 && (long)buffer % 4 == 0)
		{
			for (i = 0; i < (remains-1) / 4; i++)
			{
				*((int*)des) = *((int*)buffer);
				des += 4;
				buffer += 4;
			}
			
			for (i = 0; i < (remains-1) % 4; i++)
				*des++ = *buffer++;
		}
		else
		{
			for (i = 0; i < (remains-1) / 2; i++)
			{
				*((short*)des) = *((short*)buffer);
				des += 2;
				buffer += 2;
			}
			
			for (i = 0; i < (remains-1) % 2; i++)
				*des++ = *buffer++;
		}
		
	}
	else
	{
  		for (i = 0; i < remains; i++)
			*des++ = *buffer++;
	}
  }
  
  pfile->fpos += (remains + extraCR_num);
  if (pfile->fpos > (pfile->dirEntry)->fsize)
  {
	// file size grows
	(pfile->dirEntry)->fsize = pfile->fpos;
  }

  writeCount += remains;

  if (curBlock->actualSize < (pfile->fpos - pfile->blockfpos))
  {
   	// if we didn't advance curBlock while writing in part2
   	if (prevBlock == curBlock)
   	{
		curBlock->actualSize = (pfile->fpos - pfile->blockfpos);
		curBlock->dataSize = (pfile->fpos - pfile->blockfpos);
   	}
   	else
   	{
   		prevBlock->actualSize = RD_BLOCK_SIZE;
   		prevBlock->dataSize = RD_BLOCK_SIZE;
   		
  		RD_writeBlockChecksum(prevBlock);
  		
		curBlock->actualSize = (pfile->fpos - pfile->blockfpos - RD_BLOCK_SIZE);
		curBlock->dataSize = (pfile->fpos - pfile->blockfpos - RD_BLOCK_SIZE);
		
		// if the capacity of curBlock is full, we compress the prevBlock( = pfile->currentBlock)
		if (curBlock->actualSize >= RD_BLOCK_SIZE)
		{
			// compress the previous block if necessary
		#ifdef RAMDISK_COMPRESS_USE_ZLIB
			pfile->currentBlock = prevBlock;
			compressCurrentBlock(pfile);
//			prevBlock = pfile->currentBlock;
			// one less file handle is using this block
			(pfile->currentBlock)->userCount--;

		#endif
			// move pfile->currentBlock to the new block we just created in the last data-copy loop
			pfile->currentBlock = curBlock;
			pfile->blockfpos += RD_BLOCK_SIZE;
			extraCR_num = 0;
		}
		else
		{
			// restore curBlock for part2 processing
			pfile->currentBlock = curBlock = prevBlock;
		}

   	}
  }
  
  RD_writeBlockChecksum(curBlock);
  
  remains = 0;
  sc_getTime(&now);
  (pfile->dirEntry)->time = now.hour * 2048 + now.minute * 32 + now.second / 2;
  (pfile->dirEntry)->date = (now.year-1980) * 512 + now.month * 32 + now.day;


  return writeCount;
}



/**********************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -