Rune Serialize - Stabilization, Generation, major overhaul
[rune.git] / classes / stdio / fwrite.d
1 #
2 # STDIO/FWRITE.D - output
3 #
4
5 public method
6 size_t
7 File.fwrite(void *buf, size_t bytes)
8 {
9         size_t r = 0;
10
11         # If a regular file requires a flush prior to turn-around to
12         # ensure that any read-back sees the write.
13         #
14         if (this.flags & F_ISREG) {
15                 if ((this.flags & F_OUT) == 0) {
16                         this.flags |= F_OUT;
17                         this.in.base = 0;
18                         this.in.index = 0;
19                 }
20         }
21
22         /*
23          * If unbuffered just write the data directly
24          * (we are guarenteed to be flushed and it doesn't
25          * matter if we are in input mode).
26          */
27         while (this.mode == File.M_NONE) {
28                 size_t n = this.fs.write1(buf, bytes);
29                 if (n <= 0L) {
30                         if (n < 0 && this.fs.error == Sys.EINTR)
31                                 continue;
32                         return r;               # early return
33                 }
34                 buf = (char *)buf + n;
35                 r += n;
36                 bytes -= n;
37                 this.pos += (off_t)n;
38         }
39
40         /*
41          * If we need an output buffer create one
42          */
43         if (this.out.buf == NULL) {
44                 this.out.initbuf();
45         }
46
47         /*
48          * Copy to the buffer until the buffer is full
49          */
50         while (bytes != 0L) {
51                 size_t n = this.out.size - this.out.index;
52
53                 if (n == 0L) {
54                         if (this.fflush() < 0)
55                                 break;
56                         continue;
57                 }
58                 if (n > bytes)
59                         n = bytes;
60                 Sys.bcopy((char *)buf + r,
61                           &this.out.buf[this.out.index], n);
62                 r += n;
63                 bytes -= n;
64                 this.pos += (off_t)n;
65                 this.out.index += n;
66         }
67
68         /*
69          * Line mode flush
70          */
71         if (this.mode == File.M_LINE &&
72                 this.out.index != 0L &&
73                 this.out.buf[this.out.index - 1L] == '\n'
74         ) {
75                 int r2;
76
77                 if ((r2 = this.fflush()) < 0)
78                         r = (size_t)r2;
79         }
80         return(r);
81 }
82
83 public method
84 int
85 File.fputc(char c)
86 {
87         if (this.mode == File.M_NONE) {
88                 if (this.fs.write(&c, 1) == 1L) {
89                         ++this.pos;
90                         return(0);
91                 }
92                 return(-1);
93         }
94
95         /*
96          * If we need an output buffer create one
97          */
98         if (this.out.buf == NULL)
99                 this.out.initbuf();
100
101         /*
102          * Copy data to buffer
103          */
104         if (this.out.index == this.out.size) {
105                 if (this.fflush() < 0)
106                         return(-1);
107         }
108         this.out.buf[this.out.index] = c;
109         ++this.out.index;
110         ++this.pos;
111
112         /*
113          * Line mode flush
114          */
115         if (this.mode == File.M_LINE && c == '\n')
116                 return(this.fflush());
117         else
118                 return(0);
119 }
120
121 public method
122 int
123 File.fflush()
124 {
125         size_t r = 0;
126
127         if (this.out.index != 0L) {
128                 while (r != this.out.index) {
129                         size_t n;
130
131                         n = this.fs.write(&this.out.buf[0] + r,
132                                           this.out.index - r);
133                         if (n < 0L)
134                                 return((int)n);
135                         r += n;
136                 }
137                 if (r != 0L && r != this.out.index) {
138                         Sys.bcopy(&this.out.buf[r], &this.out.buf[0],
139                                   this.out.index - r);
140                 }
141                 this.out.index -= r;
142         }
143         return(0);
144 }