PageRenderTime 23ms CodeModel.GetById 10ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/src/lib/io/basic/binary_file_write.e

http://github.com/tybor/Liberty
Specman e | 298 lines | 220 code | 32 blank | 46 comment | 23 complexity | 3ea3bec395642eb3bbcdc544c35a5b75 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4class BINARY_FILE_WRITE
  5   -- This class allow to write a file on the disk as a binary file
  6   -- (ie. file containing bytes). If you need to write text in a file,
  7   -- then consider using TEXT_FILE_WRITE.
  8
  9inherit
 10   DISPOSABLE
 11   BINARY_OUTPUT_STREAM
 12      redefine
 13         dispose
 14      end
 15   TERMINAL_OUTPUT_STREAM
 16      redefine
 17         dispose
 18      end
 19   FILE_STREAM
 20      redefine
 21         dispose
 22      end
 23
 24create {ANY}
 25   make, connect_to, connect_for_appending_to
 26
 27feature {ANY}
 28   connect_to (new_path: ABSTRACT_STRING)
 29         -- Truncate file to zero length or create binary file for writing.
 30         -- The stream is positioned at the beginning of the file.
 31      local
 32         p: POINTER
 33      do
 34         p := new_path.to_external
 35         output_stream := binary_file_write_open(p)
 36         if output_stream.is_not_null then
 37            set_path(new_path)
 38            if capacity = 0 then
 39               buffer := buffer.calloc(4096)
 40               capacity := 4096
 41            end
 42            if the_terminal_settings /= Void then
 43               the_terminal_settings.make(output_stream, Current)
 44            end
 45         end
 46      end
 47
 48   connect_for_appending_to (new_path: STRING)
 49         -- Truncate file to zero length or create binary file for writing.
 50         -- The stream is positioned at the beginning of the file.
 51      require
 52         not is_connected
 53         not new_path.is_empty
 54      local
 55         p: POINTER
 56      do
 57         p := new_path.to_external
 58         output_stream := binary_file_write_append(p)
 59         if output_stream.is_not_null then
 60            path := new_path
 61            if capacity = 0 then
 62               buffer := buffer.calloc(4096)
 63               capacity := 4096
 64            end
 65            if the_terminal_settings /= Void then
 66               the_terminal_settings.make(output_stream, Current)
 67            end
 68         end
 69      end
 70
 71   disconnect
 72      do
 73         if buffer_position > 0 then
 74            write_buffer
 75         end
 76         fclose(output_stream)
 77         path := Void
 78      end
 79
 80   put_byte (byte: INTEGER)
 81      do
 82         if buffer_position >= 4096 then
 83            write_buffer
 84         end
 85         buffer.put(byte.to_character, buffer_position)
 86         buffer_position := buffer_position + 1
 87      end
 88
 89   put_integer_16_native_endian (i: INTEGER_16)
 90         -- Write in the same order as the machine running this code.
 91         -- The result is machine dependant.
 92      do
 93         if buffer_position >= 4095 or else buffer_position.is_odd then
 94            write_buffer
 95         end
 96         put_16_ne(buffer, i, buffer_position)
 97         buffer_position := buffer_position + 2
 98      end
 99
100   put_integer_16_big_endian (i: INTEGER_16)
101         -- Write `i' in big endian mode.
102         -- The result is machine independent.
103      do
104         if buffer_position >= 4095 or else buffer_position.is_odd then
105            write_buffer
106         end
107         put_16_be(buffer, i, buffer_position)
108         buffer_position := buffer_position + 2
109      end
110
111   put_integer_16_little_endian (i: INTEGER_16)
112         -- Write `i' in little endian mode.
113         -- The result is machine independent.
114      do
115         if buffer_position >= 4095 or else buffer_position.is_odd then
116            write_buffer
117         end
118         put_16_le(buffer, i, buffer_position)
119         buffer_position := buffer_position + 2
120      end
121
122   put_integer_32_native_endian (i: INTEGER_32)
123         -- Write in the same order as the machine running this code.
124         -- The result is machine dependant.
125      do
126         if buffer_position >= 4095 or else buffer_position.is_odd then
127            write_buffer
128         end
129         put_32_ne(buffer, i, buffer_position)
130         buffer_position := buffer_position + 4
131      end
132
133   put_integer_32_big_endian (i: INTEGER_32)
134         -- Write `i' in big endian mode.
135         -- The result is machine independent.
136      do
137         if buffer_position >= 4095 or else buffer_position.is_odd then
138            write_buffer
139         end
140         put_32_be(buffer, i, buffer_position)
141         buffer_position := buffer_position + 4
142      end
143
144   put_integer_32_little_endian (i: INTEGER_32)
145         -- Write `i' in little endian mode.
146         -- The result is machine independent.
147      do
148         if buffer_position >= 4095 or else buffer_position.is_odd then
149            write_buffer
150         end
151         put_32_le(buffer, i, buffer_position)
152         buffer_position := buffer_position + 4
153      end
154
155   terminal_settings: TERMINAL_SETTINGS
156      do
157         if the_terminal_settings = Void then
158            create the_terminal_settings.make(filtered_stream_pointer, Current)
159         end
160         Result := the_terminal_settings
161      ensure
162         valid: Result /= Void
163         associated: Result.associated_stream = Current
164      end
165
166feature {FILTER_OUTPUT_STREAM}
167   filtered_put_character (c: CHARACTER)
168      do
169         put_byte(c.code)
170      end
171
172   filtered_flush
173         -- forces a write of unwritten character (write my have been
174         -- delayed, flush writes buffered characters)
175      do
176         if buffer_position > 0 then
177            write_buffer
178         end
179         io_flush(output_stream)
180      end
181
182feature {FILTER}
183   filtered_descriptor: INTEGER 0
184   filtered_has_descriptor: BOOLEAN False
185
186   filtered_stream_pointer: POINTER
187      do
188         Result := output_stream
189      end
190
191   filtered_has_stream_pointer: BOOLEAN True
192
193feature {}
194   buffer: NATIVE_ARRAY[CHARACTER]
195   buffer_position: INTEGER
196   capacity: INTEGER
197   output_stream: POINTER
198   the_terminal_settings: TERMINAL_SETTINGS
199
200   make
201         -- The new created object is not connected. (See also `connect_to' and
202         -- `connect_for_appending_to'.)
203      do
204         buffer := buffer.calloc(4096)
205         capacity := 4096
206      ensure
207         not is_connected
208      end
209
210   dispose
211      require
212         disconnect_file_after_use: not is_connected
213      do
214      end
215
216   write_buffer
217      local
218         unused_result: INTEGER
219      do
220         if buffer_position > 0 then
221            unused_result := io_fwrite(buffer, buffer_position, output_stream)
222            buffer_position := 0
223         end
224      end
225
226feature {} -- built-ins
227   put_16_ne (a_buf: NATIVE_ARRAY[CHARACTER]; i: INTEGER_16; ch_pos: INTEGER)
228      external "built_in"
229      end
230
231   put_16_le (a_buf: NATIVE_ARRAY[CHARACTER]; i: INTEGER_16; ch_pos: INTEGER)
232      external "built_in"
233      end
234
235   put_16_be (a_buf: NATIVE_ARRAY[CHARACTER]; i: INTEGER_16; ch_pos: INTEGER)
236      external "built_in"
237      end
238
239   put_32_ne (a_buf: NATIVE_ARRAY[CHARACTER]; i: INTEGER_32; ch_pos: INTEGER)
240      external "built_in"
241      end
242
243   put_32_le (a_buf: NATIVE_ARRAY[CHARACTER]; i: INTEGER_32; ch_pos: INTEGER)
244      external "built_in"
245      end
246
247   put_32_be (a_buf: NATIVE_ARRAY[CHARACTER]; an_i: INTEGER_32; ch_pos: INTEGER)
248      external "built_in"
249      end
250
251   binary_file_write_open (a_path_pointer: POINTER): POINTER
252      external "plug_in"
253      alias "{
254         location: "${sys}/plugins"
255         module_name: "io"
256         feature_name: "binary_file_write_open"
257         }"
258      end
259
260   binary_file_write_append (a_path_pointer: POINTER): POINTER
261      external "plug_in"
262      alias "{
263         location: "${sys}/plugins"
264         module_name: "io"
265         feature_name: "binary_file_write_append"
266         }"
267      end
268
269   fclose (a_stream_pointer: POINTER)
270      external "plug_in"
271      alias "{
272         location: "${sys}/plugins"
273         module_name: "io"
274         feature_name: "io_fclose"
275         }"
276      end
277
278end -- class BINARY_FILE_WRITE
279--
280-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
281--
282-- Permission is hereby granted, free of charge, to any person obtaining a copy
283-- of this software and associated documentation files (the "Software"), to deal
284-- in the Software without restriction, including without limitation the rights
285-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
286-- copies of the Software, and to permit persons to whom the Software is
287-- furnished to do so, subject to the following conditions:
288--
289-- The above copyright notice and this permission notice shall be included in
290-- all copies or substantial portions of the Software.
291--
292-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
293-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
294-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
295-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
296-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
297-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
298-- THE SOFTWARE.