📄 e00write.c
字号:
n=1; while(*(pszLine+1) == ' ') { n++; pszLine++; } strcpy( psInfo->szOutBuf+psInfo->iOutBufPtr, "~ "); psInfo->iOutBufPtr += 2; psInfo->szOutBuf[psInfo->iOutBufPtr++] = ' ' + n; } /*------------------------------------------------------------- * The cases below are specific to FULL compression. *------------------------------------------------------------*/ else if (psInfo->nComprLevel == E00_COMPR_FULL && isdigit(*pszLine)) { /* Keep track of current input/output buffer positions in case * we would have to revert the encoding. This could happen if * the numeric value is less than 4 characters. */ nStartOutBufPtr = psInfo->iOutBufPtr; pszStartSrcPtr = pszLine; /* Reset flags used for parsing numeric format */ nDigits = 0; nDotPosition = 0; /* 0 means no decimal point */ nExpSign = 0; /* 0 means no exponent */ numExpDigits = 0; numTotalDigits = 0; n = 0; /* Prepare the code sequence in the output buffer. * The code value will be set only after the number * is finished parsing. */ psInfo->szOutBuf[psInfo->iOutBufPtr++] = '~'; pszCodePos = psInfo->szOutBuf+psInfo->iOutBufPtr++; /* Scan the numeric sequence, encoding the digits as we read, * and keeping track of decimal point position and exponent. */ for(iCurPos=0; *pszLine != '\0' && numExpDigits<2; pszLine++, iCurPos++) { if (isdigit(*pszLine)) { /* Accumulate pairs of digits */ numTotalDigits++; if (numTotalDigits % 2 == 1) { n = (*pszLine - '0')*10; } else { n += (*pszLine - '0'); if (n >= 92) { /* Pairs of digits > 92 are encoded on 2 chars */ psInfo->szOutBuf[psInfo->iOutBufPtr++] = 92 + '!'; n -= 92; } psInfo->szOutBuf[psInfo->iOutBufPtr++] = n + '!'; } /* Count number of exponent digits to end the loop * once we've read 2 exponent digits */ if (nExpSign != 0) numExpDigits++; } else if (*pszLine == '.' && nDotPosition == 0 && iCurPos < 15) { /* Decimal point position... make sure that we have only * one decimal point, and that it is not beyond the 14th * position. If these conditions are not met then end the * numeric sequence here. */ nDotPosition = iCurPos; } else if (*pszLine == 'E' && (*(pszLine+1) == '-' || *(pszLine+1)=='+') && isdigit(*(pszLine+2)) && isdigit(*(pszLine+3)) && !isdigit(*(pszLine+4)) ) { /* Exponent ... fetch sign, and read only 2 more digits * A "E+" or "E-" MUST be followed by 2 and only 2 digits. * If it's not the case, then the numeric sequence ends * here. */ pszLine++; nExpSign = (*pszLine=='-') ? -1: 1; } else { /* Numeric sequence finished ... stop parsing. */ break; } }/*for ... parsing numeric value*/ /* If the numeric value contains an even number of digits, * then pad the last pair of digits with a zero and encode it. */ if (numTotalDigits % 2 == 1) { psInfo->szOutBuf[psInfo->iOutBufPtr++] = n + '!'; } /* If the character that ends the number is NOT a '~', a ' ' * or a 'end of line' then add a '~' to mark the end of the * number. This extra '~' will be ignored by the uncompress * algorithm. */ if (*(pszLine) != '~' && *(pszLine) != ' ' && *(pszLine) != '\0') { psInfo->szOutBuf[psInfo->iOutBufPtr++] = '~'; } /* At the end of the loop, the read pointer is located on the char * that follows the numeric value. Move it back 1 char so that * processing can continue later with the outer loop. */ pszLine--; /* Check that the parsed value contains enough characters to * justify encoding it. The encoded value should not be * bigger than the original. If the encoded value is the same * size as the original then it is still encoded (a bit silly!). * All numbers < 4 chars are not encoded, and some, such as * "1092" won't either because it would require 5 chars to * encode them. * * If the value should not be encoded, then overwrite the sutff * we started encoding with a direct copy of the numeric value. * * (At this point, iCurPos is equal to the number of chars in the * source value.) */ if ( iCurPos < psInfo->iOutBufPtr - nStartOutBufPtr ) { strncpy(psInfo->szOutBuf+ nStartOutBufPtr, pszStartSrcPtr, iCurPos); psInfo->iOutBufPtr = nStartOutBufPtr + iCurPos; } else { /* Now that we have parsed the numeric value, set the code * based on the characteristics we found. */ *pszCodePos = '!' + ((numTotalDigits % 2 == 1)? 45:0) + (nExpSign?((nExpSign>0)?15:30):0) + nDotPosition; } } else { /* This char cannot be compressed ... output directly. */ psInfo->szOutBuf[psInfo->iOutBufPtr++] = *pszLine; } /* Check for buffer overflow... just in case!!! */ if (psInfo->iOutBufPtr >= E00_WRITE_BUF_SIZE) { /* The buffer size has been set big enough to prevent this error * from ever happening. So if it ever happens, then it's likely * that the input lines were longer than 80 chars, which is the * maximum length of a uncompressed line in a E00 file. */ CPLError(CE_Failure, CPLE_FileIO, "Output buffer overflow!!!."); nStatus = 205; break; } /* Get ready to proceed with next char from input string */ pszLine++; } /* Terminate this line with a newline code * This code applies to both PARTIAL and FULL compresion. */ strcpy( psInfo->szOutBuf+psInfo->iOutBufPtr, "~}"); psInfo->iOutBufPtr += 2; return nStatus;}/********************************************************************** * _WriteNextCompressedLine() * * If bFlushWholeBuffer == 0, write the first 80 characters from * psInfo->szOutBuf, and remove the written chars from szOutBuf. * A '\n' (not counted in nMaxChars) will be written to terminate the * output line. * * Pass bFlushBuffer == 1 to force writing the whole contents of szOutBuf * at once. * * Returns 0 if the line was written succesfully, or an error number * (> 0) if an error happened. **********************************************************************/static int _WriteNextCompressedLine(E00WritePtr psInfo, int bFlushWholeBuffer){ int nStatus = 0, nToWrite; char *pszSrc, *pszDst; psInfo->szOutBuf[psInfo->iOutBufPtr] = '\0'; if (!bFlushWholeBuffer && psInfo->iOutBufPtr > 80) { /* Write the first 80 chars * Note that a compressed line cannot end with spaces... spaces should * be reported on the next line. */ nToWrite = 80; while(nToWrite > 1 && psInfo->szOutBuf[nToWrite-1] == ' ') nToWrite--; nStatus = _PrintfNextLine(psInfo, "%-.*s", nToWrite, psInfo->szOutBuf); /* Remove these chars from the output buffer */ pszDst = psInfo->szOutBuf; pszSrc = psInfo->szOutBuf+nToWrite; while(*pszSrc != '\0') { *pszDst = *pszSrc; pszDst++; pszSrc++; } psInfo->iOutBufPtr -= nToWrite; } else { /* Just write the buffer contents directly */ nStatus = _PrintfNextLine(psInfo, "%s", psInfo->szOutBuf); psInfo->iOutBufPtr = 0; } return nStatus;}/********************************************************************** * _PrintfNextLine() * * Cover function for fprintf() that will do error checking and * reporting, and either call fprintf() directly or call the callback * provided by the caller if E00WriteCallbackOpen() was used. * * A \n will be automatically appended to the string when it is * written, so no \n should be included at the end of pszFmt. * * Returns 0 on success, or error 204 if it failed. **********************************************************************/static int _PrintfNextLine(E00WritePtr psInfo, const char *pszFmt, ...){ va_list args; static char szBuf[E00_WRITE_BUF_SIZE]; int nStatus = 0; /* Expand the string to print */ va_start(args, pszFmt); vsprintf(szBuf, pszFmt, args); va_end(args); /* Write the line using the right method */ if (psInfo->pfnWriteNextLine == NULL) { /* Use fprintf() directly */ if ( VSIFPrintf(psInfo->fp, "%s\n", szBuf) < 0) { CPLError(CE_Failure, CPLE_FileIO, "Error writing to file: %s", strerror(errno)); nStatus = 204; } } else { /* Use pfnWritenextLine() callback */ if ( psInfo->pfnWriteNextLine(psInfo->pRefData, szBuf) < 0) { CPLError(CE_Failure, CPLE_FileIO, "Error writing to file."); nStatus = 204; } } return nStatus;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -