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