e00compr-1.0.1/0000755000175000017500000000000011151052151014526 5ustar aboudreaultaboudreaulte00compr-1.0.1/ex_read.c0000644000175000017500000000201211151051746016305 0ustar aboudreaultaboudreault/********************************************************************** * ex_read.c * * This example program illustrates the use of the E00ReadOpen() * and associated compressed E00 read functions. **********************************************************************/ #include #include "e00compr.h" int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; const char *pszLine; /* Open input */ hReadPtr = E00ReadOpen("test.e00"); if (hReadPtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if (CPLGetLastErrorNo() == 0) printf("%s\n", pszLine); else { /* An error happened while reading the last line... */ break; } } /* Close input file */ E00ReadClose(hReadPtr); } else { /* ERROR ... failed to open input file */ } return 0; } e00compr-1.0.1/cpl_conv.h0000755000175000017500000000566011151051746016525 0ustar aboudreaultaboudreault/****************************************************************************** * Copyright (c) 1998, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * cpl_conv.h * * Prototypes, and stuff for various convenience functions. This is intended * to remain light weight. * * $Log: * Revision 1.1 1998/10/18 06:15:11 warmerda * Initial implementation. * */ #ifndef CPL_CONV_H_INCLUDED #define CPL_CONV_H_INCLUDED #include "cpl_port.h" #include "cpl_vsi.h" #include "cpl_error.h" /* -------------------------------------------------------------------- */ /* Safe malloc() API. Thin cover over VSI functions with fatal */ /* error reporting if memory allocation fails. */ /* -------------------------------------------------------------------- */ CPL_C_START void CPL_DLL *CPLMalloc( size_t ); void CPL_DLL *CPLCalloc( size_t, size_t ); void CPL_DLL *CPLRealloc( void *, size_t ); char CPL_DLL *CPLStrdup( const char * ); #define CPLFree VSIFree /* -------------------------------------------------------------------- */ /* Read a line from a text file, and strip of CR/LF. */ /* -------------------------------------------------------------------- */ const char *CPLReadLine( FILE * ); /* -------------------------------------------------------------------- */ /* Fetch a function from DLL / so. */ /* -------------------------------------------------------------------- */ void CPL_DLL *CPLGetSymbol( const char *, const char * ); /* -------------------------------------------------------------------- */ /* Read a directory (cpl_dir.c) */ /* -------------------------------------------------------------------- */ char CPL_DLL **CPLReadDir( const char *pszPath ); CPL_C_END #endif /* ndef CPL_CONV_H_INCLUDED */ e00compr-1.0.1/ex_write.c0000644000175000017500000000311511151051746016531 0ustar aboudreaultaboudreault/********************************************************************** * ex_write.c * * This example program illustrates the use of the E00WriteOpen() * and associated compressed E00 write functions. **********************************************************************/ #include #include "e00compr.h" int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; E00WritePtr hWritePtr; const char *pszLine; int nStatus = 0; /* Open input file */ hReadPtr = E00ReadOpen("test1.e00"); if (hReadPtr) { /* Open output file */ hWritePtr = E00WriteOpen("test2.e00", E00_COMPR_FULL); if (hWritePtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if ((nStatus = CPLGetLastErrorNo()) == 0) nStatus = E00WriteNextLine(hWritePtr, pszLine); if (nStatus != 0) { /* An error happened while converting the last * line... abort*/ break; } } /* Close output file. */ E00WriteClose(hWritePtr); } else { /* ERROR ... failed to open output file */ nStatus = CPLGetLastErrorNo(); } /* Close input file. */ E00ReadClose(hReadPtr); } else { /* ERROR ... failed to open input file */ nStatus = CPLGetLastErrorNo(); } return nStatus; } e00compr-1.0.1/ex_readcb.c0000644000175000017500000000460211151051746016621 0ustar aboudreaultaboudreault/********************************************************************** * ex_readcb.c * * This example program illustrates the use of the E00ReadCallbackOpen() * and associated compressed E00 read functions. **********************************************************************/ #include #include "e00compr.h" static const char *myReadNextLine(void *pRefData); static void myReadRewind(void *pRefData); int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; const char *pszLine; FILE *fp; /* Open input file */ if ((fp = fopen("test.e00", "rt")) == NULL) { /* Error */ printf("Cannot open input file test.e00\n"); return 1; } /* Initialize reader */ hReadPtr = E00ReadCallbackOpen((void*)fp, myReadNextLine, myReadRewind); if (hReadPtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if (CPLGetLastErrorNo() == 0) printf("%s\n", pszLine); else { /* An error happened while reading the last line... */ break; } } /* Close input file */ E00ReadClose(hReadPtr); fclose(fp); } else { /* ERROR ... file is not a valid E00 */ } return 0; } /********************************************************************** * myReadNextLine() * * My own implementation of the ReadNextLine() function to test the * E00ReadCallbackOpen() functions. * * This function must return a reference to static buffer with the next * line of input, or NULL when it reaches EOF. **********************************************************************/ static const char *myReadNextLine(void *pRefData) { FILE *fp; static char szBuf[256]; fp = (FILE *)pRefData; if (fgets(szBuf, 255, fp) == NULL) return NULL; szBuf[255] = '\0'; return szBuf; } /********************************************************************** * myReadRewind() * * Callback function to rewind the file being read by myReadNextLine() **********************************************************************/ static void myReadRewind(void *pRefData) { rewind((FILE *)pRefData); } e00compr-1.0.1/HISTORY.TXT0000644000175000017500000000132211151051746016277 0ustar aboudreaultaboudreaultE00Compr library - Revision History =================================== Current Version: ---------------- Version 1.0.1 (2009-02-24): --------------------------- - Added a short manual page (#1875) - Updated documentation and code examples (#247) Version 1.0.0 (2005-09-17): --------------------------- - Switch to MIT license (previous license didn't allow modifications to the code) - Update refs to website and email address in docs. Version 0.5 (1999-02-25): ------------------------- Version 0.5 was the first complete and stable release. It should really have been called 1.0. No history information before this version. --------- $Id: HISTORY.TXT,v 1.3 2009-02-24 20:03:50 aboudreault Exp $ e00compr-1.0.1/e00write.c0000644000175000017500000005217111151051746016350 0ustar aboudreaultaboudreault/********************************************************************** * $Id: e00write.c,v 1.7 2009-02-24 20:03:50 aboudreault Exp $ * * Name: e00write.c * Project: Compressed E00 Read/Write library * Language: ANSI C * Purpose: Functions to write Compressed E00 files from a stream of * uncompressed lines. * Author: Daniel Morissette, dmorissette@mapgears.com * * $Log: e00write.c,v $ * Revision 1.7 2009-02-24 20:03:50 aboudreault * Added a short manual pages (#1875) * Updated documentation and code examples (#247) * * Revision 1.6 2005-09-17 14:22:05 daniel * Switch to MIT license, update refs to website and email address, and * prepare for 1.0.0 release. * * Revision 1.5 1999/02/25 18:46:41 daniel * Now use CPL for Error handling, Memory allocation, and File access. * * Revision 1.4 1999/01/08 17:40:01 daniel * Added E00WriteCallbackOpen() * * Revision 1.3 1998/11/13 16:54:23 daniel * Check for '\r' and '\n' at end of input line while compressing, just * in case... * * Revision 1.2 1998/11/13 15:48:42 daniel * Simplified the generation of the compression codes for numbers * (use a logical rule instead of going case by case) * * Revision 1.1 1998/11/13 14:19:51 daniel * Initial revision * ********************************************************************** * Copyright (c) 1998-2005, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * **********************************************************************/ #include #include #include #include #include #include "e00compr.h" static int _CompressLine(E00WritePtr psInfo, const char *pszLine); static int _WriteNextCompressedLine(E00WritePtr psInfo, int nMaxChars); static int _PrintfNextLine(E00WritePtr psInfo, const char *pszFmt, ...); /********************************************************************** * E00WriteOpen() * * Try to open output file, and alloc/initialize a new E00WritePtr * handle. * * nComprLevel must be one of: * E00_COMPR_NONE, E00_COMPR_PARTIAL or E00_COMPR_FULL * * Returns the new handle, or NULL if the file could not be opened. * E00WriteClose() will eventually have to be called to release * the resources used by the new handle. **********************************************************************/ E00WritePtr E00WriteOpen(const char *pszFname, int nComprLevel) { E00WritePtr psInfo = NULL; FILE *fp; CPLErrorReset(); /* Open the file */ fp = VSIFOpen(pszFname, "wt"); if (fp == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open %s: %s", pszFname, strerror(errno)); return NULL; } /* Allocate and initialize a E00ReadPtr handle. */ psInfo = (E00WritePtr)CPLCalloc(1, sizeof(struct _E00WriteInfo)); psInfo->fp = fp; psInfo->nComprLevel = nComprLevel; return psInfo; } /********************************************************************** * E00WriteCallbackOpen() * * This is an alternative to E00WriteOpen() for cases where you want to * do all the file management yourself. You open/close the file yourself * and provide a callback functions to write one line at a time to the * file. pRefData is your handle on the physical file and can * be whatever you want... it is not used by the library, it will be * passed directly to your callback function when it is called. * * The callback function must have the following C prototype: * * int myWriteNextLine(void *pRefData, const char *pszLine); * * Like printf() does, myWriteNextLine() should return a positive * value on success (the number of chars written) * or -1 if an error happened. * The value passed by the library in pszLine will not be terminated * by a '\n' character... it is assumed that the myWriteNextLine() * implementation will take care of terminating the line with a * '\n' if necessary. * * nComprLevel must be one of: * E00_COMPR_NONE, E00_COMPR_PARTIAL or E00_COMPR_FULL * * E00WriteCallbackOpen() returns a new E00ReadWritePtr handle. * E00WriteClose() will eventually have to be called to release * the resources used by the new handle. **********************************************************************/ E00WritePtr E00WriteCallbackOpen(void *pRefData, int (*pfnWriteNextLine)(void *, const char *), int nComprLevel) { E00WritePtr psInfo = NULL; CPLErrorReset(); /* Make sure we received a valid function pointer */ if (pfnWriteNextLine == NULL) { CPLError(CE_Failure, CPLE_IllegalArg, "Invalid function pointer!"); return NULL; } /* Allocate and initialize a E00ReadPtr handle. */ psInfo = (E00WritePtr)CPLCalloc(1, sizeof(struct _E00WriteInfo)); psInfo->pRefData = pRefData; psInfo->pfnWriteNextLine = pfnWriteNextLine; psInfo->nComprLevel = nComprLevel; return psInfo; } /********************************************************************** * E00WriteClose() * * Close output file and release any memory used by the E00WritePtr. **********************************************************************/ void E00WriteClose(E00WritePtr psInfo) { CPLErrorReset(); if (psInfo) { /* Flush output buffer before closing file. */ if (psInfo->iOutBufPtr > 0) _WriteNextCompressedLine(psInfo, 1); if (psInfo->fp) fclose(psInfo->fp); CPLFree(psInfo); } } /********************************************************************** * E00WriteNextLine() * * Take a line of what should be headed to a uncompressed E00 file, * convert it to the requested compression level, and write the * compressed result to the output file. * * Returns 0 if the line was processed succesfully, or an error number * (> 0) if an error happened. **********************************************************************/ int E00WriteNextLine(E00WritePtr psInfo, const char *pszLine) { char *pszPtr; int nStatus = 0; CPLErrorReset(); if (psInfo && (psInfo->fp || psInfo->pfnWriteNextLine)) { psInfo->nSrcLineNo++; if (psInfo->nComprLevel == E00_COMPR_NONE) { /* Uncompressed file... write line directly. */ nStatus = _PrintfNextLine(psInfo, "%s", pszLine); } else if (psInfo->nSrcLineNo == 1) { /* Header line in a compressed file... write line * after replacing "EXP 0" with "EXP 1". */ if ((pszPtr = strstr(pszLine, " 0")) != NULL) { nStatus = _PrintfNextLine(psInfo, "EXP 1%s", pszPtr+2); } else { /* Write line directly... assume that it contains a valid * EXP prefix! */ nStatus = _PrintfNextLine(psInfo, "%s", pszLine); } } else { /* FULL or PARTIAL compression... compress the current line, * (output goes in psInfo->szOutBuf) */ nStatus = _CompressLine(psInfo, pszLine); while (nStatus == 0 && psInfo->iOutBufPtr >= 80) { /* Time to write the first 80 chars from the output buffer */ nStatus = _WriteNextCompressedLine(psInfo, 0); } } } else { /* This should never happen unless the lib is not properly used * or if an error happened in previous calls and was ignored by * the caller */ CPLError(CE_Failure, CPLE_IllegalArg, "Invalid E00WritePtr handle!"); nStatus = 203; } return nStatus; } /********************************************************************** * _CompressLine() * * Compress one line of input, and store the compressed copy at the * end of psInfo->pszOutBuf. * * Returns 0 if the line was compressed succesfully, or an error number * (> 0) if an error happened. **********************************************************************/ static int _CompressLine(E00WritePtr psInfo, const char *pszLine) { int nStatus = 0; int nDigits, nExpSign, nDotPosition, iCurPos; int numTotalDigits, numExpDigits; char n, *pszCodePos; int nStartOutBufPtr; const char *pszStartSrcPtr; while(*pszLine != '\0' && *pszLine != '\n' && *pszLine != '\r') { /*------------------------------------------------------------- * By default, apply PARTIAL compression * Note that PARTIAL is a subset of FULL compression. *------------------------------------------------------------*/ if (*pszLine == '~') { /* The '~' char is encoded as "~~" */ strcpy( psInfo->szOutBuf+psInfo->iOutBufPtr, "~~"); psInfo->iOutBufPtr += 2; } else if (strncmp(pszLine, " ", 3) == 0) { /* A stream of at least 3 spaces. * Count number of spaces and replace with a "~ n" code */ 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; } e00compr-1.0.1/e00compr.mak0000755000175000017500000001766311151051746016676 0ustar aboudreaultaboudreault# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 !IF "$(CFG)" == "" CFG=e00compr - Win32 Debug !MESSAGE No configuration specified. Defaulting to e00compr - Win32 Debug. !ENDIF !IF "$(CFG)" != "e00compr - Win32 Release" && "$(CFG)" !=\ "e00compr - Win32 Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE on this makefile !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "e00compr.mak" CFG="e00compr - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "e00compr - Win32 Release" (based on\ "Win32 (x86) Console Application") !MESSAGE "e00compr - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF ################################################################################ # Begin Project # PROP Target_Last_Scanned "e00compr - Win32 Debug" RSC=rc.exe CPP=cl.exe !IF "$(CFG)" == "e00compr - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" OUTDIR=.\Release INTDIR=.\Release ALL : "$(OUTDIR)\e00conv.exe" CLEAN : -@erase ".\e00conv.exe" -@erase ".\Release\e00read.obj" -@erase ".\Release\e00write.obj" -@erase ".\Release\e00error.obj" -@erase ".\Release\e00conv.obj" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" # ADD BASE CPP /nologo /W3 /GX /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c # ADD CPP /nologo /W3 /GX /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c CPP_PROJ=/nologo /ML /W3 /GX /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)/e00compr.pch" /YX /Fo"$(INTDIR)/" /c CPP_OBJS=.\Release/ CPP_SBRS= # ADD BASE RSC /l 0xc0c /d "NDEBUG" # ADD RSC /l 0xc0c /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo BSC32_FLAGS=/nologo /o"$(OUTDIR)/e00compr.bsc" BSC32_SBRS= LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"e00conv.exe" LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ odbccp32.lib /nologo /subsystem:console /incremental:no\ /pdb:"$(OUTDIR)/e00conv.pdb" /machine:I386 /out:"e00conv.exe" LINK32_OBJS= \ "$(INTDIR)/e00read.obj" \ "$(INTDIR)/e00write.obj" \ "$(INTDIR)/e00error.obj" \ "$(INTDIR)/e00conv.obj" "$(OUTDIR)\e00conv.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << !ELSEIF "$(CFG)" == "e00compr - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" OUTDIR=.\Debug INTDIR=.\Debug ALL : "$(OUTDIR)\e00conv.exe" CLEAN : -@erase ".\Debug\vc40.pdb" -@erase ".\Debug\vc40.idb" -@erase ".\e00conv.exe" -@erase ".\Debug\e00write.obj" -@erase ".\Debug\e00error.obj" -@erase ".\Debug\e00read.obj" -@erase ".\Debug\e00conv.obj" -@erase ".\e00conv.ilk" -@erase ".\Debug\e00conv.pdb" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)/e00compr.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c CPP_OBJS=.\Debug/ CPP_SBRS= # ADD BASE RSC /l 0xc0c /d "_DEBUG" # ADD RSC /l 0xc0c /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo BSC32_FLAGS=/nologo /o"$(OUTDIR)/e00compr.bsc" BSC32_SBRS= LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"e00conv.exe" LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ odbccp32.lib /nologo /subsystem:console /incremental:yes\ /pdb:"$(OUTDIR)/e00conv.pdb" /debug /machine:I386 /out:"e00conv.exe" LINK32_OBJS= \ "$(INTDIR)/e00write.obj" \ "$(INTDIR)/e00error.obj" \ "$(INTDIR)/e00read.obj" \ "$(INTDIR)/e00conv.obj" "$(OUTDIR)\e00conv.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << !ENDIF .c{$(CPP_OBJS)}.obj: $(CPP) $(CPP_PROJ) $< .cpp{$(CPP_OBJS)}.obj: $(CPP) $(CPP_PROJ) $< .cxx{$(CPP_OBJS)}.obj: $(CPP) $(CPP_PROJ) $< .c{$(CPP_SBRS)}.sbr: $(CPP) $(CPP_PROJ) $< .cpp{$(CPP_SBRS)}.sbr: $(CPP) $(CPP_PROJ) $< .cxx{$(CPP_SBRS)}.sbr: $(CPP) $(CPP_PROJ) $< ################################################################################ # Begin Target # Name "e00compr - Win32 Release" # Name "e00compr - Win32 Debug" !IF "$(CFG)" == "e00compr - Win32 Release" !ELSEIF "$(CFG)" == "e00compr - Win32 Debug" !ENDIF ################################################################################ # Begin Source File SOURCE=.\e00read.c !IF "$(CFG)" == "e00compr - Win32 Release" DEP_CPP_E00RE=\ ".\e00compr.h"\ NODEP_CPP_E00RE=\ ".\iDecimalPoint"\ ".\psInfo"\ "$(INTDIR)\e00read.obj" : $(SOURCE) $(DEP_CPP_E00RE) "$(INTDIR)" !ELSEIF "$(CFG)" == "e00compr - Win32 Debug" DEP_CPP_E00RE=\ ".\e00compr.h"\ "$(INTDIR)\e00read.obj" : $(SOURCE) $(DEP_CPP_E00RE) "$(INTDIR)" !ENDIF # End Source File ################################################################################ # Begin Source File SOURCE=.\e00error.c DEP_CPP_E00ER=\ ".\e00compr.h"\ "$(INTDIR)\e00error.obj" : $(SOURCE) $(DEP_CPP_E00ER) "$(INTDIR)" # End Source File ################################################################################ # Begin Source File SOURCE=.\e00write.c !IF "$(CFG)" == "e00compr - Win32 Release" DEP_CPP_E00WR=\ ".\e00compr.h"\ NODEP_CPP_E00WR=\ ".\+"\ "$(INTDIR)\e00write.obj" : $(SOURCE) $(DEP_CPP_E00WR) "$(INTDIR)" !ELSEIF "$(CFG)" == "e00compr - Win32 Debug" DEP_CPP_E00WR=\ ".\e00compr.h"\ "$(INTDIR)\e00write.obj" : $(SOURCE) $(DEP_CPP_E00WR) "$(INTDIR)" !ENDIF # End Source File ################################################################################ # Begin Source File SOURCE=.\e00conv.c !IF "$(CFG)" == "e00compr - Win32 Release" DEP_CPP_E00CO=\ ".\e00compr.h"\ NODEP_CPP_E00CO=\ ".\of"\ "$(INTDIR)\e00conv.obj" : $(SOURCE) $(DEP_CPP_E00CO) "$(INTDIR)" !ELSEIF "$(CFG)" == "e00compr - Win32 Debug" DEP_CPP_E00CO=\ ".\e00compr.h"\ "$(INTDIR)\e00conv.obj" : $(SOURCE) $(DEP_CPP_E00CO) "$(INTDIR)" !ENDIF # End Source File # End Target # End Project ################################################################################ e00compr-1.0.1/cpl_vsisimple.c0000755000175000017500000002077111151051746017566 0ustar aboudreaultaboudreault/****************************************************************************** * Copyright (c) 1998, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * cpl_vsisimple.cpp * * This is a simple implementation (direct to Posix) of the Virtual System * Interface (VSI). See gdal_vsi.h. * * TODO: * - add some assertions to ensure that arguments are widely legal. For * instance validation of access strings to fopen(). * * $Log: cpl_vsisimple.cpp,v $ * Revision 1.3 1998/12/14 04:50:33 warmerda * Avoid C++ comments so it will be C compilable as well. * * Revision 1.2 1998/12/04 21:42:57 danmo * Added #ifndef WIN32 arounf #include * * Revision 1.1 1998/12/03 18:26:03 warmerda * New * */ #include "cpl_vsi.h" /* for stat() */ #ifndef WIN32 # include #endif #include /************************************************************************/ /* VSIFOpen() */ /************************************************************************/ FILE *VSIFOpen( const char * pszFilename, const char * pszAccess ) { return( fopen( (char *) pszFilename, (char *) pszAccess ) ); } /************************************************************************/ /* VSIFClose() */ /************************************************************************/ int VSIFClose( FILE * fp ) { return( fclose(fp) ); } /************************************************************************/ /* VSIFSeek() */ /************************************************************************/ int VSIFSeek( FILE * fp, long nOffset, int nWhence ) { return( fseek( fp, nOffset, nWhence ) ); } /************************************************************************/ /* VSIFTell() */ /************************************************************************/ long VSIFTell( FILE * fp ) { return( ftell( fp ) ); } /************************************************************************/ /* VSIRewind() */ /************************************************************************/ void VSIRewind( FILE * fp ) { rewind( fp ); } /************************************************************************/ /* VSIFRead() */ /************************************************************************/ size_t VSIFRead( void * pBuffer, size_t nSize, size_t nCount, FILE * fp ) { return( fread( pBuffer, nSize, nCount, fp ) ); } /************************************************************************/ /* VSIFWrite() */ /************************************************************************/ size_t VSIFWrite( void * pBuffer, size_t nSize, size_t nCount, FILE * fp ) { return( fwrite( pBuffer, nSize, nCount, fp ) ); } /************************************************************************/ /* VSIFGets() */ /************************************************************************/ char *VSIFGets( char *pszBuffer, int nBufferSize, FILE * fp ) { return( fgets( pszBuffer, nBufferSize, fp ) ); } /************************************************************************/ /* VSIFGetc() */ /************************************************************************/ int VSIFGetc( FILE * fp ) { return( fgetc( fp ) ); } /************************************************************************/ /* VSIUngetc() */ /************************************************************************/ int VSIUngetc( int c, FILE * fp ) { return( ungetc( c, fp ) ); } /************************************************************************/ /* VSIFPrintf() */ /* */ /* This is a little more complicated than just calling */ /* fprintf() because of the variable arguments. Instead we */ /* have to use vfprintf(). */ /************************************************************************/ int VSIFPrintf( FILE * fp, const char * pszFormat, ... ) { va_list args; int nReturn; va_start( args, pszFormat ); nReturn = vfprintf( fp, pszFormat, args ); va_end( args ); return( nReturn ); } /************************************************************************/ /* VSIFEof() */ /************************************************************************/ int VSIFEof( FILE * fp ) { return( feof( fp ) ); } /************************************************************************/ /* VSIFPuts() */ /************************************************************************/ int VSIFPuts( const char * pszString, FILE * fp ) { return fputs( pszString, fp ); } /************************************************************************/ /* VSIFPutc() */ /************************************************************************/ int VSIFPutc( int nChar, FILE * fp ) { return( fputc( nChar, fp ) ); } /************************************************************************/ /* VSICalloc() */ /************************************************************************/ void *VSICalloc( size_t nCount, size_t nSize ) { return( calloc( nCount, nSize ) ); } /************************************************************************/ /* VSIMalloc() */ /************************************************************************/ void *VSIMalloc( size_t nSize ) { return( malloc( nSize ) ); } /************************************************************************/ /* VSIRealloc() */ /************************************************************************/ void * VSIRealloc( void * pData, size_t nNewSize ) { return( realloc( pData, nNewSize ) ); } /************************************************************************/ /* VSIFree() */ /************************************************************************/ void VSIFree( void * pData ) { if( pData != NULL ) free( pData ); } /************************************************************************/ /* VSIStrdup() */ /************************************************************************/ char *VSIStrdup( const char * pszString ) { return( strdup( pszString ) ); } /************************************************************************/ /* VSIStat() */ /************************************************************************/ int VSIStat( const char * pszFilename, VSIStatBuf * pStatBuf ) { return( stat( pszFilename, pStatBuf ) ); } e00compr-1.0.1/e00compr.html0000644000175000017500000006165211151051746017064 0ustar aboudreaultaboudreault
E00compr - Compressed E00 Read/Write Library

E00compr 1.0

Compressed E00 Read/Write Library

By Daniel Morissette, dmorissette@mapgears.com


The latest version of this documentation and of the whole package can be obtained from http://avce00.maptools.org/

Table of Contents

Copyright and License terms

The most part of the E00COMPR library is Copyright (c) 1998-2005, Daniel Morissette (dmorissette@mapgears.com)
it also contains portions (CPL lib) that are Copyright (c) 1998-1999, Frank Warmerdam (warmerdam@pobox.com)

The AVCE00 library and the supporting CPL code are freely available under the following Open Source license terms:

Copyright (c) 1998-2005, Daniel Morissette
Copyright (c) 1998-1999, Frank Warmerdam

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

What is E00compr?

E00compr is an ANSI C library that reads and writes Arc/Info compressed E00 files. Both "PARTIAL" and "FULL" compression levels are supported.

This package can be divided in three parts:

  • The 'e00conv' command-line program. This program takes a E00 file as input (compressed or not) and copies it to a new file with the requested compression level (NONE, PARTIAL or FULL).

  • A set of library functions to read compressed E00 files. These functions read a E00 file (compressed or not) and return a stream of uncompressed lines, making the E00 file appear as if it was not compressed.

  • A set of library functions to write compressed E00 files. These functions take one line after another from what should be a uncompressed E00 file, and write them to a file with the requested compression level, either NONE, PARTIAL or FULL.

Building the package

The library has already been succesfully built on Windows (with MSVC++ 4 and 5), and on Linux (with gcc).

Windows users:

    A MSVC++ 4 makefile (e00compr.mak) to build the 'e00conv.exe' command-line program is included with the distribution. You should have no problem opening this file with MSVC++ and building the package directly.

    MSVC++ 5 will ask you if you want to convert the makefile to the new project format. Answer "Yes" and you should be just fine.

    If you are using another development environment, then you will likley need to build your own project. Include the following files in your project:

      e00compr.h
      e00read.c
      e00write.c

      cpl_port.h
      cpl_conv.h
      cpl_error.h
      cpl_vsi.h
      cpl_conv.c
      cpl_error.c
      cpl_vsisimple.c

Unix users:

    A Makefile is included with the distribution. Its default target will build the 'e00conv' executable using gcc. Take a look at the definitions at the top of the Makefile to see if you need to modify it to build in your own environment.

    In most cases, building the package should be as simple as extracting the distribution files to a empty directory, and then going to this directory and typing make.

    If you encounter problems with the Makefile, then make sure that it contains Unix line breaks. The line breaks are sometimes altered when the distribution is copied between PCs and Unix systems, and Make doesn't seem to like Makefiles that contain DOS CR-LF line breaks.

Using the 'e00conv' Conversion Program

'e00conv' is a command-line executable that takes a E00 file as input (compressed or not) and copies it to a new file with the requested compression level (NONE, PARTIAL or FULL).

    e00conv <input_file> <output_file> [NONE|PARTIAL|FULL]

    • input_file is the name of the E00 file to read from.

    • output_file is the name of the file to create. If the file already exists then it is overwritten.

    • The last argument is optional and specifies the compression level to use when creating the output file (one of NONE, PARTIAL or FULL). The default is NONE (uncompressed).

How to use the library in your programs


Note: If you are not planning to use the library in your programs,
then you can stop reading here...
the rest of this document won't be of any use to you!

To use the library in your programs, include the file "e00compr.h", and link with the "e00compr.a" library produced by the Unix Makefile.

If you are working in a Windows development environment (i.e. with projects, no Makefiles!) then add all the C files from the distribution to your project, except "e00conv.c".

Library functions to Read compressed E00 files

All the read functions are defined inside "e00read.c". Information about the file currently being read is stored inside an internal structure. You do not need to understand the contents of this structure to use the library.

All you need is to declare a E00ReadPtr variable which will serve as a handle on the input file for all the other functions.

You use the following functions to read a E00 file:

    E00ReadPtr  E00ReadOpen(const char *pszFname);
    void        E00ReadClose(E00ReadPtr hInfo);

    const char *E00ReadNextLine(E00ReadPtr hInfo);
    void        E00ReadRewind(E00ReadPtr hInfo);
Each function is described after the example below.

Example:

    This short example uses the library to read a E00 compressed file ("test.e00") and prints the uncompressed result to stdout.

    /**********************************************************************
     *                          ex_read.c
     *
     * This example program illustrates the use of the E00ReadOpen()
     * and associated compressed E00 read functions.
     **********************************************************************/
    
    #include <stdio.h>
    
    #include "e00compr.h"
    
    int main(int argc, char *argv[])
    {
        E00ReadPtr  hReadPtr;
        const char  *pszLine;
    
        /* Open input */
        hReadPtr = E00ReadOpen("test.e00");
    
        if (hReadPtr)
        {
            /* Read lines from input until we reach EOF */
            while((pszLine = E00ReadNextLine(hReadPtr)) != NULL)
            {
                if (CPLGetLastErrorNo() == 0)
                    printf("%s\n", pszLine);
                else
                {
                    /* An error happened while reading the last line... */
                    break;
                }
            }
    
            /* Close input file */
            E00ReadClose(hReadPtr);
        }
        else
        {
            /* ERROR ... failed to open input file */
        }
    
        return 0;
    }
      

E00ReadPtr data type

    A variable of type E00ReadPtr serves as a handle on the current input file.

    The handle is allocated by E00ReadOpen(), and you must call E00ReadClose() to properly release the memory associated with it.

E00ReadOpen()

    E00ReadPtr E00ReadOpen(const char *pszFname);

    Opens a E00 input file and returns a E00ReadPtr handle.

    The input file can be in compressed or uncompressed format. E00ReadClose() will eventually have to be called to release the returned handle.

    Returns NULL if the file could not be opened or if it does not appear to be a valid E00 file.

E00ReadCallbackOpen()

    E00ReadPtr  E00ReadCallbackOpen(void *pRefData,
                                    const char * (*pfnReadNextLine)(void *),
                                    void (*pfnReadRewind)(void *));
    

    This is an alternative to E00ReadOpen() for cases where you have to do all the file management yourself. You open/close the file yourself and provide 2 callback functions: to read from the file and rewind the file pointer.

    pRefData is your own handle on the physical file and can be whatever you want... it is not used by the library, it will be passed directly to your 2 callback functions when they are called.

    The callback functions must have the following C prototype:

        const char *myReadNextLine(void *pRefData);
        void        myReadRewind(void *pRefData);
        

      myReadNextLine() should return a reference to its own internal buffer, or NULL if an error happens or when EOF is reached.

    E00ReadCallbackOpen() returns a E00ReadPtr handle or NULL if the file does not appear to be a valid E00 file.

    For an example of the use of this method, see the file ex_readcb.c included in the library distribution.

E00ReadClose()

    void E00ReadClose(E00ReadPtr hInfo);

    Closes the physical file and releases any memory associated with a E00ReadPtr handle.

E00ReadNextLine()

    const char *E00ReadNextLine(E00ReadPtr hInfo);

    Returns the next line of input from the E00 file in uncompressed form or NULL if we reached EOF or if an error happened. The returned line is a null-terminated string, and it does not include a newline character. Call CPLGetLastErrorNo() after calling E00ReadNextLine() to make sure that the whole line was read succesfully.

    Note that E00ReadNextLine() returns a reference to an internal buffer whose contents will be valid only until the next call to this function. The caller should not attempt to free() the returned pointer.

E00ReadRewind()

    void E00ReadRewind(E00ReadPtr hInfo);

    Rewinds the E00ReadPtr just like the stdio rewind() function would do.

    Useful when you have to do multiple read passes on the same input file.

Library functions to Write compressed E00 files

The write functions are defined inside "e00write.c". The information about the file currently being written is stored inside an internal structure. As for the read library, you do not need to understand the contents of this structure to use the library.

Your program has to declare a E00WritePtr variable which will serve as a handle on the output file for all the other functions.

You use the following functions to write a E00 file:

    E00WritePtr E00WriteOpen(const char *pszFname, int nComprLevel);
    void        E00WriteClose(E00WritePtr hInfo);

    int		E00WriteNextLine(E00WritePtr hInfo, const char *pszLine);
Each function is described after the example below.

Example:

    This example is a simpler version of the "e00conv.c" program that is included with this distribution. It uses the read library to read a E00 file ("test1.e00") and uses the write library to copy its contents one line at a time to a new E00 file ("test2.e00") with FULL compression:

    /**********************************************************************
     *                          ex_write.c
     *
     * This example program illustrates the use of the E00WriteOpen()
     * and associated compressed E00 write functions.
     **********************************************************************/
    #include <stdio.h>
    
    #include "e00compr.h"
    
    int main(int argc, char *argv[])
    {
        E00ReadPtr  hReadPtr;
        E00WritePtr hWritePtr;
        const char  *pszLine;
        int         nStatus = 0;
    
        /* Open input file */
        hReadPtr = E00ReadOpen("test1.e00");
    
        if (hReadPtr)
        {
            /* Open output file */
            hWritePtr = E00WriteOpen("test2.e00", E00_COMPR_FULL);
    
            if (hWritePtr)
            {
                /* Read lines from input until we reach EOF */
                while((pszLine = E00ReadNextLine(hReadPtr)) != NULL)
                {
                    if ((nStatus = CPLGetLastErrorNo()) == 0)
                        nStatus = E00WriteNextLine(hWritePtr, pszLine);
    
                    if (nStatus != 0)
                    {
                        /* An error happened while converting the last 
                         * line... abort*/
                        break;
                    }
                }
                /* Close output file. */
                E00WriteClose(hWritePtr);
            }
            else
            {
                /* ERROR ... failed to open output file */
                nStatus = CPLGetLastErrorNo();
            }
    
            /* Close input file. */
            E00ReadClose(hReadPtr);
        }
        else
        {
            /* ERROR ... failed to open input file */
            nStatus = CPLGetLastErrorNo();
        }
    
        return nStatus;
    }
    

E00WritePtr data type

    A variable of type E00WritePtr serves as a handle on the current input file.

    The handle is allocated by E00WriteOpen(), and you must call E00WriteClose() to properly release the memory associated with it.

E00WriteOpen()

    E00WritePtr E00WriteOpen(const char *pszFname, int nComprLevel);

    Creates a new E00 file for output with the specified compression level, and returns a E00WritePtr handle for it. If the file already exists, then it is overwritten.

    nComprLevel is one of Arc/Info's 3 levels of compression:

    • E00_COMPR_NONE - creates an uncompressed file.
    • E00_COMPR_PARTIAL - creates a file with PARTIAL compression.
    • E00_COMPR_FULL - creates a file with FULL compression.

    Returns NULL if the file could not be opened.

E00WriteCallbackOpen()

    E00WritePtr E00WriteCallbackOpen(void *pRefData,
                                     int (*pfnWriteNextLine)(void *, const char *),
                                     int nComprLevel);
    

    This is an alternative to E00WriteOpen() for cases where you have to do all the file management yourself. You open/close the file yourself and provide a callback function to write one line at a time to the file.

    pRefData is your own handle on the physical file and can be whatever you want... it is not used by the library, it will be passed directly to your callback function when it is called.

    The callback function must have the following C prototype:

        int    myWriteNextLine(void *pRefData, const char *pszLine);
    

      myWriteNextLine() should return a positive value on success (the number of chars written, like printf() does) or -1 if an error happened.

      The value passed by the library in pszLine is not terminated by a '\n' character... it is assumed that your myWriteNextLine() implementation will take care of terminating the line with a '\n' if necessary.

    nComprLevel is one of Arc/Info's 3 levels of compression:

    • E00_COMPR_NONE - creates an uncompressed file.
    • E00_COMPR_PARTIAL - creates a file with PARTIAL compression.
    • E00_COMPR_FULL - creates a file with FULL compression.

    E00WriteCallbackOpen() returns a new E00ReadWritePtr handle and E00WriteClose() will eventually have to be called to release the resources used by the new handle.

    For an example of the use of this method, see the file ex_writecb.c included in the library distribution.

E00WriteClose()

    void E00WriteClose(E00WritePtr hInfo);

    Closes the physical file and release any memory associated with a E00WritePtr handle.

E00WriteNextLine()

    int E00WriteNextLine(E00WritePtr hInfo, const char *pszLine);

    Takes the next line of what should be headed to a uncompressed E00 file, converts it to the requested compression level, and writes the (compressed) result to the output file.

    pszLine should be a null-terminated string with a maximum of 80 characters (E00 lines cannot be longer than 80 characters). Do NOT include a '\n' at the end of the line, it will be added automatically by the function if it is needed.

    Returns 0 if the line was processed succesfully, or an error number (see error codes below) if an error happened.

    Note that this function does not do any syntax check on the input you provide. It assumes that what you pass to it is a valid stream of E00 lines as they would appear in an uncompressed E00 file.

Trapping errors reported by the library

When errors happen, the library's default behavior is to report an error message on stderr, and to fail nicely, usually by simulating a EOF situation. Errors are reported through the function CPLError() defined in "cpl_error.c".

While this is sufficient for the purposes of the 'e00conv' command-line program, you may want to trap and handle errors yourself if you use the library in a bigger application (a GUI application for instance).

CPLSetErrorHandler()

    void  CPLSetErrorHandler(void (*pfnErrorHandler)(CPLErr, int, const char *));
    

    You can use CPLSetErrorHandler() to override the default error handler function. Your new error handler should be a C function with the following prototype:

      void MyErrorHandler(CPLErr eErrClass, int err_no, const char *msg);

    And you register it with the following call at the beginning of your program:

      CPLSetErrorHandler( MyErrorHandler );

CPLError()

    void CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...);

    The library reports errors through this function. It's default behavior is to display the error messages to stderr, but it can be overridden using CPLSetErrorHandler().

    You can call CPLGetLastErrorNo() or CPLGetLastErrorMsg() to get the last error number and string.

    eErrClass defines the severity of the error:

        typedef enum
        {
            CE_None = 0,
            CE_Log = 1,
            CE_Warning = 2,
            CE_Failure = 3,
            CE_Fatal = 4
        } CPLErr;
    

    Error class CE_Fatal will abort the execution of the program, it is mainly used for out of memory errors, or unrecoverable situations of that kind. All the other error classes return control to the calling function.

CPLGetLastErrorNo()

    int         CPLGetLastErrorNo();

    Returns the number of the last error that was produced. Returns 0 if the last library function that was called completed without any error. See the list of possible error numbers below.

    Note: This function works even if you redefined your own error handler using CPLSetErrorHandler() .

CPLGetLastErrorMsg()

    const char *CPLGetLastErrorMsg();

    Returns a reference to a static buffer containing the last error message that was produced. The caller should not attempt to free this buffer. Returns an empty string ("") if the last library function that was called completed without any error.

    Note: This function works even if you redefined your own error handler using CPLSetErrorHandler() .

Errors generated by the library and their meaning:

The values for the error codes returned by the library are defined in the file cpl_error.h.

    #define CPLE_OutOfMemory		2
    #define CPLE_FileIO			3
    #define CPLE_OpenFailed			4
    #define CPLE_IllegalArg			5
    #define CPLE_NotSupported		6
    #define CPLE_AssertionFailed		7
    

The following errors codes can be returned:

Error CodeDescription
0 Success, no error.
CPLE_OutOfMemory Memory allocation failed. This is a fatal error, it will abort the program execution. There is currently no proper way to recover from it.
CPLE_FileIO Unexpected error reading or writing to a file. This can also happen if an input file is corrupt.
CPLE_OpenFailed Failed to open the input ou output file. Check for permissions, disk space, etc.
CPLE_IllegalArg
CPLE_AssertionFailed
Illegal argument passed to one of the library's functions. This is a kind of internal error that should not happen unless the lib is modified or is not used as it is expected.
CPLE_NotSupported One of the functions encountered an unsupported/unexpected case in one of the files. This error can also be a sign that the file is corrupt.


Last Update: $Date: 2009-02-24 20:03:50 $
Daniel Morissette, dmorissette@mapgears.com
e00compr-1.0.1/README.TXT0000644000175000017500000000440711151051746016102 0ustar aboudreaultaboudreault E00compr Compressed E00 Read/Write Library -------------------------------------- Please see the file "e00compr.html" for the documentation. If you do not have access to a HTML viewer (or web browser), then see "e00compr.txt" which is a text-only version of the same file. The latest version of this documentation and of the whole package can be obtained from http://avce00.maptools.org/ COPYRIGHT AND LICENSE TERMS: ---------------------------- The most part of the E00COMPR library is Copyright (c) 1998-2005, Daniel Morissette (dmorissette@mapgears.com) it also contains portions (CPL lib) that are Copyright (c) 1998-1999, Frank Warmerdam (warmerdam@pobox.com) The AVCE00 library and the supporting CPL code are freely available under the following Open Source license terms: ********************************************************************** * Copyright (c) 1998-2005, Daniel Morissette * Copyright (c) 1998-1999, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ********************************************************************** ----- $Id: README.TXT,v 1.3 2009-02-24 20:03:50 aboudreault Exp $ ----- e00compr-1.0.1/e00error.c0000644000175000017500000001146111151051746016344 0ustar aboudreaultaboudreault/********************************************************************** * $Id: e00error.c,v 1.7 2009-02-24 20:03:50 aboudreault Exp $ * * Name: e00error.c * Project: Compressed E00 Read/Write library * Language: ANSI C * Purpose: Error handling functions. * Author: Daniel Morissette, dmorissette@mapgears.com * * $Log: e00error.c,v $ * Revision 1.7 2009-02-24 20:03:50 aboudreault * Added a short manual pages (#1875) * Updated documentation and code examples (#247) * * Revision 1.6 2005-09-17 14:22:05 daniel * Switch to MIT license, update refs to website and email address, and * prepare for 1.0.0 release. * * Revision 1.5 1999/01/08 17:38:19 daniel * Changed E00Error argument "errno" to "nErrNo" to fix a warning with gcc * * Revision 1.4 1998/11/02 18:37:04 daniel * New file header, and added E00ErrorReset() * * Revision 1.1 1998/10/29 13:26:00 daniel * Initial revision * ********************************************************************** * Copyright (c) 1998-2005, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * **********************************************************************/ #include #include #include "e00compr.h" /* static buffer to store the last error message. We'll assume that error * messages cannot be longer than 2000 chars... which is quite reasonable * (that's 25 lines of 80 chars!!!) */ static char gszE00LastErrMsg[2000] = ""; static int gnE00LastErrNo = 0; static void (*gpfnE00ErrorHandler)(int, const char *) = NULL; /********************************************************************** * E00Error() * * This function records an error code and displays the error message * to stderr. * * The error code can be accessed later using E00GetLastErrNo() **********************************************************************/ void E00Error(int nErrNo, const char *pszFmt, ...) { va_list args; gnE00LastErrNo = nErrNo; /* Expand the error message */ va_start(args, pszFmt); vsprintf(gszE00LastErrMsg, pszFmt, args); va_end(args); /* If the user provided his own error handling function, then call * it, otherwise print the error to stderr and return. */ if (gpfnE00ErrorHandler != NULL) { gpfnE00ErrorHandler(nErrNo, gszE00LastErrMsg); } else { fprintf(stderr, "ERROR %d: %s\n", gnE00LastErrNo, gszE00LastErrMsg); } } /********************************************************************** * E00ErrorReset() * * Erase traces of previous errors. **********************************************************************/ void E00ErrorReset() { gnE00LastErrNo = 0; gszE00LastErrMsg[0] = '\0'; } /********************************************************************** * CPLGetLastErrorNo() * **********************************************************************/ int CPLGetLastErrorNo() { return gnE00LastErrNo; } /********************************************************************** * E00GetLastErrorMsg() * **********************************************************************/ const char* E00GetLastErrorMsg() { return gszE00LastErrMsg; } /********************************************************************** * E00SetErrorHandler() * * Let the library user specify his own error handler function. * * A valid error handler is a C function with the following prototype: * * void MyErrorHandler(int nErrNo, const char *pszMsg) * * Pass NULL to come back to the default behavior. **********************************************************************/ void E00SetErrorHandler(void (*pfnErrorHandler)(int, const char *)) { gpfnE00ErrorHandler = pfnErrorHandler; } e00compr-1.0.1/e00conv.c0000644000175000017500000001241711151051746016162 0ustar aboudreaultaboudreault/********************************************************************** * $Id: e00conv.c,v 1.8 2009-02-24 20:03:50 aboudreault Exp $ * * Name: e00conv.c * Project: Compressed E00 Read/Write library * Language: ANSI C * Purpose: Command-line program that uses the Compressed E00 * Read/Write library to convert a E00 file from one level * of compression to another. * (Note: the current version only writes uncompressed E00) * Author: Daniel Morissette, dmorissette@mapgears.com * * $Log: e00conv.c,v $ * Revision 1.8 2009-02-24 20:03:50 aboudreault * Added a short manual pages (#1875) * Updated documentation and code examples (#247) * * Revision 1.7 2005-09-17 14:22:05 daniel * Switch to MIT license, update refs to website and email address, and * prepare for 1.0.0 release. * * Revision 1.6 1999/02/25 18:29:51 daniel * Now use CPL error handling and memory allocations * * Revision 1.5 1998/11/13 15:40:38 daniel * Added support for wirting compressed files. * * Revision 1.4 1998/11/02 18:37:04 daniel * New file header, and added E00ErrorReset() * * Revision 1.1 1998/10/29 13:26:00 daniel * Initial revision * ********************************************************************** * Copyright (c) 1998-2005, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * **********************************************************************/ #include #include #include "e00compr.h" /********************************************************************** * main() * **********************************************************************/ int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; E00WritePtr hWritePtr; const char *pszInFile = NULL, *pszOutFile = NULL; const char *pszLine; int nStatus = 0, nComprLevel = E00_COMPR_NONE; /* ---------------------------------------------------------------- * Parse input parameters * ---------------------------------------------------------------*/ if (argc >= 4) { /* 4th param is compression level (NONE, PARTIAL or FULL) * Default is NONE. * * We simply check the first char: N, P or F */ switch(toupper(argv[3][0])) { case 'F': nComprLevel = E00_COMPR_FULL; break; case 'P': nComprLevel = E00_COMPR_PARTIAL; break; case 'N': default: nComprLevel = E00_COMPR_NONE; } } if (argc >= 3) { /* Input and output file names */ pszInFile = argv[1]; pszOutFile = argv[2]; } else { printf("\n"); printf("E00CONV - Version %s\n", E00COMPR_VERSION); printf(" Converts Arc/Info E00 files from one level of compression to another.\n"); printf(" Copyright (c) 1999-2005, Daniel Morissette (dmorissette@mapgears.com)\n"); printf(" E00COMPR web page: http://avce00.maptools.org/\n"); printf("\n"); printf("Usage: e00conv [NONE|PARTIAL|FULL]\n"); printf("\n"); return 1; } /* ---------------------------------------------------------------- * Open files and proceed with the conversion * ---------------------------------------------------------------*/ hReadPtr = E00ReadOpen(pszInFile); if (hReadPtr) { hWritePtr = E00WriteOpen(pszOutFile, nComprLevel); if (hWritePtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if ((nStatus = CPLGetLastErrorNo()) == 0) nStatus = E00WriteNextLine(hWritePtr, pszLine); if (nStatus != 0) { /* An error happened while converting the last * line... abort*/ break; } } /* Close files. */ E00WriteClose(hWritePtr); } else nStatus = CPLGetLastErrorNo(); E00ReadClose(hReadPtr); } else nStatus = CPLGetLastErrorNo(); return nStatus; } e00compr-1.0.1/e00compr.h0000644000175000017500000001573111151051746016344 0ustar aboudreaultaboudreault/********************************************************************** * $Id: e00compr.h,v 1.10 2009-02-24 20:03:50 aboudreault Exp $ * * Name: e00compr.h * Project: Compressed E00 Read/Write library * Language: ANSI C * Purpose: Header file containing all definitions for the library. * Author: Daniel Morissette, dmorissette@mapgears.com * * $Log: e00compr.h,v $ * Revision 1.10 2009-02-24 20:03:50 aboudreault * Added a short manual pages (#1875) * Updated documentation and code examples (#247) * * Revision 1.9 2005-09-17 14:22:05 daniel * Switch to MIT license, update refs to website and email address, and * prepare for 1.0.0 release. * * Revision 1.8 1999/03/03 18:47:07 daniel * Moved extern "C" after #include lines (form MSVC++ 6) * * Revision 1.7 1999/02/25 18:47:40 daniel * Now use CPL for Error handling, Memory allocation, and File access. * * Revision 1.6 1999/01/08 17:40:33 daniel * Added E00Read/WriteCallbakcOpen() * * Revision 1.5 1998/11/13 15:39:45 daniel * Added functions for write support. * * Revision 1.4 1998/11/02 18:37:03 daniel * New file header, and added E00ErrorReset() * * Revision 1.1 1998/10/29 13:26:00 daniel * Initial revision * ********************************************************************** * Copyright (c) 1998-2005, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * **********************************************************************/ #ifndef _E00COMPR_H_INCLUDED_ #define _E00COMPR_H_INCLUDED_ #include #include "cpl_port.h" #include "cpl_conv.h" #include "cpl_error.h" #ifdef __cplusplus extern "C" { #endif /*--------------------------------------------------------------------- * Current version of the library... always useful! *--------------------------------------------------------------------*/ #define E00COMPR_VERSION "1.0.0 (2005-09-17)" /*===================================================================== Data types and constants =====================================================================*/ #define E00_READ_BUF_SIZE 256 /* E00 lines are always 80 chars or less */ /* for both compressed and uncompressed */ /* files, except the first line (the EXP)*/ /* for which there is no known limit */ /* We'll assume that it can't be longer */ /* than 256 chars */ #define E00_WRITE_BUF_SIZE 256 /* This buffer must be big enough to hold*/ /* at least 2 lines of compressed output */ /* (i.e. 160 chars)... but just in case */ /* compressing a line would ever result */ /* in it becoming bigger than its source */ /* we'll set the size to 256 chars! */ #define E00_COMPR_NONE 0 /* Compression levels to use when writing*/ #define E00_COMPR_PARTIAL 1 #define E00_COMPR_FULL 2 /*--------------------------------------------------------------------- * E00ReadPtr * * A E00ReadPtr handle is used to hold information about the compressed * file currently being read. *--------------------------------------------------------------------*/ struct _E00ReadInfo { FILE *fp; /* Input file handle */ int bEOF; /* Reached EOF? */ int bIsCompressed; /* 1 if file is compressed, 0 if not */ int nInputLineNo; int iInBufPtr; /* Last character processed in szInBuf */ char szInBuf[E00_READ_BUF_SIZE]; /* compressed input buffer */ char szOutBuf[E00_READ_BUF_SIZE];/* uncompressed output buffer */ /* pRefData, pfnReadNextLine() and pfnReadRewind() are used only * when the file is opened with E00ReadCallbackOpen() * (and in this case the FILE *fp defined above is not used) */ void * pRefData; const char * (*pfnReadNextLine)(void *); void (*pfnReadRewind)(void *); }; typedef struct _E00ReadInfo *E00ReadPtr; /*--------------------------------------------------------------------- * E00WritePtr * * A E00WritePtr handle is used to hold information about the * file currently being written. *--------------------------------------------------------------------*/ struct _E00WriteInfo { FILE *fp; /* Output file handle */ int nComprLevel; int nSrcLineNo; int iOutBufPtr; /* Current position in szOutBuf */ char szOutBuf[E00_WRITE_BUF_SIZE]; /* compressed output buffer */ /* pRefData and pfnWriteNextLine() are used only * when the file is opened with E00WriteCallbackOpen() * (and in this case the FILE *fp defined above is not used) */ void *pRefData; int (*pfnWriteNextLine)(void *, const char *); }; typedef struct _E00WriteInfo *E00WritePtr; /*===================================================================== Function prototypes =====================================================================*/ E00ReadPtr E00ReadOpen(const char *pszFname); E00ReadPtr E00ReadCallbackOpen(void *pRefData, const char * (*pfnReadNextLine)(void *), void (*pfnReadRewind)(void *)); void E00ReadClose(E00ReadPtr psInfo); const char *E00ReadNextLine(E00ReadPtr psInfo); void E00ReadRewind(E00ReadPtr psInfo); E00WritePtr E00WriteOpen(const char *pszFname, int nComprLevel); E00WritePtr E00WriteCallbackOpen(void *pRefData, int (*pfnWriteNextLine)(void *, const char *), int nComprLevel); void E00WriteClose(E00WritePtr psInfo); int E00WriteNextLine(E00WritePtr psInfo, const char *pszLine); #ifdef __cplusplus } #endif #endif /* _E00COMPR_H_INCLUDED_ */ e00compr-1.0.1/cpl_port.h0000755000175000017500000001740511151051746016544 0ustar aboudreaultaboudreault/****************************************************************************** * Copyright (c) 1998, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * cpl_port.h * * Include file providing low level portability services for CPL. This * should be the first include file for any CPL based code. It provides the * following: * * o Includes some standard system include files, such as stdio, and stdlib. * * o Defines CPL_C_START, CPL_C_END macros. * * o Ensures that some other standard macros like NULL are defined. * * o Defines some portability stuff like CPL_MSB, or CPL_LSB. * * o Ensures that core types such as GBool, GInt32, GInt16, GUInt32, * GUInt16, and GByte are defined. * * $Log: cpl_port.h,v $ * Revision 1.9 1999/02/17 01:41:17 warmerda * Added NULL. * * Revision 1.8 1999/02/02 21:32:38 warmerda * Added CPL_{MSB,LSB}WORD{16,32} macros. * * Revision 1.7 1999/02/02 19:02:36 warmerda * Removed duplicates of base types, and CPL_LSB * * Revision 1.6 1999/01/28 18:36:06 warmerda * Ensure WIN32 is defined on Windows. * * Revision 1.5 1999/01/28 05:26:12 danmo * Added byte swapping macros. * * Revision 1.4 1998/12/15 19:05:30 warmerda * added errno.h * * Revision 1.3 1998/12/14 04:50:07 warmerda * Added DBMALLOC support * * Revision 1.2 1998/12/04 21:38:40 danmo * Changed str*casecmp() to str*icmp() for WIN32 * * Revision 1.1 1998/12/03 18:26:02 warmerda * New * */ #ifndef CPL_BASE_H_INCLUDED #define CPL_BASE_H_INCLUDED /* ==================================================================== */ /* We will use WIN32 as a standard windows define. */ /* ==================================================================== */ #if defined(_WIN32) && !defined(WIN32) # define WIN32 #endif /* ==================================================================== */ /* Standard include files. */ /* ==================================================================== */ #include #include #include #include #include #include #ifdef DBMALLOC #include #endif /* ==================================================================== */ /* Base portability stuff ... this stuff may need to be */ /* modified for new platforms. */ /* ==================================================================== */ /*--------------------------------------------------------------------- * types for 16 and 32 bits integers, etc... *--------------------------------------------------------------------*/ #if UINT_MAX == 65535 typedef long GInt32; typedef unsigned long GUInt32; #else typedef int GInt32; typedef unsigned int GUInt32; #endif typedef short GInt16; typedef unsigned short GUInt16; typedef unsigned char GByte; typedef int GBool; /* ==================================================================== */ /* Other standard services. */ /* ==================================================================== */ #ifdef __cplusplus # define CPL_C_START extern "C" { # define CPL_C_END } #else # define CPL_C_START # define CPL_C_END #endif /* # define CPL_DLL __declspec(dllexport) */ #define CPL_DLL #ifndef NULL # define NULL 0 #endif #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE 1 #endif #ifndef MAX # define MIN(a,b) ((ab) ? a : b) #endif #ifndef NULL #define NULL 0 #endif #ifndef ABS # define ABS(x) ((x<0) ? (-1*(x)) : x) #endif #ifndef EQUAL #ifdef WIN32 # define EQUALN(a,b,n) (strnicmp(a,b,n)==0) # define EQUAL(a,b) (stricmp(a,b)==0) #else # define EQUALN(a,b,n) (strncasecmp(a,b,n)==0) # define EQUAL(a,b) (strcasecmp(a,b)==0) #endif #endif /*--------------------------------------------------------------------- * CPL_LSB and CPL_MSB * Only one of these 2 macros should be defined and specifies the byte * ordering for the current platform. * This should be defined in the Makefile, but if it is not then * the default is CPL_LSB (Intel ordering, LSB first). *--------------------------------------------------------------------*/ #if ! ( defined(CPL_LSB) || defined(CPL_MSB) ) #define CPL_LSB #endif /*--------------------------------------------------------------------- * Little endian <==> big endian byte swap macros. *--------------------------------------------------------------------*/ #define CPL_SWAP16(x) \ ((GUInt16)( \ (((GUInt16)(x) & 0x00ffU) << 8) | \ (((GUInt16)(x) & 0xff00U) >> 8) )) #define CPL_SWAP32(x) \ ((GUInt32)( \ (((GUInt32)(x) & (GUInt32)0x000000ffUL) << 24) | \ (((GUInt32)(x) & (GUInt32)0x0000ff00UL) << 8) | \ (((GUInt32)(x) & (GUInt32)0x00ff0000UL) >> 8) | \ (((GUInt32)(x) & (GUInt32)0xff000000UL) >> 24) )) /* Until we have a safe 64 bits integer data type defined, we'll replace m * this version of the CPL_SWAP64() macro with a less efficient one. */ /* #define CPL_SWAP64(x) \ ((uint64)( \ (uint64)(((uint64)(x) & (uint64)0x00000000000000ffULL) << 56) | \ (uint64)(((uint64)(x) & (uint64)0x000000000000ff00ULL) << 40) | \ (uint64)(((uint64)(x) & (uint64)0x0000000000ff0000ULL) << 24) | \ (uint64)(((uint64)(x) & (uint64)0x00000000ff000000ULL) << 8) | \ (uint64)(((uint64)(x) & (uint64)0x000000ff00000000ULL) >> 8) | \ (uint64)(((uint64)(x) & (uint64)0x0000ff0000000000ULL) >> 24) | \ (uint64)(((uint64)(x) & (uint64)0x00ff000000000000ULL) >> 40) | \ (uint64)(((uint64)(x) & (uint64)0xff00000000000000ULL) >> 56) )) */ #define CPL_SWAPDOUBLE(p) { \ double _tmp = *(double *)(p); \ ((GByte *)(p))[0] = ((GByte *)&_tmp)[7]; \ ((GByte *)(p))[1] = ((GByte *)&_tmp)[6]; \ ((GByte *)(p))[2] = ((GByte *)&_tmp)[5]; \ ((GByte *)(p))[3] = ((GByte *)&_tmp)[4]; \ ((GByte *)(p))[4] = ((GByte *)&_tmp)[3]; \ ((GByte *)(p))[5] = ((GByte *)&_tmp)[2]; \ ((GByte *)(p))[6] = ((GByte *)&_tmp)[1]; \ ((GByte *)(p))[7] = ((GByte *)&_tmp)[0]; \ } #ifdef CPL_MSB # define CPL_MSBWORD16(x) (x) # define CPL_LSBWORD16(x) CPL_SWAP16(x) # define CPL_MSBWORD32(x) (x) # define CPL_LSBWORD32(x) CPL_SWAP32(x) #else # define CPL_LSBWORD16(x) (x) # define CPL_MSBWORD16(x) CPL_SWAP16(x) # define CPL_LSBWORD32(x) (x) # define CPL_MSBWORD32(x) CPL_SWAP32(x) #endif #endif /* ndef CPL_BASE_H_INCLUDED */ e00compr-1.0.1/cpl_conv.c0000755000175000017500000001456611151051746016525 0ustar aboudreaultaboudreault/****************************************************************************** * Copyright (c) 1998, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * cpl_conv.c: Various CPL convenience functions (from cpl_conv.h). * * $Log: cpl_conv.cpp,v $ * Revision 1.4 1999/01/02 20:29:53 warmerda * Allow zero length allocations * * Revision 1.3 1998/12/15 19:01:07 warmerda * Added CPLReadLine(). * * Revision 1.2 1998/12/03 18:30:04 warmerda * Use CPLError() instead of GPSError(). * * Revision 1.1 1998/12/02 19:33:23 warmerda * New * */ #include "cpl_conv.h" /************************************************************************/ /* CPLCalloc() */ /************************************************************************/ void *CPLCalloc( size_t nCount, size_t nSize ) { void *pReturn; if( nSize == 0 ) return NULL; pReturn = VSICalloc( nCount, nSize ); if( pReturn == NULL ) { CPLError( CE_Fatal, CPLE_OutOfMemory, "CPLCalloc(): Out of memory allocating %d bytes.\n", nSize * nCount ); } return pReturn; } /************************************************************************/ /* CPLMalloc() */ /************************************************************************/ void *CPLMalloc( size_t nSize ) { void *pReturn; if( nSize == 0 ) return NULL; pReturn = VSIMalloc( nSize ); if( pReturn == NULL ) { CPLError( CE_Fatal, CPLE_OutOfMemory, "CPLMalloc(): Out of memory allocating %d bytes.\n", nSize ); } return pReturn; } /************************************************************************/ /* CPLRealloc() */ /************************************************************************/ void * CPLRealloc( void * pData, size_t nNewSize ) { void *pReturn; if( pData == NULL ) pReturn = VSIMalloc( nNewSize ); else pReturn = VSIRealloc( pData, nNewSize ); if( pReturn == NULL ) { CPLError( CE_Fatal, CPLE_OutOfMemory, "CPLRealloc(): Out of memory allocating %d bytes.\n", nNewSize ); } return pReturn; } /************************************************************************/ /* CPLStrdup() */ /************************************************************************/ char *CPLStrdup( const char * pszString ) { char *pszReturn; if( pszString == NULL ) pszString = ""; pszReturn = VSIStrdup( pszString ); if( pszReturn == NULL ) { CPLError( CE_Fatal, CPLE_OutOfMemory, "CPLStrdup(): Out of memory allocating %d bytes.\n", strlen(pszString) ); } return( pszReturn ); } /************************************************************************/ /* CPLReadLine() */ /* */ /* Read a line of text from the given file handle, taking care */ /* to capture CR and/or LF and strip off ... equivelent of */ /* DKReadLine(). Pointer to an internal buffer is returned. */ /* The application shouldn't free it, or depend on it's value */ /* past the next call to CPLReadLine() */ /* */ /* TODO: Allow arbitrarily long lines ... currently limited to */ /* 512 characters. */ /************************************************************************/ const char *CPLReadLine( FILE * fp ) { static char *pszRLBuffer = NULL; static int nRLBufferSize = 0; int nLength; /* -------------------------------------------------------------------- */ /* Allocate our working buffer. Eventually this should grow as */ /* needed ... we will implement that aspect later. */ /* -------------------------------------------------------------------- */ if( nRLBufferSize < 512 ) { nRLBufferSize = 512; pszRLBuffer = (char *) CPLRealloc(pszRLBuffer, nRLBufferSize); } /* -------------------------------------------------------------------- */ /* Do the actual read. */ /* -------------------------------------------------------------------- */ if( VSIFGets( pszRLBuffer, nRLBufferSize, fp ) == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Clear CR and LF off the end. */ /* -------------------------------------------------------------------- */ nLength = strlen(pszRLBuffer); if( nLength > 0 && (pszRLBuffer[nLength-1] == 10 || pszRLBuffer[nLength-1] == 13) ) { pszRLBuffer[--nLength] = '\0'; } if( nLength > 0 && (pszRLBuffer[nLength-1] == 10 || pszRLBuffer[nLength-1] == 13) ) { pszRLBuffer[--nLength] = '\0'; } return( pszRLBuffer ); } e00compr-1.0.1/e00conv.10000644000175000017500000000165111151051746016076 0ustar aboudreaultaboudreault.TH E00CONV 1 "September 24, 2005" .SH NAME e00conv \- Converts Arc/Info E00 files from one level of compression to another. .SH SYNOPSIS .B e00conv .RI " [NONE|PARTIAL|FULL]" .SH DESCRIPTION .B e00conv is a program takes a E00 file as input (compressed or not) and copies it to a new file with the requested compression level (NONE, PARTIAL or FULL). .SH OPTIONS .P input_file is the name of the E00 file to read from. .P output_file is the name of the file to create. If the file already exists then it is overwritten. .P The last argument is optional and specifies the compression level to use when creating the output file (one of NONE, PARTIAL or FULL). The default is NONE (uncompressed). .SH SEE ALSO The program documentation available in HTML format. .SH AUTHOR e00conv was written by Daniel Morissette . .PP This manual page was written by Paul Wise . e00compr-1.0.1/cpl_error.c0000644000175000017500000001230711151051746016675 0ustar aboudreaultaboudreault/********************************************************************** * $Id: cpl_error.cpp,v 1.3 1998/12/15 19:02:27 warmerda Exp $ * * Name: cpl_error.cpp * Project: CPL - Common Portability Library * Purpose: Error handling functions. * Author: Daniel Morissette, dmorissette@mapgears.com * ********************************************************************** * Copyright (c) 1998, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ********************************************************************** * * $Log: cpl_error.cpp,v $ * Revision 1.3 1998/12/15 19:02:27 warmerda * Avoid use of errno as a variable * * Revision 1.2 1998/12/06 02:52:52 warmerda * Implement assert support * * Revision 1.1 1998/12/03 18:26:02 warmerda * New * **********************************************************************/ #include "cpl_error.h" /* static buffer to store the last error message. We'll assume that error * messages cannot be longer than 2000 chars... which is quite reasonable * (that's 25 lines of 80 chars!!!) */ static char gszCPLLastErrMsg[2000] = ""; static int gnCPLLastErrNo = 0; static void (*gpfnCPLErrorHandler)(CPLErr, int, const char *) = NULL; /********************************************************************** * CPLError() * * This function records an error code and displays the error message * to stderr. * * The error code can be accessed later using CPLGetLastErrNo() **********************************************************************/ void CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...) { va_list args; /* Expand the error message */ va_start(args, fmt); vsprintf(gszCPLLastErrMsg, fmt, args); va_end(args); /* If the user provided his own error handling function, then call * it, otherwise print the error to stderr and return. */ gnCPLLastErrNo = err_no; if (gpfnCPLErrorHandler != NULL) { gpfnCPLErrorHandler(eErrClass, err_no, gszCPLLastErrMsg); } else { fprintf(stderr, "ERROR %d: %s\n", gnCPLLastErrNo, gszCPLLastErrMsg); } if( eErrClass == CE_Fatal ) abort(); } /********************************************************************** * CPLErrorReset() * * Erase any traces of previous errors. **********************************************************************/ void CPLErrorReset() { gnCPLLastErrNo = 0; gszCPLLastErrMsg[0] = '\0'; } /********************************************************************** * CPLGetLastErrorNo() * **********************************************************************/ int CPLGetLastErrorNo() { return gnCPLLastErrNo; } /********************************************************************** * CPLGetLastErrorMsg() * **********************************************************************/ const char* CPLGetLastErrorMsg() { return gszCPLLastErrMsg; } /********************************************************************** * CPLSetErrorHandler() * * Allow the library's user to specify his own error handler function. * * A valid error handler is a C function with the following prototype: * * void MyErrorHandler(int errno, const char *msg) * * Pass NULL to come back to the default behavior. **********************************************************************/ void CPLSetErrorHandler(void (*pfnErrorHandler)(CPLErr, int, const char *)) { gpfnCPLErrorHandler = pfnErrorHandler; } /************************************************************************/ /* _CPLAssert() */ /* */ /* This function is called only when an assertion fails. */ /************************************************************************/ void _CPLAssert( const char * pszExpression, const char * pszFile, int iLine ) { CPLError( CE_Fatal, CPLE_AssertionFailed, "Assertion `%s' failed\n" "in file `%s', line %d\n", pszExpression, pszFile, iLine ); } e00compr-1.0.1/ex_writecb.c0000644000175000017500000000611611151051746017042 0ustar aboudreaultaboudreault/********************************************************************** * ex_writecb.c * * This example program illustrates the use of the E00WriteCallbackOpen() * and associated compressed E00 write functions. **********************************************************************/ #include #include "e00compr.h" static int myWriteNextLine(void *pRefData, const char *pszLine); int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; E00WritePtr hWritePtr = NULL; const char *pszLine; FILE *fp; int nStatus = 0; /* Open input file */ hReadPtr = E00ReadOpen("test1.e00"); if (hReadPtr) { /* Open output file, and if succesful then initialize the writer * using the myWriteNextLine callback method. * For the purposes of this example, fp will be used directly * as reference data for the callback. */ if ((fp = fopen("test2.e00", "wt")) != NULL) { hWritePtr = E00WriteCallbackOpen((void *)fp, myWriteNextLine, E00_COMPR_FULL); } if (hWritePtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if ((nStatus = CPLGetLastErrorNo()) == 0) nStatus = E00WriteNextLine(hWritePtr, pszLine); if (nStatus != 0) { /* An error happened while converting the last * line... abort*/ break; } } /* Close output file. */ E00WriteClose(hWritePtr); } else { /* ERROR ... failed to open output file */ nStatus = CPLGetLastErrorNo(); } /* Close the physical output file */ if (fp) fclose(fp); /* Close input file. */ E00ReadClose(hReadPtr); } else { /* ERROR ... failed to open input file */ nStatus = CPLGetLastErrorNo(); } return nStatus; } /********************************************************************** * myWriteNextLine() * * My own implementation of the ReadWriteNextLine() function to test the * E00WriteCallbackOpen() functions. * * This function writes a line to the E00 file. The line that is passed * as argument won't be terminated by a '\n', it is the responsibility * of this function to add one if needed. * * myWriteNextLine() should return a positive value on success (the number * of chars written, as printf() does) or -1 if an error happened... **********************************************************************/ static int myWriteNextLine(void *pRefData, const char *pszLine) { int nStatus; /* For the purpose of this example, pRefData is the actual FILE * * but it can be whatever you want... */ nStatus = fprintf((FILE *)pRefData, "%s\n", pszLine); return nStatus; } e00compr-1.0.1/e00compr.txt0000755000175000017500000005535111151051746016741 0ustar aboudreaultaboudreault E00compr 1.0 Compressed E00 Read/Write Library By Daniel Morissette, dmorissette@mapgears.com -------------------------------------- The latest version of this documentation and of the whole package can be obtained from http://avce00.maptools.org/ -------------------------------------- Table of Contents * Copyright and License terms * What is E00compr? * Building the package * Using the 'e00conv' Conversion program * How to use the library in your programs * Library functions to Read compressed E00 files o Example o E00ReadPtr data type o E00ReadOpen() o E00ReadCallbackOpen() o E00ReadClose() o E00ReadNextLine() o E00ReadRewind() * Library functions to Write compressed E00 files o Example o E00WritePtr data type o E00WriteOpen() o E00WriteCallbackOpen() o E00WriteClose() o E00WriteNextLine() * Trapping errors reported by the library o CPLSetErrorHandler() o CPLError() o CPLGetLastErrorNo() o CPLGetLastErrorMsg() o Errors generated by the library and their meaning Copyright and License terms The most part of the E00COMPR library is Copyright (c) 1998-2005, Daniel Morissette (dmorissette@mapgears.com) it also contains portions (CPL lib) that are Copyright (c) 1998-1999, Frank Warmerdam (warmerdam@pobox.com) The AVCE00 library and the supporting CPL code are freely available under the following Open Source license terms: Copyright (c) 1998-2005, Daniel Morissette Portions Copyright (c) 1998-1999, Frank Warmerdam Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. What is E00compr? E00compr is an ANSI C library that reads and writes Arc/Info compressed E00 files. Both "PARTIAL" and "FULL" compression levels are supported. This package can be divided in three parts: * The 'e00conv' command-line program. This program takes a E00 file as input (compressed or not) and copies it to a new file with the requested compression level (NONE, PARTIAL or FULL). * A set of library functions to read compressed E00 files. These functions read a E00 file (compressed or not) and return a stream of uncompressed lines, making the E00 file appear as if it was not compressed. * A set of library functions to write compressed E00 files. These functions take one line after another from what should be a uncompressed E00 file, and write them to a file with the requested compression level, either NONE, PARTIAL or FULL. Building the package The library has already been succesfully built on Windows (with MSVC++ 4 and 5), and on Linux (with gcc). Windows users: A MSVC++ 4 makefile (e00compr.mak) to build the 'e00conv.exe' command-line program is included with the distribution. You should have no problem opening this file with MSVC++ and building the package directly. MSVC++ 5 will ask you if you want to convert the makefile to the new project format. Answer "Yes" and you should be just fine. If you are using another development environment, then you will likley need to build your own project. Include the following files in your project: e00compr.h e00read.c e00write.c cpl_port.h cpl_conv.h cpl_error.h cpl_vsi.h cpl_conv.c cpl_error.c cpl_vsisimple.c Unix users: A Makefile is included with the distribution. Its default target will build the 'e00conv' executable using gcc. Take a look at the definitions at the top of the Makefile to see if you need to modify it to build in your own environment. In most cases, building the package should be as simple as extracting the distribution files to a empty directory, and then going to this directory and typing make. If you encounter problems with the Makefile, then make sure that it contains Unix line breaks. The line breaks are sometimes altered when the distribution is copied between PCs and Unix systems, and Make doesn't seem to like Makefiles that contain DOS CR-LF line breaks. Using the 'e00conv' Conversion Program 'e00conv' is a command-line executable that takes a E00 file as input (compressed or not) and copies it to a new file with the requested compression level (NONE, PARTIAL or FULL). e00conv [NONE|PARTIAL|FULL] o input_file is the name of the E00 file to read from. o output_file is the name of the file to create. If the file already exists then it is overwritten. o The last argument is optional and specifies the compression level to use when creating the output file (one of NONE, PARTIAL or FULL). The default is NONE (uncompressed). How to use the library in your programs -------------------------------------- Note: If you are not planning to use the library in your programs, then you can stop reading here... the rest of this document won't be of any use to you! -------------------------------------- To use the library in your programs, include the file "e00compr.h", and link with the "e00compr.a" library produced by the Unix Makefile. If you are working in a Windows development environment (i.e. with projects, no Makefiles!) then add all the C files from the distribution to your project, except "e00conv.c". Library functions to Read compressed E00 files All the read functions are defined inside "e00read.c". Information about the file currently being read is stored inside an internal structure. You do not need to understand the contents of this structure to use the library. All you need is to declare a E00ReadPtr variable which will serve as a handle on the input file for all the other functions. You use the following functions to read a E00 file: E00ReadPtr E00ReadOpen(const char *pszFname); void E00ReadClose(E00ReadPtr hInfo); const char *E00ReadNextLine(E00ReadPtr hInfo); void E00ReadRewind(E00ReadPtr hInfo); Each function is described after the example below. Example: This short example uses the library to read a E00 compressed file ("test.e00") and prints the uncompressed result to stdout. /********************************************************************** * ex_read.c * * This example program illustrates the use of the E00ReadOpen() * and associated compressed E00 read functions. **********************************************************************/ #include #include "e00compr.h" int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; const char *pszLine; /* Open input */ hReadPtr = E00ReadOpen("test.e00"); if (hReadPtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if (CPLGetLastErrorNo() == 0) printf("%s\n", pszLine); else { /* An error happened while reading the last line... */ break; } } /* Close input file */ E00ReadClose(hReadPtr); } else { /* ERROR ... failed to open input file */ } return 0; } E00ReadPtr data type A variable of type E00ReadPtr serves as a handle on the current input file. The handle is allocated by E00ReadOpen(), and you must call E00ReadClose() to properly release the memory associated with it. E00ReadOpen() E00ReadPtr E00ReadOpen(const char *pszFname); Opens a E00 input file and returns a E00ReadPtr handle. The input file can be in compressed or uncompressed format. E00ReadClose() will eventually have to be called to release the returned handle. Returns NULL if the file could not be opened or if it does not appear to be a valid E00 file. E00ReadCallbackOpen() E00ReadPtr E00ReadCallbackOpen(void *pRefData, const char * (*pfnReadNextLine)(void *), void (*pfnReadRewind)(void *)); This is an alternative to E00ReadOpen() for cases where you have to do all the file management yourself. You open/close the file yourself and provide 2 callback functions: to read from the file and rewind the file pointer. pRefData is your own handle on the physical file and can be whatever you want... it is not used by the library, it will be passed directly to your 2 callback functions when they are called. The callback functions must have the following C prototype: const char *myReadNextLine(void *pRefData); void myReadRewind(void *pRefData); myReadNextLine() should return a reference to its own internal buffer, or NULL if an error happens or when EOF is reached. E00ReadCallbackOpen() returns a E00ReadPtr handle or NULL if the file does not appear to be a valid E00 file. For an example of the use of this method, see the file ex_readcb.c included in the library distribution. E00ReadClose() void E00ReadClose(E00ReadPtr hInfo); Closes the physical file and releases any memory associated with a E00ReadPtr handle. E00ReadNextLine() const char *E00ReadNextLine(E00ReadPtr hInfo); Returns the next line of input from the E00 file in uncompressed form or NULL if we reached EOF or if an error happened. The returned line is a null-terminated string, and it does not include a newline character. Call CPLGetLastErrorNo() after calling E00ReadNextLine() to make sure that the whole line was read succesfully. Note that E00ReadNextLine() returns a reference to an internal buffer whose contents will be valid only until the next call to this function. The caller should not attempt to free() the returned pointer. E00ReadRewind() void E00ReadRewind(E00ReadPtr hInfo); Rewinds the E00ReadPtr just like the stdio rewind() function would do. Useful when you have to do multiple read passes on the same input file. Library functions to Write compressed E00 files The write functions are defined inside "e00write.c". The information about the file currently being written is stored inside an internal structure. As for the read library, you do not need to understand the contents of this structure to use the library. Your program has to declare a E00WritePtr variable which will serve as a handle on the output file for all the other functions. You use the following functions to write a E00 file: E00WritePtr E00WriteOpen(const char *pszFname, int nComprLevel); void E00WriteClose(E00WritePtr hInfo); int E00WriteNextLine(E00WritePtr hInfo, const char *pszLine); Each function is described after the example below. Example: This example is a simpler version of the "e00conv.c" program that is included with this distribution. It uses the read library to read a E00 file ("test1.e00") and uses the write library to copy its contents one line at a time to a new E00 file ("test2.e00") with FULL compression: /********************************************************************** * ex_write.c * * This example program illustrates the use of the E00WriteOpen() * and associated compressed E00 write functions. **********************************************************************/ #include #include "e00compr.h" int main(int argc, char *argv[]) { E00ReadPtr hReadPtr; E00WritePtr hWritePtr; const char *pszLine; int nStatus = 0; /* Open input file */ hReadPtr = E00ReadOpen("test1.e00"); if (hReadPtr) { /* Open output file */ hWritePtr = E00WriteOpen("test2.e00", E00_COMPR_FULL); if (hWritePtr) { /* Read lines from input until we reach EOF */ while((pszLine = E00ReadNextLine(hReadPtr)) != NULL) { if ((nStatus = CPLGetLastErrorNo()) == 0) nStatus = E00WriteNextLine(hWritePtr, pszLine); if (nStatus != 0) { /* An error happened while converting the last * line... abort*/ break; } } /* Close output file. */ E00WriteClose(hWritePtr); } else { /* ERROR ... failed to open output file */ nStatus = CPLGetLastErrorNo(); } /* Close input file. */ E00ReadClose(hReadPtr); } else { /* ERROR ... failed to open input file */ nStatus = CPLGetLastErrorNo(); } return nStatus; } E00WritePtr data type A variable of type E00WritePtr serves as a handle on the current input file. The handle is allocated by E00WriteOpen(), and you must call E00WriteClose() to properly release the memory associated with it. E00WriteOpen() E00WritePtr E00WriteOpen(const char *pszFname, int nComprLevel); Creates a new E00 file for output with the specified compression level, and returns a E00WritePtr handle for it. If the file already exists, then it is overwritten. nComprLevel is one of Arc/Info's 3 levels of compression: o E00_COMPR_NONE - creates an uncompressed file. o E00_COMPR_PARTIAL - creates a file with PARTIAL compression. o E00_COMPR_FULL - creates a file with FULL compression. Returns NULL if the file could not be opened. E00WriteCallbackOpen() E00WritePtr E00WriteCallbackOpen(void *pRefData, int (*pfnWriteNextLine)(void *, const char *), int nComprLevel); This is an alternative to E00WriteOpen() for cases where you have to do all the file management yourself. You open/close the file yourself and provide a callback function to write one line at a time to the file. pRefData is your own handle on the physical file and can be whatever you want... it is not used by the library, it will be passed directly to your callback function when it is called. The callback function must have the following C prototype: int myWriteNextLine(void *pRefData, const char *pszLine); myWriteNextLine() should return a positive value on success (the number of chars written, like printf() does) or -1 if an error happened. The value passed by the library in pszLine is not terminated by a '\n' character... it is assumed that your myWriteNextLine() implementation will take care of terminating the line with a '\n' if necessary. nComprLevel is one of Arc/Info's 3 levels of compression: o E00_COMPR_NONE - creates an uncompressed file. o E00_COMPR_PARTIAL - creates a file with PARTIAL compression. o E00_COMPR_FULL - creates a file with FULL compression. E00WriteCallbackOpen() returns a new E00ReadWritePtr handle and E00WriteClose() will eventually have to be called to release the resources used by the new handle. For an example of the use of this method, see the file ex_writecb.c included in the library distribution. E00WriteClose() void E00WriteClose(E00WritePtr hInfo); Closes the physical file and release any memory associated with a E00WritePtr handle. E00WriteNextLine() int E00WriteNextLine(E00WritePtr hInfo, const char *pszLine); Takes the next line of what should be headed to a uncompressed E00 file, converts it to the requested compression level, and writes the (compressed) result to the output file. pszLine should be a null-terminated string with a maximum of 80 characters (E00 lines cannot be longer than 80 characters). Do NOT include a '\n' at the end of the line, it will be added automatically by the function if it is needed. Returns 0 if the line was processed succesfully, or an error number (see error codes below) if an error happened. Note that this function does not do any syntax check on the input you provide. It assumes that what you pass to it is a valid stream of E00 lines as they would appear in an uncompressed E00 file. Trapping errors reported by the library When errors happen, the library's default behavior is to report an error message on stderr, and to fail nicely, usually by simulating a EOF situation. Errors are reported through the function CPLError() defined in "cpl_error.c". While this is sufficient for the purposes of the 'e00conv' command-line program, you may want to trap and handle errors yourself if you use the library in a bigger application (a GUI application for instance). CPLSetErrorHandler() void CPLSetErrorHandler(void (*pfnErrorHandler)(CPLErr, int, const char *)); You can use CPLSetErrorHandler() to override the default error handler function. Your new error handler should be a C function with the following prototype: void MyErrorHandler(CPLErr eErrClass, int err_no, const char *msg); And you register it with the following call at the beginning of your program: CPLSetErrorHandler( MyErrorHandler ); CPLError() void CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...); The library reports errors through this function. It's default behavior is to display the error messages to stderr, but it can be overridden using CPLSetErrorHandler(). You can call CPLGetLastErrorNo() or CPLGetLastErrorMsg() to get the last error number and string. eErrClass defines the severity of the error: typedef enum { CE_None = 0, CE_Log = 1, CE_Warning = 2, CE_Failure = 3, CE_Fatal = 4 } CPLErr; Error class CE_Fatal will abort the execution of the program, it is mainly used for out of memory errors, or unrecoverable situations of that kind. All the other error classes return control to the calling function. CPLGetLastErrorNo() int CPLGetLastErrorNo(); Returns the number of the last error that was produced. Returns 0 if the last library function that was called completed without any error. See the list of possible error numbers below. Note: This function works even if you redefined your own error handler using CPLSetErrorHandler() . CPLGetLastErrorMsg() const char *CPLGetLastErrorMsg(); Returns a reference to a static buffer containing the last error message that was produced. The caller should not attempt to free this buffer. Returns an empty string ("") if the last library function that was called completed without any error. Note: This function works even if you redefined your own error handler using CPLSetErrorHandler() . Errors generated by the library and their meaning: The values for the error codes returned by the library are defined in the file cpl_error.h. #define CPLE_OutOfMemory 2 #define CPLE_FileIO 3 #define CPLE_OpenFailed 4 #define CPLE_IllegalArg 5 #define CPLE_NotSupported 6 #define CPLE_AssertionFailed 7 The following errors codes can be returned: Error Code Description 0 Success, no error. CPLE_OutOfMemory Memory allocation failed. This is a fatal error, it will abort the program execution. There is currently no proper way to recover from it. CPLE_FileIO Unexpected error reading or writing to a file. This can also happen if an input file is corrupt. CPLE_OpenFailed Failed to open the input ou output file. Check for permissions, disk space, etc. CPLE_IllegalArg Illegal argument passed to one of the CPLE_AssertionFailed library's functions. This is a kind of internal error that should not happen unless the lib is modified or is not used as it is expected. CPLE_NotSupported One of the functions encountered an unsupported/unexpected case in one of the files. This error can also be a sign that the file is corrupt. ------------------------------------------------------------------------ Last Update: $Date: 2009-02-24 20:03:50 $ Daniel Morissette, dmorissette@mapgears.com e00compr-1.0.1/e00read.c0000644000175000017500000005400211151051746016124 0ustar aboudreaultaboudreault/********************************************************************** * $Id: e00read.c,v 1.10 2009-02-24 20:03:50 aboudreault Exp $ * * Name: e00read.c * Project: Compressed E00 Read/Write library * Language: ANSI C * Purpose: Functions to read Compressed E00 files and return a stream * of uncompressed lines. * Author: Daniel Morissette, dmorissette@mapgears.com * * $Log: e00read.c,v $ * Revision 1.10 2009-02-24 20:03:50 aboudreault * Added a short manual pages (#1875) * Updated documentation and code examples (#247) * * Revision 1.9 2005-09-17 14:22:05 daniel * Switch to MIT license, update refs to website and email address, and * prepare for 1.0.0 release. * * Revision 1.8 1999/02/25 18:45:56 daniel * Now use CPL for Error handling, Memory allocation, and File access * * Revision 1.7 1999/01/08 17:39:08 daniel * Added E00ReadCallbackOpen() * * Revision 1.6 1998/11/13 16:34:08 daniel * Fixed '\r' problem when reading E00 files from a PC under Unix * * Revision 1.5 1998/11/13 15:48:08 daniel * Simplified the decoding of the compression codes for numbers * (use a logical rule instead of going case by case) * * Revision 1.4 1998/11/02 18:34:29 daniel * Added E00ErrorReset() calls. Replace "EXP 1" by "EXP 0" on read. * * Revision 1.1 1998/10/29 13:26:00 daniel * Initial revision * ********************************************************************** * Copyright (c) 1998-2005, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * **********************************************************************/ #include #include #include #include #include "e00compr.h" static void _ReadNextSourceLine(E00ReadPtr psInfo); static const char *_UncompressNextLine(E00ReadPtr psInfo); /********************************************************************** * _E00ReadTestOpen() * * Given a pre-initialized E00ReadPtr, this function will make sure * that the file is really a E00 file, and also establish if it is * compressed or not... setting the structure members by the same way. * * Returns NULL (and destroys the E00ReadPtr) if the file does not * appear to be a valid E00 file. **********************************************************************/ static E00ReadPtr _E00ReadTestOpen(E00ReadPtr psInfo) { /* Check that the file is in E00 format. */ _ReadNextSourceLine(psInfo); if (!psInfo->bEOF && strncmp(psInfo->szInBuf, "EXP ", 4) == 0) { /* We should be in presence of a valid E00 file... * Is the file compressed or not? * * Note: we cannot really rely on the number that follows the EXP to * establish if the file is compressed since we sometimes encounter * uncompressed files that start with a "EXP 1" line!!! * * The best test is to read the first non-empty line: if the file is * compressed, the first line of data should be 79 or 80 characters * long and contain several '~' characters. */ do { _ReadNextSourceLine(psInfo); }while(!psInfo->bEOF && (psInfo->szInBuf[0] == '\0' || isspace(psInfo->szInBuf[0])) ); if (!psInfo->bEOF && (strlen(psInfo->szInBuf)==79 || strlen(psInfo->szInBuf)==80) && strchr(psInfo->szInBuf, '~') != NULL ) psInfo->bIsCompressed = 1; /* Move the Read ptr ready to read at the beginning of the file */ E00ReadRewind(psInfo); } else { CPLFree(psInfo); psInfo = NULL; } return psInfo; } /********************************************************************** * E00ReadOpen() * * Try to open a E00 file given its filename and return a E00ReadPtr handle. * * Returns NULL if the file could not be opened or if it does not * appear to be a valid E00 file. **********************************************************************/ E00ReadPtr E00ReadOpen(const char *pszFname) { E00ReadPtr psInfo = NULL; FILE *fp; CPLErrorReset(); /* Open the file */ fp = VSIFOpen(pszFname, "rt"); if (fp == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open %s: %s", pszFname, strerror(errno)); return NULL; } /* File was succesfully opened, allocate and initialize a * E00ReadPtr handle and check that the file is valid. */ psInfo = (E00ReadPtr)CPLCalloc(1, sizeof(struct _E00ReadInfo)); psInfo->fp = fp; psInfo = _E00ReadTestOpen(psInfo); if (psInfo == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "%s is not a valid E00 file.", pszFname); } return psInfo; } /********************************************************************** * E00ReadCallbackOpen() * * This is an alternative to E00ReadOpen() for cases where you want to * do all the file management yourself. You open/close the file yourself * and provide 2 callback functions: to read from the file and rewind the * file pointer. pRefData is your handle on the physical file and can * be whatever you want... it is not used by the library, it will be * passed directly to your 2 callback functions when they are called. * * The callback functions must have the following C prototype: * * const char *myReadNextLine(void *pRefData); * void myReadRewind(void *pRefData); * * myReadNextLine() should return a reference to its own internal * buffer, or NULL if an error happens or EOF is reached. * * E00ReadCallbackOpen() returns a E00ReadPtr handle or NULL if the file * does not appear to be a valid E00 file. **********************************************************************/ E00ReadPtr E00ReadCallbackOpen(void *pRefData, const char * (*pfnReadNextLine)(void *), void (*pfnReadRewind)(void *)) { E00ReadPtr psInfo = NULL; CPLErrorReset(); /* Make sure we received valid function pointers */ if (pfnReadNextLine == NULL || pfnReadRewind == NULL) { CPLError(CE_Failure, CPLE_IllegalArg, "Invalid function pointers!"); return NULL; } /* Allocate and initialize a * E00ReadPtr handle and check that the file is valid. */ psInfo = (E00ReadPtr)CPLCalloc(1, sizeof(struct _E00ReadInfo)); psInfo->pRefData = pRefData; psInfo->pfnReadNextLine = pfnReadNextLine; psInfo->pfnReadRewind = pfnReadRewind; psInfo = _E00ReadTestOpen(psInfo); if (psInfo == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "This is not a valid E00 file."); } return psInfo; } /********************************************************************** * E00ReadClose() * * Close input file and release any memory used by the E00ReadPtr. **********************************************************************/ void E00ReadClose(E00ReadPtr psInfo) { CPLErrorReset(); if (psInfo) { if (psInfo->fp) VSIFClose(psInfo->fp); CPLFree(psInfo); } } /********************************************************************** * E00ReadRewind() * * Rewind the E00ReadPtr. Allows to start another read pass on the * input file. **********************************************************************/ void E00ReadRewind(E00ReadPtr psInfo) { CPLErrorReset(); psInfo->szInBuf[0] = psInfo->szOutBuf[0] = '\0'; psInfo->iInBufPtr = 0; psInfo->nInputLineNo = 0; if (psInfo->pfnReadRewind == NULL) VSIRewind(psInfo->fp); else psInfo->pfnReadRewind(psInfo->pRefData); psInfo->bEOF = 0; } /********************************************************************** * E00ReadNextLine() * * Return the next line of input from the E00 file or NULL if we reached EOF. * * Returns a reference to an internal buffer whose contents will be valid * only until the next call to this function. **********************************************************************/ const char *E00ReadNextLine(E00ReadPtr psInfo) { const char *pszLine = NULL; char *pszPtr; CPLErrorReset(); if (psInfo && !psInfo->bEOF) { if (!psInfo->bIsCompressed) { /* Uncompressed file... return line directly. */ _ReadNextSourceLine(psInfo); pszLine = psInfo->szInBuf; } else if (psInfo->bIsCompressed && psInfo->nInputLineNo == 0) { /* Header line in a compressed file... return line * after replacing "EXP 1" with "EXP 0". E00ReadOpen() * has already verified that this line starts with "EXP " */ _ReadNextSourceLine(psInfo); if ( (pszPtr = strstr(psInfo->szInBuf, " 1")) != NULL) pszPtr[1] = '0'; pszLine = psInfo->szInBuf; } else { if (psInfo->nInputLineNo == 1) { /* We just read the header line... reload the input buffer */ _ReadNextSourceLine(psInfo); } /* Uncompress the next line of input and return it */ pszLine = _UncompressNextLine(psInfo); } /* If we just reached EOF then make sure we don't add an extra * empty line at the end of the uncompressed oputput. */ if (psInfo->bEOF && strlen(pszLine) == 0) pszLine = NULL; } return pszLine; } /********************************************************************** * _ReadNextSourceLine() * * Loads the next line from the source file in psInfo. * * psInfo->bEOF should be checked after this call. **********************************************************************/ static void _ReadNextSourceLine(E00ReadPtr psInfo) { if (!psInfo->bEOF) { psInfo->iInBufPtr = 0; psInfo->szInBuf[0] = '\0'; /* Read either using fgets() or psInfo->pfnReadNextLine() * depending on the way the file was opened... */ if (psInfo->pfnReadNextLine == NULL) { if (VSIFGets(psInfo->szInBuf,E00_READ_BUF_SIZE,psInfo->fp) == NULL) { /* We reached EOF */ psInfo->bEOF = 1; } } else { const char *pszLine; pszLine = psInfo->pfnReadNextLine(psInfo->pRefData); if (pszLine) { strncpy(psInfo->szInBuf, pszLine, E00_READ_BUF_SIZE); } else { /* We reached EOF */ psInfo->bEOF = 1; } } if (!psInfo->bEOF) { /* A new line was succesfully read. Remove trailing '\n' if any. * (Note: For Unix systems, we also have to check for '\r') */ int nLen; nLen = strlen(psInfo->szInBuf); while(nLen > 0 && (psInfo->szInBuf[nLen-1] == '\n' || psInfo->szInBuf[nLen-1] == '\r' ) ) { nLen--; psInfo->szInBuf[nLen] = '\0'; } psInfo->nInputLineNo++; } } } /********************************************************************** * _GetNextSourceChar() * * Returns the next char from the source file input buffer... and * reload the input buffer when necessary... this function makes the * whole input file appear as one huge null-terminated string with * no line delimiters. * * Will return '\0' when EOF is reached. **********************************************************************/ static char _GetNextSourceChar(E00ReadPtr psInfo) { char c = '\0'; if (!psInfo->bEOF) { if (psInfo->szInBuf[psInfo->iInBufPtr] == '\0') { _ReadNextSourceLine(psInfo); c = _GetNextSourceChar(psInfo); } else { c = psInfo->szInBuf[psInfo->iInBufPtr++]; } } return c; } /********************************************************************** * _UngetSourceChar() * * Reverse the effect of the previous call to _GetNextSourceChar() by * moving the input buffer pointer back 1 character. * * This function can be called only once per call to _GetNextSourceChar() * (i.e. you cannot unget more than one character) otherwise the pointer * could move before the beginning of the input buffer. **********************************************************************/ static void _UngetSourceChar(E00ReadPtr psInfo) { if (psInfo->iInBufPtr > 0) psInfo->iInBufPtr--; else { /* This error can happen only if _UngetSourceChar() is called * twice in a row (which should never happen!). */ CPLError(CE_Failure, CPLE_AssertionFailed, "UNEXPECTED INTERNAL ERROR: _UngetSourceChar() " "failed while reading line %d.", psInfo->nInputLineNo); } } /********************************************************************** * _UncompressNextLine() * * Uncompress one line of input and return a reference to an internal * buffer containing the uncompressed output. **********************************************************************/ static const char *_UncompressNextLine(E00ReadPtr psInfo) { char c; int bEOL = 0; /* Set to 1 when End of Line reached */ int iOutBufPtr = 0, i, n; int iDecimalPoint, bOddNumDigits, iCurDigit; char *pszExp; int bPreviousCodeWasNumeric = 0; while(!bEOL && (c=_GetNextSourceChar(psInfo)) != '\0') { if (c != '~') { /* Normal character... just copy it */ psInfo->szOutBuf[iOutBufPtr++] = c; bPreviousCodeWasNumeric = 0; } else /* c == '~' */ { /* ======================================================== * Found an encoded sequence. * =======================================================*/ c = _GetNextSourceChar(psInfo); /* -------------------------------------------------------- * Compression level 1: only spaces, '~' and '\n' are encoded * -------------------------------------------------------*/ if (c == ' ') { /* "~ " followed by number of spaces */ c = _GetNextSourceChar(psInfo); n = c - ' '; for(i=0; iszOutBuf[iOutBufPtr++] = ' '; bPreviousCodeWasNumeric = 0; } else if (c == '}') { /* "~}" == '\n' */ bEOL = 1; bPreviousCodeWasNumeric = 0; } else if (bPreviousCodeWasNumeric) { /* If the previous code was numeric, then the only valid code * sequences are the ones above: "~ " and "~}". If we end up * here, it is because the number was followed by a '~' but * this '~' was not a code, it only marked the end of a * number that was not followed by any space. * * We should simply ignore the '~' and return the character * that follows it directly. */ psInfo->szOutBuf[iOutBufPtr++] = c; bPreviousCodeWasNumeric = 0; } else if (c == '~' || c == '-') { /* "~~" and "~-" are simple escape sequences for '~' and '-' */ psInfo->szOutBuf[iOutBufPtr++] = c; } /* -------------------------------------------------------- * Compression level 2: numeric values are encoded. * * All codes for this level are in the form "~ c0 c1 c2 ... cn" * where: * * ~ marks the beginning of a new code sequence * * c0 is a single character code defining the format * of the number (decimal position, exponent, * and even or odd number of digits) * * c1 c2 ... cn each of these characters represent a pair of * digits of the encoded value with '!' == 00 * values 92..99 are encoded on 2 chars that * must be added to each other * (i.e. 92 == }!, 93 == }", ...) * * The sequence ends with a ' ' or a '~' character * -------------------------------------------------------*/ else if (c >= '!' && c <= 'z') { /* The format code defines 3 characteristics of the final number: * - Presence of a decimal point and its position * - Presence of an exponent, and its sign * - Odd or even number of digits */ n = c - '!'; iDecimalPoint = n % 15; /* 0 = no decimal point */ bOddNumDigits = n / 45; /* 0 = even num.digits, 1 = odd */ n = n / 15; if ( n % 3 == 1 ) pszExp = "E+"; else if (n % 3 == 2 ) pszExp = "E-"; else pszExp = NULL; /* Decode the c1 c2 ... cn value and apply the format. * Read characters until we encounter a ' ' or a '~' */ iCurDigit = 0; while((c=_GetNextSourceChar(psInfo)) != '\0' && c != ' ' && c != '~') { n = c - '!'; if (n == 92 && (c=_GetNextSourceChar(psInfo)) != '\0') n += c - '!'; psInfo->szOutBuf[iOutBufPtr++] = '0' + n/10; if (++iCurDigit == iDecimalPoint) psInfo->szOutBuf[iOutBufPtr++] = '.'; psInfo->szOutBuf[iOutBufPtr++] = '0' + n%10; if (++iCurDigit == iDecimalPoint) psInfo->szOutBuf[iOutBufPtr++] = '.'; } if (c == '~' || c == ' ') { bPreviousCodeWasNumeric = 1; _UngetSourceChar(psInfo); } /* If odd number of digits, then flush the last one */ if (bOddNumDigits) iOutBufPtr--; /* Insert the exponent string before the 2 last digits * (we assume the exponent string is 2 chars. long) */ if (pszExp) { for(i=0; i<2;i++) { psInfo->szOutBuf[iOutBufPtr] = psInfo->szOutBuf[iOutBufPtr-2]; psInfo->szOutBuf[iOutBufPtr-2] = pszExp[i]; iOutBufPtr++; } } } else { /* Unsupported code sequence... this is a possibility * given the fact that this library was written by * reverse-engineering the format! * * Send an error to the user and abort. * * If this error ever happens, and you are convinced that * the input file is not corrupted, then please report it to * me at dmorissette@mapgears.com, quoting the section of the input * file that produced it, and I'll do my best to add support * for this code sequence. */ CPLError(CE_Failure, CPLE_NotSupported, "Unexpected code \"~%c\" encountered in line %d.", c, psInfo->nInputLineNo); /* Force the program to abort by simulating a EOF */ psInfo->bEOF = 1; bEOL = 1; } }/* if c == '~' */ /* E00 lines should NEVER be longer than 80 chars. if we passed * that limit, then the input file is likely corrupt. */ if (iOutBufPtr > 80) { CPLError(CE_Failure, CPLE_FileIO, "Uncompressed line longer than 80 chars. " "Input file possibly corrupt around line %d.", psInfo->nInputLineNo); /* Force the program to abort by simulating a EOF */ psInfo->bEOF = 1; bEOL = 1; } }/* while !EOL */ psInfo->szOutBuf[iOutBufPtr++] = '\0'; return psInfo->szOutBuf; } e00compr-1.0.1/cpl_vsi.h0000755000175000017500000001107111151051746016352 0ustar aboudreaultaboudreault/****************************************************************************** * Copyright (c) 1998, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * cpl_vsi.h * * Include file defining the Virtual System Interface (VSI) functions. This * should normally be included by all translators using VSI functions for * accessing system services. It is also used by the GDAL core, and can be * used by higher level applications which adhere to VSI use. * * Most VSI functions are direct analogs of Posix C library functions. * VSI exists to allow ``hooking'' these functions to provide application * specific checking, io redirection and so on. * * $Log: cpl_vsi.h,v $ * Revision 1.4 1999/02/25 04:48:11 danmo * Added VSIStat() macros specific to _WIN32 (for MSVC++) * * Revision 1.3 1999/01/28 18:31:25 warmerda * Test on _WIN32 rather than WIN32. It seems to be more reliably defined. * * Revision 1.2 1998/12/04 21:42:57 danmo * Added #ifndef WIN32 arounf #include * * Revision 1.1 1998/12/03 18:26:02 warmerda * New * */ #ifndef CPL_VSI_H_INCLUDED #define CPL_VSI_H_INCLUDED #include "cpl_port.h" /* -------------------------------------------------------------------- */ /* We need access to ``struct stat''. */ /* -------------------------------------------------------------------- */ #ifndef _WIN32 # include #endif #include CPL_C_START /* ==================================================================== */ /* stdio file access functions. */ /* ==================================================================== */ FILE CPL_DLL * VSIFOpen( const char *, const char * ); int CPL_DLL VSIFClose( FILE * ); int CPL_DLL VSIFSeek( FILE *, long, int ); long CPL_DLL VSIFTell( FILE * ); void CPL_DLL VSIRewind( FILE * ); size_t CPL_DLL VSIFRead( void *, size_t, size_t, FILE * ); size_t CPL_DLL VSIFWrite( void *, size_t, size_t, FILE * ); char CPL_DLL *VSIFGets( char *, int, FILE * ); int CPL_DLL VSIFPuts( const char *, FILE * ); int CPL_DLL VSIFPrintf( FILE *, const char *, ... ); int CPL_DLL VSIFGetc( FILE * ); int CPL_DLL VSIFPutc( int, FILE * ); int CPL_DLL VSIUngetc( int, FILE * ); int CPL_DLL VSIFEof( FILE * ); /* ==================================================================== */ /* VSIStat() related. */ /* ==================================================================== */ typedef struct stat VSIStatBuf; int CPL_DLL VSIStat( const char *, VSIStatBuf * ); #ifdef _WIN32 # define VSI_ISLNK(x) ( 0 ) /* N/A on Windows */ # define VSI_ISREG(x) ((x) & S_IFREG) # define VSI_ISDIR(x) ((x) & S_IFDIR) # define VSI_ISCHR(x) ((x) & S_IFCHR) # define VSI_ISBLK(x) ( 0 ) /* N/A on Windows */ #else # define VSI_ISLNK(x) S_ISLNK(x) # define VSI_ISREG(x) S_ISREG(x) # define VSI_ISDIR(x) S_ISDIR(x) # define VSI_ISCHR(x) S_ISCHR(x) # define VSI_ISBLK(x) S_ISBLK(x) #endif /* ==================================================================== */ /* Memory allocation */ /* ==================================================================== */ void CPL_DLL *VSICalloc( size_t, size_t ); void CPL_DLL *VSIMalloc( size_t ); void CPL_DLL VSIFree( void * ); void CPL_DLL *VSIRealloc( void *, size_t ); char CPL_DLL *VSIStrdup( const char * ); CPL_C_END #endif /* ndef CPL_VSI_H_INCLUDED */ e00compr-1.0.1/Makefile0000755000175000017500000000221111151051746016176 0ustar aboudreaultaboudreault# Makefile for the Compressed E00 Read/Write library # # $Id: Makefile,v 1.2 1999-02-25 18:57:09 daniel Exp $ # # $Log: Makefile,v $ # Revision 1.2 1999-02-25 18:57:09 daniel # Now use CPL for Error handling, Memory allocation, and File access # # Revision 1.1 1999/01/08 17:41:17 daniel # Initial revision # # CC= gcc CFLAGS= -Wall LFLAGS= AR= ar LIB_OBJS= e00read.o e00write.o cpl_error.o cpl_conv.o cpl_vsisimple.o LIB= e00compr.a default: all all: e00conv $(LIB_OBJS): e00compr.h e00conv: e00conv.o $(LIB) $(CC) $(LFLAGS) -o e00conv e00conv.o $(LIB) ex_read: ex_read.o $(LIB) $(CC) $(LFLAGS) -o ex_read ex_read.o $(LIB) ex_readcb: ex_readcb.o $(LIB) $(CC) $(LFLAGS) -o ex_readcb ex_readcb.o $(LIB) ex_write: ex_write.o $(LIB) $(CC) $(LFLAGS) -o ex_write ex_write.o $(LIB) ex_writecb: ex_writecb.o $(LIB) $(CC) $(LFLAGS) -o ex_writecb ex_writecb.o $(LIB) .c.o: $(CC) -c $(CFLAGS) $< $(LIB): $(LIB_OBJS) rm -f $(LIB) $(AR) rc $(LIB) $(LIB_OBJS) clean: clean-examples rm -f e00conv e00conv.o $(LIB) $(LIB_OBJS) clean-examples: rm -f ex_read ex_read.o ex_readcb ex_readcb.o rm -f ex_write ex_write.o ex_writecb ex_writecb.o e00compr-1.0.1/cpl_error.h0000644000175000017500000000702511151051746016703 0ustar aboudreaultaboudreault/********************************************************************** * $Id: cpl_error.h,v 1.6 1999/02/17 05:40:47 danmo Exp $ * * Name: cpl_error.h * Project: CPL - Common Portability Library * Purpose: CPL Error handling * Author: Daniel Morissette, dmorissette@mapgears.com * ********************************************************************** * Copyright (c) 1998, Daniel Morissette * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ********************************************************************** * * $Log: cpl_error.h,v $ * Revision 1.6 1999/02/17 05:40:47 danmo * Fixed CPLAssert() macro to work with EGCS. * * Revision 1.5 1999/01/11 15:34:29 warmerda * added reserved range comment * * Revision 1.4 1998/12/15 19:02:27 warmerda * Avoid use of errno as a variable * * Revision 1.3 1998/12/06 22:20:42 warmerda * Added error code. * * Revision 1.2 1998/12/06 02:52:52 warmerda * Implement assert support * * Revision 1.1 1998/12/03 18:26:02 warmerda * New * **********************************************************************/ #ifndef _CPL_ERROR_H_INCLUDED_ #define _CPL_ERROR_H_INCLUDED_ #include "cpl_port.h" /*===================================================================== Error handling functions (cpl_error.c) =====================================================================*/ CPL_C_START typedef enum { CE_None = 0, CE_Log = 1, CE_Warning = 2, CE_Failure = 3, CE_Fatal = 4 } CPLErr; void CPL_DLL CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...); void CPL_DLL CPLErrorReset(); int CPL_DLL CPLGetLastErrorNo(); const char CPL_DLL * CPLGetLastErrorMsg(); void CPL_DLL CPLSetErrorHandler(void(*pfnErrorHandler)(CPLErr,int, const char *)); void CPL_DLL _CPLAssert( const char *, const char *, int ); #ifdef DEBUG # define CPLAssert(expr) ((expr) ? (void)(0) : _CPLAssert(#expr,__FILE__,__LINE__)) #else # define CPLAssert(expr) #endif CPL_C_END /* ==================================================================== */ /* Well known error codes. */ /* ==================================================================== */ #define CPLE_AppDefined 1 #define CPLE_OutOfMemory 2 #define CPLE_FileIO 3 #define CPLE_OpenFailed 4 #define CPLE_IllegalArg 5 #define CPLE_NotSupported 6 #define CPLE_AssertionFailed 7 #define CPLE_NoWriteAccess 8 /* 100 - 299 reserved for GDAL */ #endif /* _CPL_ERROR_H_INCLUDED_ */