1 /* fileio.c -- does standard I/O
2 
3   (c) 1998-2007 (W3C) MIT, ERCIM, Keio University
4   See tidy.h for the copyright notice.
5 
6   Default implementations of Tidy input sources
7   and output sinks based on standard C FILE*.
8 
9 */
10 
11 #include <stdio.h>
12 
13 #include "forward.h"
14 #include "fileio.h"
15 #include "tidy.h"
16 #include "sprtf.h"
17 
18 typedef struct _fp_input_source
19 {
20     FILE*        fp;
21     TidyBuffer   unget;
22 } FileSource;
23 
filesrc_getByte(void * sourceData)24 static int TIDY_CALL filesrc_getByte( void* sourceData )
25 {
26   FileSource* fin = (FileSource*) sourceData;
27   int bv;
28   if ( fin->unget.size > 0 )
29     bv = tidyBufPopByte( &fin->unget );
30   else
31     bv = fgetc( fin->fp );
32   return bv;
33 }
34 
filesrc_eof(void * sourceData)35 static Bool TIDY_CALL filesrc_eof( void* sourceData )
36 {
37   FileSource* fin = (FileSource*) sourceData;
38   Bool isEOF = ( fin->unget.size == 0 );
39   if ( isEOF )
40     isEOF = feof( fin->fp ) != 0;
41   return isEOF;
42 }
43 
filesrc_ungetByte(void * sourceData,byte bv)44 static void TIDY_CALL filesrc_ungetByte( void* sourceData, byte bv )
45 {
46   FileSource* fin = (FileSource*) sourceData;
47   tidyBufPutByte( &fin->unget, bv );
48 }
49 
50 #if SUPPORT_POSIX_MAPPED_FILES
51 #  define initFileSource initStdIOFileSource
52 #  define freeFileSource freeStdIOFileSource
53 #endif
TY_(initFileSource)54 int TY_(initFileSource)( TidyAllocator *allocator, TidyInputSource* inp, FILE* fp )
55 {
56   FileSource* fin = NULL;
57 
58   fin = (FileSource*) TidyAlloc( allocator, sizeof(FileSource) );
59   if ( !fin )
60       return -1;
61   TidyClearMemory( fin, sizeof(FileSource) );
62   fin->unget.allocator = allocator;
63   fin->fp = fp;
64 
65   inp->getByte    = filesrc_getByte;
66   inp->eof        = filesrc_eof;
67   inp->ungetByte  = filesrc_ungetByte;
68   inp->sourceData = fin;
69 
70   return 0;
71 }
72 
TY_(freeFileSource)73 void TY_(freeFileSource)( TidyInputSource* inp, Bool closeIt )
74 {
75     FileSource* fin = (FileSource*) inp->sourceData;
76     if ( closeIt && fin && fin->fp )
77       fclose( fin->fp );
78     tidyBufFree( &fin->unget );
79     TidyFree( fin->unget.allocator, fin );
80 }
81 
TY_(filesink_putByte)82 void TIDY_CALL TY_(filesink_putByte)( void* sinkData, byte bv )
83 {
84   FILE* fout = (FILE*) sinkData;
85   fputc( bv, fout );
86 #if defined(ENABLE_DEBUG_LOG)
87   if (fileno(fout) != 2)
88   {
89       if (bv != 0x0d)
90       {
91           /*\
92            * avoid duplicate newline - SPRTF will translate an 0x0d to CRLF,
93            *  and do the same with the following 0x0a
94           \*/
95           SPRTF("%c",bv);
96       }
97   }
98 #endif
99 }
100 
TY_(initFileSink)101 void TY_(initFileSink)( TidyOutputSink* outp, FILE* fp )
102 {
103   outp->putByte  = TY_(filesink_putByte);
104   outp->sinkData = fp;
105 }
106 
107 /*
108  * local variables:
109  * mode: c
110  * indent-tabs-mode: nil
111  * c-basic-offset: 4
112  * eval: (c-set-offset 'substatement-open 0)
113  * end:
114  */
115