Exemple #1
0
int JudgeFAT(char *file_path, dbr_list* p_dbr, fat_boot_sector* fat)
{
	char sz_temp1[4] = {0};
	char sz_temp2[4] = {0};
	LARGE_INTEGER tmp1 = {0};
	LARGE_INTEGER tmp2 = {0};

	char flag[4] = {'\xf8', '\xff', '\xff', '\x0f'};

	DWORD readsize = 0;
	
	tmp1.QuadPart = p_dbr->ll_offset + (fat->reserved * SECTOR_SIZE);
	tmp2.QuadPart = p_dbr->ll_offset - ((fat->backup_boot + fat->reserved) * SECTOR_SIZE);

	if (!ReadFileOffset(file_path, tmp1.QuadPart, 4, sz_temp1, FILE_BEGIN))
		ErrorOut("ReadFile Error!\n");
	
	if (!memcmp(sz_temp1, flag, 4))
	{
		p_dbr->ll_start_sector = p_dbr->ll_offset / SECTOR_SIZE;
		return 1;
	}else
	{
		if (!ReadFileOffset(file_path, tmp2.QuadPart, 4, sz_temp2, FILE_BEGIN))
			ErrorOut("ReadFile Error!\n");

		if (!memcmp(sz_temp2, flag, 4))
		{
			p_dbr->ll_start_sector = p_dbr->ll_offset / SECTOR_SIZE - fat->backup_boot;
			p_dbr->n_is_org = 1; 
			return 1;
		}
	}
	return 0;
}
Exemple #2
0
int JudgeMFT(char* file_path, dbr_list* p_dbr, ntfs_boot_sector* ntfs)
{

	char sz_temp1[4] = {0};
	char sz_temp2[4] = {0};
	DWORD readsize;
	LARGE_INTEGER tmp1 = {0};
	LARGE_INTEGER tmp2 = {0};
	tmp1.QuadPart = p_dbr->ll_offset + (ntfs->mft_lcn.QuadPart * ntfs->sectors_per_cluster * SECTOR_SIZE);
	tmp2.QuadPart = p_dbr->ll_offset - (ntfs->sectors_nbr * SECTOR_SIZE) + (ntfs->mft_lcn.QuadPart * ntfs->sectors_per_cluster * SECTOR_SIZE);

	if (!ReadFileOffset(file_path, tmp1.QuadPart, 4, sz_temp1, FILE_BEGIN))
		ErrorOut("ReadFile Error!\n");
	
	if (!memcmp(sz_temp1, "FILE", 4))
	{
		p_dbr->ll_start_sector = p_dbr->ll_offset / SECTOR_SIZE;
		return 1;
	}else
	{
		if (!ReadFileOffset(file_path, tmp2.QuadPart, 4, sz_temp2, FILE_BEGIN))
			ErrorOut("ReadFile Error!\n");
		
		if (!memcmp(sz_temp2, "FILE", 4))
		{
			p_dbr->ll_start_sector = p_dbr->ll_offset / SECTOR_SIZE - ntfs->sectors_nbr;
			p_dbr->n_is_org = 1;
			return 1;
		}
	}
	return 0;
}
Exemple #3
0
static void IOError( char *msgstart, const char *name )
/*****************************************************/
{
    ErrorOut( msgstart );
    ErrorOut( name );
    ErrorOut( ": " );
    ErrorExit( strerror( errno ) );
}
Exemple #4
0
void Format::StringPrint(ostream& os, const char* value, int size) const
{
   int i;

   // prefix
   os << prefix_val;

   // will it fit
   if (size > max_width_val) { ErrorOut(os); return; }

   // padding
   int spaces;
   if (size < min_width_val) spaces = min_width_val - size;  else spaces = 0;
   int s1, s2;                                // leading and following spaces
   if (alignment_val == Format::LEFT) { s1 = 0; s2 = spaces; }
   else if (alignment_val == Format::RIGHT) { s1 = spaces; s2 = 0; }
   else { s1 = spaces / 2; s2 = spaces - s1; }

   // leading spaces
   for (i = 0; i < s1; i++) os << ' ';

   // the string
   for (i = 0; i < size; i++) os << value[i];

   // trailing blanks
   for (i = 0; i < s2; i++) os << ' ';

   // suffix
   os << suffix_val;
}
Exemple #5
0
bool WriteFileOffset(char* file_path, __int64 ll_offset, long l_buf_size, char* buf, __in DWORD dwMoveMethod)
{
	DWORD readsize;
	LARGE_INTEGER tmp = {0};

	HANDLE hFile = CreateFileA(file_path, 
		GENERIC_WRITE | GENERIC_READ,               
		FILE_SHARE_WRITE|FILE_SHARE_READ,
		NULL, 
		OPEN_EXISTING, 
		FILE_FLAG_SEQUENTIAL_SCAN, 
		NULL);

	if ( hFile == INVALID_HANDLE_VALUE){                               //Open the data file.
		ErrorOut("CreateFile() Error!");
	}
	tmp.QuadPart = ll_offset;
	tmp.LowPart = SetFilePointer(hFile, tmp.QuadPart, &tmp.HighPart, dwMoveMethod);
	if (WriteFile(hFile, buf, l_buf_size, &readsize, NULL))
	{
		CloseHandle(hFile);
		return 1;
	}else
	{
		CloseHandle(hFile);
		return 0;
	}
}
Exemple #6
0
/*得到文件大小*/
__int64 ToGetFileSize(char* pFile)
{
	DWORD	dwFileSizeHigh	= 0;
	long	filesize		= 0;
	__int64 nFileSize		= 0;

	HANDLE hFile = CreateFileA((LPCSTR)pFile, 
		GENERIC_READ,               
		FILE_SHARE_READ,
		NULL, 
		OPEN_EXISTING, 
		FILE_FLAG_SEQUENTIAL_SCAN, 
		NULL);

	if ( hFile == INVALID_HANDLE_VALUE)
	{                 
		ErrorOut("CreateFile Error!");
	}

	nFileSize = GetFileSize(hFile, &dwFileSizeHigh);
	nFileSize += (((__int64) dwFileSizeHigh) << 32);

	CloseHandle(hFile);
	return nFileSize;
}
Exemple #7
0
// 往dbrList中插入一个元素
int InsertDBRList(dbr_list_t* p_dbr_head, char* sz_data, int n_type,__int64 i, LCN ll_offset) 
{  
	int j = 0;  

	dbr_list_t *pTemp	= NULL;   // 临时指针
	dbr_list_t *s		= NULL;   

	pTemp = p_dbr_head;  
	while(pTemp != NULL&& j < i)    // 插入到头结点的下一个节点
	{   
		if (!memcmp(pTemp->p_next->dbr, sz_data, 512))
		{
			free(sz_data);
			return 0;
		}
		pTemp = pTemp->p_next;   
		j++;    
	}  

	if (pTemp == NULL) 
	{
		ErrorOut("Insert dbrList Error!");
	}

	s = (dbr_list_t *)malloc(sizeof(dbr_list_t)); 
	memset(s, 0, sizeof(dbr_list_t));

	if(NULL == s) 
	{
		ErrorOut("Insert dbrList Error!");
	}
	else
	{ 
		s->dbr			= sz_data;
		s->n_type		= n_type;
		s->ll_offset	= ll_offset;
		s->p_next		= pTemp->p_next; 
		s->ll_start_sector = 0;
		s->ll_total_sector = 0;
		s->flag			   = 0;
		s->n_is_org		   = 0;
		pTemp->p_next = s; 
		g_n_dbr++;
		return 1;
	} 
	return 0;
}
Exemple #8
0
int Maping_file(char* big_file, LCN lOffset, long lSize)
{
	char* pDPT_File;                                                  //存放指向内存映射文件的首地址

	HANDLE hFile = CreateFileA(big_file, 
		GENERIC_READ,               
		FILE_SHARE_READ,
		NULL, 
		OPEN_EXISTING, 
		FILE_FLAG_SEQUENTIAL_SCAN, 
		NULL);

	if ( hFile == INVALID_HANDLE_VALUE){                               //Open the data file.
		ErrorOut("CreateFile() Error!");
	}

	HANDLE hFileMapping = CreateFileMapping(hFile, 
		NULL,         //Create the file-mapping object.
		PAGE_READONLY,
		0, 
		0,
		NULL);
	if (hFileMapping == INVALID_HANDLE_VALUE){
		ErrorOut("CreateFileMapping() Error!");
	}
	PBYTE pbFile = (PBYTE) MapViewOfFile(hFileMapping, FILE_MAP_READ,
		lOffset & 0xFFFFFFFF00000000,                                                             // Offset high
		lOffset & 0xFFFFFFFF,                                                                     // Offset low
		lSize);                                                                                   // bytes to map
	if (pbFile == INVALID_HANDLE_VALUE){
		ErrorOut("MapViewOfFile() Error!");
	}
	//printf("%lld,  %lld\n", g_ll_file_size, lOffset);

	//////////////////////////////////////////////
	pDPT_File = (char*)pbFile;
	ToGetDBR(pDPT_File, lSize, lOffset);

	//////////////////////////////////////////////

	UnmapViewOfFile(pbFile);
	CloseHandle(hFileMapping);
	CloseHandle(hFile);
	return 0;
}
Exemple #9
0
// 往dbrList中插入一个元素
int InsertRebuildList(rebuild_content_t* p_rebuild_head, char* sz_data, int n_size, LCN ll_offset, __int64 i) 
{  
	int j = 0;  

	rebuild_content_t *pTemp	= NULL;   // 临时指针
	rebuild_content_t *s		= NULL;   

	pTemp = p_rebuild_head;  
	while(pTemp != NULL&& j < i)    // 插入到头结点的下一个节点
	{   
		pTemp = pTemp->p_next;   
		j++;    
	}  

	if (pTemp == NULL) 
	{
		ErrorOut("Insert dbrList Error!");
	}

	s = (rebuild_content_t *)malloc(sizeof(rebuild_content_t)); 
	memset(s, 0, sizeof(rebuild_content_t));

	if(NULL == s) 
	{
		ErrorOut("Insert rebuild_content_t Error!");
	}
	else
	{ 
		s->content		= sz_data;
		s->n_size		= n_size;
		s->ll_offset	= ll_offset;
		s->p_next		= pTemp->p_next; 
		pTemp->p_next = s; 
		return 1;
	} 
	return 0;
}
Exemple #10
0
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
  ISequentialOutStream *outStream, const UInt64 * /*inSize*/ ,
  const UInt64 * /*outSize */, ICompressProgressInfo *progress)
{
  ZSTDMT_RdWr_t rdwr;
  size_t result;
  HRESULT res = S_OK;

  struct ZstdStream Rd;
  Rd.inStream = inStream;
  Rd.outStream = outStream;
  Rd.processedIn = &_processedIn;
  Rd.processedOut = &_processedOut;

  struct ZstdStream Wr;
  if (_processedIn == 0)
    Wr.progress = progress;
  else
    Wr.progress = 0;
  Wr.inStream = inStream;
  Wr.outStream = outStream;
  Wr.processedIn = &_processedIn;
  Wr.processedOut = &_processedOut;

  /* 1) setup read/write functions */
  rdwr.fn_read = ::ZstdRead;
  rdwr.fn_write = ::ZstdWrite;
  rdwr.arg_read = (void *)&Rd;
  rdwr.arg_write = (void *)&Wr;

  /* 2) create compression context, if needed */
  if (!_ctx)
    _ctx = ZSTDMT_createCCtx(_numThreads, _props._level, _inputSize);
  if (!_ctx)
    return S_FALSE;

  /* 3) compress */
  result = ZSTDMT_compressCCtx(_ctx, &rdwr);
  if (ZSTDMT_isError(result)) {
    if (result == (size_t)-ZSTDMT_error_canceled)
      return E_ABORT;
    return ErrorOut(result);
  }

  return res;
}
Exemple #11
0
// 创建一个空链表 用来存储需要重构的信息
rebuild_content_t *CreateReBuildHead()
{
	rebuild_content_t *pTemp = NULL;
	pTemp = (rebuild_content_t*)malloc(sizeof(rebuild_content_t));
	if(NULL == pTemp)    
	{
		ErrorOut("Malloc Error!");
		return NULL;
	}
	else
	{ 
		// 初始化链表 返回p
		pTemp->p_next	= NULL;
		pTemp->content	= NULL;
		pTemp->ll_offset= 0;
		pTemp->n_size	= 0;
		return(pTemp);
	}
}
Exemple #12
0
HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
  ISequentialOutStream * outStream, ICompressProgressInfo * progress)
{
  ZSTDMT_RdWr_t rdwr;
  size_t result;
  HRESULT res = S_OK;

  struct ZstdStream Rd;
  Rd.inStream = inStream;
  Rd.processedIn = &_processedIn;

  struct ZstdStream Wr;
  Wr.progress = progress;
  Wr.outStream = outStream;
  Wr.processedIn = &_processedIn;
  Wr.processedOut = &_processedOut;

  /* 1) setup read/write functions */
  rdwr.fn_read = ::ZstdRead;
  rdwr.fn_write = ::ZstdWrite;
  rdwr.arg_read = (void *)&Rd;
  rdwr.arg_write = (void *)&Wr;

  /* 2) create decompression context */
  ZSTDMT_DCtx *ctx = ZSTDMT_createDCtx(_numThreads, _inputSize);
  if (!ctx)
      return S_FALSE;

  /* 3) decompress */
  result = ZSTDMT_decompressDCtx(ctx, &rdwr);
  if (ZSTDMT_isError(result)) {
    if (result == (size_t)-ZSTDMT_error_canceled)
      return E_ABORT;
    return ErrorOut(result);
  }

  /* 4) free resources */
  ZSTDMT_freeDCtx(ctx);
  return res;
}
Exemple #13
0
// 创建一个空链表 用来存储需要重构的信息
dbr_list_t *CreateDBRHead()
{
	dbr_list_t *pTemp = NULL;
	pTemp = (dbr_list_t*)malloc(sizeof(dbr_list_t));
	if(NULL == pTemp)    
	{
		ErrorOut("Malloc Error!");
		return NULL;
	}
	else
	{ 
		// 初始化链表 返回p
		pTemp->p_next	= NULL;
		pTemp->dbr		= NULL;
		pTemp->n_type	= 0;
		pTemp->ll_offset= 0;
		pTemp->flag		= 0;
		pTemp->ll_start_sector = 0;
		pTemp->ll_total_sector = 0;
		pTemp->n_is_org = 0;
		return(pTemp);
	}
}
Exemple #14
0
int wms_get_file_1(HINTERNET hConnect, LPCSTR pathname, LPCSTR strReferer, LPCSTR tx_saveto)
{
HINTERNET hReq;
DWORD  dwSize, dwCode;
CHAR szData[HTTP_GET_SIZE+1];

//CString strReferer = "http://maps.peterrobins.co.uk/f/m.html";

//strReferer = "http://map.geoportail.lu";

	if ( !(hReq = HttpOpenRequest (hConnect, "GET", pathname, HTTP_VERSION, strReferer, NULL, 0 ,0 ))) {
		ErrorOut (GetLastError(), "HttpOpenRequest");
		return FALSE;
	}


	if (!HttpSendRequest (hReq, NULL, 0, NULL, 0) ) {
		ErrorOut (GetLastError(), "HttpSend");
		return FALSE;
	}

	dwSize = sizeof (DWORD) ;
	if ( !HttpQueryInfo (hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL)) {
		ErrorOut (GetLastError(), "HttpQueryInfo");
		return FALSE;
	}

	if ( dwCode == HTTP_STATUS_DENIED || dwCode == HTTP_STATUS_PROXY_AUTH_REQ) {
		// This is a secure page.
		fprintf(stderr, "This page is password protected.\n");
		return FALSE;
	}
	if ( dwCode == 404) {
		fprintf(stderr, "Page not found.\n");
		return FALSE;
	}

	FILE * fp = fopen(tx_saveto, "wb+");
	if (fp == NULL) {
		printf("Couldn't create %s\n", tx_saveto);
		return FALSE;
	}
	long file_len=0;
	while (!abortProgram) {
		if (!InternetReadFile (hReq, (LPVOID)szData, HTTP_GET_SIZE, &dwSize) ) {
			ErrorOut (GetLastError (), "InternetReadFile");
			file_len = -1;
			break;
		}
		if (dwSize == 0)
			break;

		if (fwrite(szData, sizeof(char), dwSize, fp) != dwSize) {
			printf("Error writing %d bytes to %s\n", dwSize, tx_saveto);
			file_len = -1;
			break;
		}
		file_len += dwSize;
//		printf("%d \r", file_len);
	}
	fclose(fp);

	if (!InternetCloseHandle (hReq) ) {
		ErrorOut (GetLastError (), "CloseHandle on hReq");
		file_len = -1;
	}
	if (file_len <= 0)
		return FALSE;

	// Validate PNG
	LPBYTE buffer = (LPBYTE)malloc(file_len+1);
	if (buffer == 0) {
		fprintf(stderr, "Couldn't allocate %d bytes to verify %s\n", file_len, tx_saveto);
		return FALSE;
	}
	memset(buffer, 0, file_len+1);
	fp = fopen(tx_saveto, "rb");
	if (fp == NULL) {
		fprintf(stderr, "Failed to reopen %s\n", tx_saveto);
		free(buffer);
		return FALSE;
	}
	if (fread(buffer, 1, file_len, fp) != file_len) {
		fprintf(stderr, "Error reading %s\n", tx_saveto);
		free(buffer);
		return FALSE;
	}
	fclose(fp);

	unsigned char pnghdr[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
	unsigned char jpghdr[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46};
	unsigned char gifhdr[] = {0x47, 0x49, 0x46, 0x38, 0x39, 0x61};

	if ((memcmp(buffer, pnghdr, sizeof(pnghdr)) == 0)
	||  (memcmp(buffer, jpghdr, sizeof(jpghdr)) == 0)
	||  (memcmp(buffer, gifhdr, sizeof(gifhdr)) == 0)) {
		free(buffer);
		return TRUE;
	} else {
		fprintf(stderr, "Error retrieving %s\n", tx_saveto);
		free(buffer);
		return FALSE;
	}
}
Exemple #15
0
int wmsLoadTiles(CTileDatabase* g_db, long minx, long miny, long maxx, long maxy, BOOL bForce, int nMapScale)
{
HINTERNET hOpen, hConnect;
char strTile[256];

	hOpen = NULL;
	FILE * fp_log = fopen("log.txt", "a+");

CProgressWindow wndProgress;
wndProgress.Initialize();

int nMeters = MyMap.GetMetresPerTile();

wndProgress.ResetProgressBar("Downloading:", (maxy-miny)/nMeters*(maxx-minx)/nMeters);

	// Grab in (8 x 8????) tiles.
	for (long y=miny; y<maxy; y+=nMeters) {
		for (long x=minx; x<maxx; x+=nMeters) {

			if (!wndProgress.ProgressBar()) return false;

			if (!bForce && g_db->TileLoaded(y, x)) {
		
				fprintf(fp_log, "Tile: [%05d,%05d] skipped - tile exists\n", x,y);
				continue;
			} else {
				
				// Only connect to WMS if required.
// SNL 11/06/2013 - hmmmm!
CString str1 = MyMap.wmsGetAttribution();
int port = MyMap.wmsGetPort();
				g_db->InitDatabase(y,x,MyMap.GetDatum());
				if (hOpen == NULL) {
					if ( !(hOpen = InternetOpen ( "Sample",  LOCAL_INTERNET_ACCESS , NULL, 0, 0) ) ) {
						ErrorOut ( GetLastError(), "InternetOpen");
						return 0;
					}

					if ( !(hConnect = InternetConnect ( hOpen, MyMap.wmsGetAttribution(), MyMap.wmsGetPort(), "",	"", INTERNET_SERVICE_HTTP, 0  , 0) ) ) {
						ErrorOut (GetLastError(), "InternetConnect");
						return 0;
					}
				}
				fprintf(fp_log, "Tile: [%05d,%05d] loading...\n", x,y);
				wmsGetTile(hConnect, strTile, y, x, g_db, fp_log, bForce, nMapScale);
			}

			if (abortProgram) {
				y=miny;
				x=maxx;
			}
		}
	}
	fclose(fp_log);

	if (hOpen != NULL) {
		if (!InternetCloseHandle (hConnect) ) {
			ErrorOut (GetLastError (), "CloseHandle on hConnect");
			return FALSE;
		}
		if (!InternetCloseHandle (hOpen) ) {
			ErrorOut (GetLastError (), "CloseHandle on hOpen");
			return FALSE;
		}
	}
	return 0;
}
Exemple #16
0
void HandleFile(char* file_path, rebuild_content_t* p_rebuild_list)
{
	char* sz_vhd_buf = (char*)malloc(SECTOR_SIZE);
	memset(sz_vhd_buf, 0, SECTOR_SIZE);

	rebuild_content_t* p_rebuild_tmp = NULL;
	char tmp[SECTOR_SIZE] = {0};

/////////////////////////////// Handle VHD
	hd_ftr* vhd;
	vhd = (hd_ftr*)data;
	LARGE_INTEGER offset = {0};
	DWORD readsize = 0;

	/*Set hd_ftr struct*/
	vhd->orig_size = 0;   // clear
	vhd->orig_size = g_ll_file_size - SECTOR_SIZE;
	vhd->orig_size = INT64_TO_NET(vhd->orig_size);
	vhd->curr_size = vhd->orig_size;
	vhd->checksum = 0;

	/*calc checksum*/
	unsigned int temp = 0;
	for (int i = 0; i < 512; i++)
	{
		temp += data[i];
	}
	vhd->checksum = htonl(~temp);
///////////////////////////////////////////


	for(p_rebuild_tmp = p_rebuild_list->p_next; p_rebuild_tmp != NULL;) 
	{
		if (!ReadFileOffset(file_path, p_rebuild_tmp->ll_offset, p_rebuild_tmp->n_size, tmp, FILE_BEGIN))
			ErrorOut("Backup Read Error!\n");
		
		if (!WriteFileOffset(file_path, p_rebuild_tmp->ll_offset, p_rebuild_tmp->n_size, p_rebuild_tmp->content, FILE_BEGIN))
			ErrorOut("Backup Write Error!\n");

		memcpy(p_rebuild_tmp->content, tmp, p_rebuild_tmp->n_size);       // BackUp SECTOR
		p_rebuild_tmp = p_rebuild_tmp->p_next;
	}

/////////////////////////////////////////////////// BackUp VHD
	ReadFileOffset(file_path, -SECTOR_SIZE, SECTOR_SIZE, sz_vhd_buf, FILE_END);
	
/////////////////////////////////////////////*	*/// Write VHD
	WriteFileOffset(file_path, -SECTOR_SIZE, SECTOR_SIZE, (char*)vhd, FILE_END);

	printf("WriteFile Success! You can mount it as vhd file now!\n");
 	system("pause");


////////////////////////// Restore SECTOR

	for(p_rebuild_tmp = p_rebuild_list->p_next; p_rebuild_tmp != NULL;) 
	{
		if (!ReadFileOffset(file_path, p_rebuild_tmp->ll_offset, p_rebuild_tmp->n_size, tmp, FILE_BEGIN))
			ErrorOut("Restore Read Error!\n");

		if (!WriteFileOffset(file_path, p_rebuild_tmp->ll_offset, p_rebuild_tmp->n_size, p_rebuild_tmp->content, FILE_BEGIN))
			ErrorOut("Restore Write Error!\n");
		memcpy(p_rebuild_tmp->content, tmp, p_rebuild_tmp->n_size);       // BackUp SECTOR
		p_rebuild_tmp = p_rebuild_tmp->p_next;
	}

///////////////////////// Restore VHD
	WriteFileOffset(file_path, -SECTOR_SIZE, SECTOR_SIZE, sz_vhd_buf, FILE_END);

	printf("Restore File Success!\n");
}
Exemple #17
0
void Format::Scientific(ostream& os, double value, int nsig) const
{
   int i;
   double v = value;

   // check nsig >= 0
   if (nsig < 0) { ErrorOut(os); return; }

   // sign
   bool neg;
   if (v < 0) { v = -v; neg = true; }
   else neg = false;

   // exponent - first try
   int lv;
   if (v == 0.0) lv = 0;
   else lv = (int)floor(log10(v));           // power of 10 - first try
   v /= pow(10.0,lv);                        // normalise by power of 10

   // round
   double p = pow(10.0,nsig-1);              // aiming at nsig-1 decimal places
   double rv = floor(v * p + 0.5);           // rounded value * p

   // exponent - adjust
   if (rv >= 10.0 * p)
      { lv++; v /= 10.0; rv = floor(v * p + 0.5); }

   // will it fit
   int w = nsig;
   if (nsig > 1) w++;                          // for decimal
   if (neg || positive_val != Format::NX) w++; // for sign
   int np;                                     // decimals in power part
   if (lv >=100 || lv <= -100)
      { if (lv >=1000 || lv <= -1000) np = 4; else np = 3; }
   else np = 2;
   w += np + 2;                                // +2 is for e and sign
   if (w > max_width_val)
   {
      int ov = w - max_width_val;              // overflow
      // can rounding shift us from E-100 to E-99
      if ((lv == -100 || lv == -1000) && ov == 1)
      {
         double p1 = p / 10.0; 
         double rv1 = floor(v * p1 + 0.5);
         if (rv1 >= p)
         {
            double v1 = rv1 * pow(10.0, lv) / p1;
            if (neg) v1 = -v1;
            Scientific(os, v1, nsig);    
            return;
         }
      }
      if (overflow_policy_val == Format::HASH) { ErrorOut(os); return; }
      if (ov > 1) --ov;                        // in case characteristic length
                                               // drops when we round
      if (ov > 1) --ov;                        // in case we can drop decimal
      nsig -= ov;                              // how many sig figures
      if (nsig <= 0) { ErrorOut(os); return; } // can't print
      Scientific(os, value, nsig);             // try again with reduced nsig
      return;
   }

   // spaces
   int spaces = min_width_val - w;
   if (spaces < 0) spaces = 0;
   int s1, s2;                                    // leading and following sp
   if (alignment_val == Format::LEFT) { s1 = 0; s2 = spaces; }
   else if (alignment_val == Format::RIGHT) { s1 = spaces; s2 = 0; }
   else { s1 = spaces / 2; s2 = spaces - s1; }

   // leading spaces
   for (i = 0; i < s1; i++) os << ' ';

   // sign
   if (neg) os << '-';
   else if (positive_val == Format::SPACE) os << ' ';
   else if (positive_val == Format::PLUS) os << '+';

   // decimal part
   String sv; sv.resize(nsig);
   for (i = nsig-1;  i >= 0; i--)
   {
      double x; x = modf(rv/10, &rv);
      sv[i] = (char)('0' + (int)floor(x * 10 + 0.5));
   }
   os << sv[0];                            // first digit
   if (nsig > 1)                           // need decimal
      { os << '.'; for (int i = 1; i < nsig; i++) os << sv[i]; }

   // power part
   os << 'e';
   if (lv >= 0) os << '+'; else { os << '-'; lv = -lv; }
   sv.resize(np);
   for (i = np-1; i >= 0; i--)
   {
      int lv1 = lv / 10; int x = lv - lv1 * 10; lv = lv1;
      sv[i] = (char)('0' + x);
   }
   for (i = 0; i < np; i++) os << sv[i];

   // trailing blanks
   for (i = 0; i < s2; i++) os << ' ';
}
Exemple #18
0
void Format::DecFig(ostream& os, double value, int ndec,
   bool force_decimal) const
{
   int i;
   double v = value;
   bool variant1 = (variant_val == Format::VAR1);

   // sign
   bool neg;
   if (v < 0) { v = -v; neg = true; } else neg = false;

   // round and break into integer and decimal bits
   // iv will contain the integer part
   // v will contain the rounded decimal part, multiplied up to make an integer
   double p = pow(10.0,ndec);                  // 10 ** ndec
   double iv;                                  // integer part
   v = modf(v, &iv);                           // decimal parts
   v = floor(v * p + 0.5);                     // rounded decimal part
   if (v >= p) { iv += 1.0; v -= p; }          // decimal part over 1

   // check for underflow
   if ( iv == 0 &&
        value != 0.0 &&
        underflow_policy_val == Format::E &&
        !force_decimal &&
        (!variant1 || v < 0.1) )
      { Scientific(os, value, ndec+1); return; }
      
   // space available for integer part
   int li = max_width_val - ndec;                 // max space for integer part
   int lj = min_width_val - ndec;                 // min space for integer part

   // space for sign
   if (neg || positive_val != Format::NX) { li--; lj--; }

   // are we going to show the decimal point
   bool dp = (ndec > 0);
   if (dp) { li--; lj--; }                        // space for decimal point

   // try again with reduced number of decimals
   if (variant1)
   {                                               
      if (li < 0)
         { DecFig(os, value, ndec+li, force_decimal); return; }
   }
   else
   {                                               
      if (li < 1)
         { DecFig(os, value, ndec+li-1, force_decimal); return; }
   }

   String si(li, ' ');
   int nchar = 0;
   for (i = li-1; i >= 0; i--)
   {
      if (iv < 0.5) break;
      nchar++;                                    // chars in integer part
      double x; x = modf(iv/10, &iv);
      si[i] = (char)('0' + (int)floor(x * 10 + 0.5));
   }
   if (iv > 0.5)                                  // won't fit
   {
      if (overflow_policy_val == Format::HASH) ErrorOut(os);
      else  Scientific(os, value, max_width_val-4);// maybe do precision better
      return;
   }
   if (nchar == 0 && !variant1)
      { nchar = 1; si[li-1] = '0'; }              // integer part is zero

   int spaces = lj - nchar;                       // number of spaces
   if (spaces < 0) spaces = 0;
   int s1, s2;                                    // leading and following sp
   if (alignment_val == Format::LEFT) { s1 = 0; s2 = spaces; }
   else if (alignment_val == Format::RIGHT) { s1 = spaces; s2 = 0; }
   else { s1 = spaces / 2; s2 = spaces - s1; }
   
   // in VAR1 variant, if there are no decimals but there is room for
   // the decimal point, put it in.
   if (ndec == 0 && variant1 && s1 > 0) { dp = true; --s1; }

   // leading spaces
   for (i = 0; i < s1; i++) os << ' ';

   // sign
   if (neg) os << '-';
   else if (positive_val == Format::SPACE) os << ' ';
   else if (positive_val == Format::PLUS) os << '+';

   // integer part
   for (i = 0; i < nchar; i++) os << si[li - nchar + i];

   // decimal part
   if (dp)
   {
      os << '.';
      String sv(ndec, '0');
      for (i = ndec-1;  i >= 0; i--)
      {
         double x; x = modf(v/10, &v);
         sv[i] = (char)('0' + (int)floor(x * 10 + 0.5));
      }
      for (i = 0; i < ndec; i++) os << sv[i];
   }

   // trailing blanks
   for (i = 0; i < s2; i++) os << ' ';

}