| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | with H2.Ascii; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | separate (H2.IO) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package body File is | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| PRIVATE ROUTINES
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	procedure OS_Read_File (File:   in out File_Record; | 
					
						
							|  |  |  | 	                        Buffer: in out System_Byte_Array; | 
					
						
							|  |  |  | 	                        Length: out    System_Length) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		OS.File.Read (File.File, Buffer, Length); | 
					
						
							|  |  |  | 		File.EOF := (Length <= 0); | 
					
						
							|  |  |  | 	end OS_Read_File; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	procedure Compact_Buffer (Buffer: in out File_Buffer) is | 
					
						
							|  |  |  | 		A, B, L: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		A := Buffer.Pos; | 
					
						
							|  |  |  | 		B := Buffer.Last; | 
					
						
							|  |  |  | 		L := Buffer.Pos - Buffer.Data'First + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Buffer.Pos := Buffer.Pos - L; -- should be same as Buffer.Data'First - 1
 | 
					
						
							|  |  |  | 		Buffer.Last := Buffer.Last - L; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Buffer.Data(Buffer.Pos + 1 .. Buffer.Last) := Buffer.Data(A + 1 .. B); | 
					
						
							|  |  |  | 	end Compact_Buffer; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	procedure Copy_Array (Dst:    in out System_Byte_Array; | 
					
						
							|  |  |  | 	                      Src:    in     System_Byte_Array; | 
					
						
							|  |  |  | 	                      Length: in     System_Length) is | 
					
						
							|  |  |  | 		pragma Inline (Copy_Array); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Dst(Dst'First .. Dst'First + Length - 1) := Src(Src'First .. Src'First + Length - 1); | 
					
						
							|  |  |  | 	end Copy_Array; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	function Is_Empty (Buf: in File_Buffer) return Standard.Boolean is | 
					
						
							|  |  |  | 		pragma Inline (Is_Empty); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return Buf.Pos >= Buf.Last; | 
					
						
							|  |  |  | 	end Is_Empty; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_Length (Buf: in out File_Buffer; Length: in System_Length) is | 
					
						
							|  |  |  | 		pragma Inline (Set_Length); | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Buf.Pos := Buf.Data'First - 1; -- this should be 0
 | 
					
						
							|  |  |  | 		Buf.Last := Buf.Pos + Length; | 
					
						
							|  |  |  | 	end Set_Length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Set_Option_Bits (Option: in out Option_Record; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  |                                 Bits:   in     Option_Bits) is | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		Option.Bits := Option.Bits or Bits; | 
					
						
							|  |  |  | 	end Set_Option_Bits; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Clear_Option_Bits (Option: in out Option_Record; | 
					
						
							|  |  |  | 	                             Bits:   in     Option_Bits) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Option.Bits := Option.Bits and not Bits; | 
					
						
							|  |  |  | 	end Clear_Option_Bits; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	-- This function is platform dependent. It is placed separately in a 
 | 
					
						
							|  |  |  | 	-- platform specific directory.
 | 
					
						
							|  |  |  | 	function Get_Default_Option return Option_Record is separate; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| OPEN AND CLOSE
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	function Is_Open (File: in File_Record) return Standard.Boolean is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		return OS.File."/="(File.File, null); | 
					
						
							|  |  |  | 	end Is_Open; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	procedure Open (File: in out File_Record; | 
					
						
							|  |  |  | 	                Name: in     Slim_String; | 
					
						
							|  |  |  | 	                Flag: in     Flag_Record; | 
					
						
							|  |  |  | 	                Pool: in     Storage_Pool_Pointer := null) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (not Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		OS.File.Open (File.File, Name, Flag, Pool => Pool); | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 		Set_Length (File.Rbuf, 0); | 
					
						
							|  |  |  | 		Set_Length (File.Wbuf, 0); | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		File.Option := Get_Default_Option; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		File.EOF := Standard.False; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	end Open; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Open (File: in out File_Record; | 
					
						
							|  |  |  | 	                Name: in     Wide_String; | 
					
						
							|  |  |  | 	                Flag: in     Flag_Record; | 
					
						
							|  |  |  | 	                Pool: in     Storage_Pool_Pointer := null) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (not Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		OS.File.Open (File.File, Name, Flag, Pool => Pool); | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Set_Length (File.Rbuf, 0); | 
					
						
							|  |  |  | 		Set_Length (File.Wbuf, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		File.Option := Get_Default_Option; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		File.EOF := Standard.False; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	end Open; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Close (File: in out File_Record) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		Flush (File); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		OS.File.Close (File.File); | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 		File.File := null; | 
					
						
							|  |  |  | 	end Close; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	procedure Set_Option (File: in out File_Record; Option: in Option_Record) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		if Slim_Character'Val(Option.LF) = Slim_Character'First or else | 
					
						
							|  |  |  | 		   Wide_Character'Val(Option.LF) = Wide_Character'First then | 
					
						
							|  |  |  | 			raise Constraint_Error; -- TODO: different exception name
 | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		File.Option := Option; | 
					
						
							|  |  |  | 	end Set_Option; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	function Get_Option (File: in File_Record) return Option_Record is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		return File.Option; | 
					
						
							|  |  |  | 	end Get_Option; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	procedure Load_Bytes (File: in out File_Record) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 		pragma Assert (Is_Empty(File.Rbuf)); | 
					
						
							|  |  |  | 		L1: System_Length; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if File.EOF then | 
					
						
							|  |  |  | 			-- raise EOF EXCEPTION. ???
 | 
					
						
							|  |  |  | 			null; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			-- Read bytes into the buffer
 | 
					
						
							|  |  |  | 			OS_Read_File (File, File.Rbuf.Data, L1); | 
					
						
							|  |  |  | 			Set_Length  (File.Rbuf, L1); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	end Load_Bytes; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	procedure Fetch_Byte (File:      in out File_Record;  | 
					
						
							|  |  |  | 	                      Item:      out    System_Byte; | 
					
						
							|  |  |  | 	                      Available: out    Standard.Boolean) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		-- NOTE: If no data is available, Item is not initialized in this procedure
 | 
					
						
							|  |  |  | 		if Is_Empty(File.Rbuf) then | 
					
						
							|  |  |  | 			Load_Bytes (File); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 		if Is_Empty(File.Rbuf) then | 
					
						
							|  |  |  | 			Available := Standard.False; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			-- Consume 1 byte
 | 
					
						
							|  |  |  | 			Available := Standard.True; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			File.Rbuf.Pos := File.Rbuf.Pos + 1; | 
					
						
							|  |  |  | 			Item := File.Rbuf.Data(File.Rbuf.Pos); | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 	end Fetch_Byte; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Fetch_Bytes (File:   in out File_Record; | 
					
						
							|  |  |  | 	                       Item:   out    System_Byte_Array; | 
					
						
							|  |  |  | 	                       Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		L1, L2: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		if Is_Empty(File.Rbuf) and then File.EOF then | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 			-- raise EOF EXCEPTION. ???
 | 
					
						
							|  |  |  | 			Length := 0; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			L1 := File.Rbuf.Last - File.Rbuf.Pos; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 			if L1 > 0 then | 
					
						
							|  |  |  | 				-- Copy the residue over to the output buffer
 | 
					
						
							|  |  |  | 				if Item'Length <= L1 then | 
					
						
							|  |  |  | 					L2 := Item'Length; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					L2 := L1; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				Copy_Array (Item, File.Rbuf.Data(File.Rbuf.Pos + 1 .. File.Rbuf.Last), L2); | 
					
						
							|  |  |  | 				File.Rbuf.Pos := File.Rbuf.Pos + L2; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				Length := L2; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				Length := 0; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 			if Item'Length > L1 then | 
					
						
							|  |  |  | 				-- Item is not full. the internal read buffer must be empty.
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				pragma Assert (File.Rbuf.Pos >= File.Rbuf.Last);  | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				L2 := Item'Length - Length; -- Remaining capacity
 | 
					
						
							|  |  |  | 				If L2 >= File.Rbuf.Data'Length then | 
					
						
							|  |  |  | 					-- The remaining capacity of the output buffer is
 | 
					
						
							|  |  |  | 					-- higher than that of the internal buffer. So read
 | 
					
						
							|  |  |  | 					-- directly into the output buffer.
 | 
					
						
							|  |  |  | 					OS_Read_File (File, Item(Item'First + Length .. Item'Last), L2); | 
					
						
							|  |  |  | 					Length := Length + L2; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					-- Read into the internal buffer.
 | 
					
						
							|  |  |  | 					OS_Read_File (File, File.Rbuf.Data, L1); | 
					
						
							|  |  |  | 					Set_Length (File.Rbuf, L1); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 					if L1 < L2 then | 
					
						
							|  |  |  | 						-- the actual bytes read may be less than the remaining capacity
 | 
					
						
							|  |  |  | 						L2 := L1;  | 
					
						
							|  |  |  | 					end if; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 					-- Copy as many bytes as needed into the output buffer.
 | 
					
						
							|  |  |  | 					Copy_Array (Item(Item'First + Length .. Item'Last), File.Rbuf.Data, L2); | 
					
						
							|  |  |  | 					Length := Length + L2; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					File.Rbuf.Pos := File.Rbuf.Pos + L2; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 			end if; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 	end Fetch_Bytes; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| READ SLIM STRING
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	procedure Read (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                Buffer: out    Slim_String; | 
					
						
							|  |  |  | 	                Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 		pragma Assert (Buffer'Length > 0); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		Outbuf: System_Byte_Array (Buffer'Range); | 
					
						
							|  |  |  | 		for Outbuf'Address use Buffer'Address; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Fetch_Bytes (File, Outbuf, Length); | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	end Read; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	procedure Read_Line (File:   in out File_Record; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	                     Buffer: out    Slim_String; | 
					
						
							|  |  |  | 	                     Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		pragma Assert (Buffer'Length > 0); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Outbuf: System_Byte_Array (Buffer'Range); | 
					
						
							|  |  |  | 		for Outbuf'Address use Buffer'Address; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		K: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		K := Outbuf'First - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		outer: loop | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 			if Is_Empty(File.Rbuf) then | 
					
						
							|  |  |  | 				Load_Bytes (File); | 
					
						
							|  |  |  | 				exit when Is_Empty(File.Rbuf); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			while File.Rbuf.Pos < File.Rbuf.Last loop | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 				K := K + 1; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				File.Rbuf.Pos := File.Rbuf.Pos + 1; | 
					
						
							|  |  |  | 				Outbuf(K) := File.Rbuf.Data(File.Rbuf.Pos); | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 				if K >= Outbuf'Last or else Outbuf(K) = File.Option.LF then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					exit outer; -- Done
 | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 			end loop; | 
					
						
							|  |  |  | 		end loop outer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Length := K + 1 - Outbuf'First; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	end Read_Line; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	procedure Get_Line (File:   in out File_Record; | 
					
						
							|  |  |  | 	                    Buffer: out    Slim_String; | 
					
						
							|  |  |  | 	                    Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 		pragma Assert (Buffer'Length > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Last: System_Length; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Read_Line (File, Buffer, Length); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		if Length <= 0 or else (File.Option.Bits and OPTION_CRLF_IN) = 0 then | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Last := Buffer'First + Length - 1; | 
					
						
							|  |  |  | 		if Buffer(Last) = Slim_Character'Val(File.Option.LF) then | 
					
						
							|  |  |  | 			if Last > Buffer'First and then  | 
					
						
							|  |  |  | 			   Buffer(Last - 1) = Slim_Character'Val(File.Option.CR) then | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				-- Switch CR/LF to LF
 | 
					
						
							|  |  |  | 				Length := Length - 1; | 
					
						
							|  |  |  | 				Buffer(Last - 1) := Slim_Character'Val(File.Option.LF); | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		elsif Buffer(Last) = Slim_Character'Val(File.Option.CR) then | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if Is_Empty(File.Rbuf) then | 
					
						
							|  |  |  | 				Load_Bytes (File); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				if Is_Empty(File.Rbuf) then | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 					return; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			end if; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			if File.Rbuf.Data(File.Rbuf.Pos + 1) = File.Option.LF then | 
					
						
							|  |  |  | 				-- Consume LF held in the internal read buffer.
 | 
					
						
							|  |  |  | 				File.Rbuf.Pos := File.Rbuf.Pos + 1; | 
					
						
							|  |  |  | 				-- Switch CR to LF (End-result: CR/LF to LF)
 | 
					
						
							|  |  |  | 				Buffer(Last) := Slim_Character'Val(File.Option.LF); | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	end Get_Line; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| READ WIDE STRING
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	procedure Read_Wide (File:       in out File_Record;  | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	                     Buffer:     out    Wide_String; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	                     Length:     out    System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 	                     Terminator: in     Wide_Character) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 		pragma Assert (Buffer'Length > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		Outbuf: Wide_String renames Buffer; | 
					
						
							|  |  |  | 		Inbuf: Slim_String (File.Rbuf.Data'Range); | 
					
						
							|  |  |  | 		for Inbuf'Address use File.Rbuf.Data'Address; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		L3, L4, I, J, K: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		K := Outbuf'First - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		outer: while K < Outbuf'Last loop | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 			if Is_Empty(File.Rbuf) then | 
					
						
							|  |  |  | 				Load_Bytes (File); | 
					
						
							|  |  |  | 				exit when Is_Empty(File.Rbuf); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			while File.Rbuf.Pos < File.Rbuf.Last and K < Outbuf'Last loop | 
					
						
							|  |  |  | 				I := File.Rbuf.Pos + 1; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				L3 := Sequence_Length(Inbuf(I)); -- Required number of bytes to compose a wide character
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if L3 <= 0 then | 
					
						
							|  |  |  | 					-- Potentially illegal sequence 
 | 
					
						
							|  |  |  | 					K := K + 1; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 					Outbuf(K) := Ascii.Wide.Question; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					File.Rbuf.Pos := I; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					L4 := File.Rbuf.Last - File.Rbuf.Pos;  -- Avaliable number of bytes available in the internal buffer
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					if L4 < L3 then | 
					
						
							|  |  |  | 						-- Insufficient data available. Exit the inner loop to read more.
 | 
					
						
							|  |  |  | 						exit; | 
					
						
							|  |  |  | 					end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					K := K + 1; | 
					
						
							|  |  |  | 					begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 						J := File.Rbuf.Pos + L3; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 						Outbuf(K..K) := Slim_To_Wide(Inbuf(I .. J)); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					exception | 
					
						
							|  |  |  | 						when others =>  | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 							Outbuf(K) := Ascii.Wide.Question; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 							J := I; -- Override J to skip 1 byte only.
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					end; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					File.Rbuf.Pos := J; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 				if Terminator /= Wide_Character'First and then Outbuf(K) = Terminator then  | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					exit outer; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 				end if; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		end loop outer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Length := K + 1 - Outbuf'First; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	end Read_Wide; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	procedure Read (File:   in out File_Record;  | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	                Buffer: out    Wide_String; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	                Length: out    System_Length) is | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		Read_Wide (File, Buffer, Length, Wide_Character'First); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	end Read; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Read_Line (File:   in out File_Record;  | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	                     Buffer: out    Wide_String; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	                     Length: out    System_Length) is | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		Read_Wide (File, Buffer, Length, Wide_Character'Val(File.Option.LF)); | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 	end Read_Line; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	procedure Get_Line (File:   in out File_Record; | 
					
						
							|  |  |  | 	                    Buffer: out    Wide_String; | 
					
						
							|  |  |  | 	                    Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 		pragma Assert (Buffer'Length > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Last: System_Length; | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Read_Line (File, Buffer, Length); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		if Length <= 0 or else (File.Option.Bits and OPTION_CRLF_IN) = 0 then | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		Last := Buffer'First + Length - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if Buffer(Last) = Wide_Character'Val(File.Option.LF) then | 
					
						
							|  |  |  | 			-- if the last character in the output bufer is LF.
 | 
					
						
							|  |  |  | 			-- inspect the previous character to check if it's CR.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if Last > Buffer'First and then  | 
					
						
							|  |  |  | 			   Buffer(Last - 1) = Wide_Character'Val(File.Option.CR) then | 
					
						
							|  |  |  | 				-- Switch CR/LF to LF
 | 
					
						
							|  |  |  | 				Length := Length - 1; | 
					
						
							|  |  |  | 				Buffer(Last - 1) := Wide_Character'Val(File.Option.LF); | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		elsif Buffer(Last) = Wide_Character'Val(File.Option.CR) then | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			-- if the last character in the output buffer is CR,
 | 
					
						
							|  |  |  | 			-- i need to inspect the first character in the internal 
 | 
					
						
							|  |  |  | 			-- read buffer to determine if it's CR/LF.
 | 
					
						
							|  |  |  | 			if Is_Empty(File.Rbuf) then | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Load_Bytes (File); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				if Is_Empty(File.Rbuf) then | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 					-- no more data available.
 | 
					
						
							|  |  |  | 					return; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			end if; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			-- At least the first byte is available.
 | 
					
						
							|  |  |  | 			declare | 
					
						
							|  |  |  | 				Inbuf: Slim_String (File.Rbuf.Data'Range); | 
					
						
							|  |  |  | 				for Inbuf'Address use File.Rbuf.Data'Address; | 
					
						
							|  |  |  | 				L3, I, J: System_Length; | 
					
						
							|  |  |  | 				W: Wide_String(1..1); | 
					
						
							|  |  |  | 			begin | 
					
						
							|  |  |  | 				I := File.Rbuf.Pos + 1; | 
					
						
							|  |  |  | 				L3 := Sequence_Length(Inbuf(I)); -- Required number of bytes to compose a wide character
 | 
					
						
							|  |  |  | 				if L3 in  1 .. File.Rbuf.Last - File.Rbuf.Pos then | 
					
						
							|  |  |  | 					-- The next byte in the internal read buffer is a valid sequence leader and
 | 
					
						
							|  |  |  | 					-- the internal buffer has enough bytes to build a wide character.
 | 
					
						
							|  |  |  | 					J := File.Rbuf.Pos + L3; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 					begin | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 						W := Slim_To_Wide(Inbuf(I .. J)); | 
					
						
							|  |  |  | 					exception | 
					
						
							|  |  |  | 						when others => | 
					
						
							|  |  |  | 							-- Don't do anything special despite the conversion error. 
 | 
					
						
							|  |  |  | 							-- The next call should encounter the error again.
 | 
					
						
							|  |  |  | 							J := File.Rbuf.Pos; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 					end; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 					 | 
					
						
							|  |  |  | 					if J > File.Rbuf.Pos and then W(1) = Wide_Character'Val(File.Option.LF) then | 
					
						
							|  |  |  | 						-- Consume LF held in the internal read buffer.
 | 
					
						
							|  |  |  | 						File.Rbuf.Pos := J; | 
					
						
							|  |  |  | 						-- Switch CR to LF (End-result: CR/LF to LF)
 | 
					
						
							|  |  |  | 						Buffer(Last) := Wide_Character'Val(File.Option.LF); | 
					
						
							|  |  |  | 					end if; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			end; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 	end Get_Line; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| WRITE SLIM STRING
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	procedure Write (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                 Buffer: in     Slim_String; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 	                 Length: out    System_Length) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		Inbuf: System_Byte_Array (Buffer'Range); | 
					
						
							|  |  |  | 		for Inbuf'Address use Buffer'Address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		F, L: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		-- This procedure attempts to write as many bytes as requested.
 | 
					
						
							|  |  |  | 		-- However, under a certain condition, it may not be able to 
 | 
					
						
							|  |  |  | 		-- process the input buffer in full.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		if not Is_Empty(File.Wbuf) then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			-- Some residue data in the internal buffer.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			if Inbuf'Length <= File.Wbuf.Data'Last - File.Wbuf.Last then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				-- Copy the input to the internal buffer to reduce OS calls
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				F := File.Wbuf.Last + 1; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				L := F + Inbuf'Length - 1; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				File.Wbuf.Data(F .. L) := Inbuf; | 
					
						
							|  |  |  | 				File.Wbuf.Last := L; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				Flush (File); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				-- The resulting length is the length  of input buffer given.
 | 
					
						
							|  |  |  | 				-- The residue in the internal write buffer is not counted.
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				Length := Inbuf'Length; | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			-- Flush the residue first.
 | 
					
						
							|  |  |  | 			Flush (File); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		L := 0; | 
					
						
							|  |  |  | 		while L < Inbuf'Length loop | 
					
						
							|  |  |  | 			--begin
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				OS.File.Write (File.File, Inbuf(Inbuf'First + L .. Inbuf'Last), F); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			--exception
 | 
					
						
							|  |  |  | 			--	when OS.Would_Block_Exception =>
 | 
					
						
							|  |  |  | 			--		-- Cannot write the input in full.
 | 
					
						
							|  |  |  | 			--		-- Copy some to to the internal buffer
 | 
					
						
							|  |  |  | 			--		L := L + as much as copied;
 | 
					
						
							|  |  |  | 			--		exit;
 | 
					
						
							|  |  |  | 			--	when others =>
 | 
					
						
							|  |  |  | 			--		raise;
 | 
					
						
							|  |  |  | 			--end;
 | 
					
						
							|  |  |  | 			L := L + F; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Length := L; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	end Write; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	procedure Write_Line (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                      Buffer: in     Slim_String; | 
					
						
							|  |  |  | 	                      Length: out    System_Length) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		Inbuf: System_Byte_Array (Buffer'Range); | 
					
						
							|  |  |  | 		for Inbuf'Address use Buffer'Address; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		L, I, LF: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		-- This procedure attempts to write the input up to the last line
 | 
					
						
							|  |  |  | 		-- terminator. It buffers the remaining input after the terminator.
 | 
					
						
							|  |  |  | 		-- The input may not include any line terminators. 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		LF := File.Wbuf.Data'First - 1; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		I := Inbuf'First - 1; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		while I < Inbuf'Last loop | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			if File.Wbuf.Last >= File.Wbuf.Data'Last then | 
					
						
							|  |  |  | 				-- The internal write buffer is full.
 | 
					
						
							|  |  |  | 				Flush (File); | 
					
						
							|  |  |  | 				LF := File.Wbuf.Data'First - 1; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			I := I + 1; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			File.Wbuf.Last := File.Wbuf.Last + 1; | 
					
						
							|  |  |  | 			File.Wbuf.Data(File.Wbuf.Last) := Inbuf(I); | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			if File.Wbuf.Data(File.Wbuf.Last) = File.Option.LF then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				-- Remeber the index of the line terminator
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				LF := File.Wbuf.Last; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			end if; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- The line terminator was found. Write up to the terminator.
 | 
					
						
							|  |  |  | 		-- Keep the rest in the internal buffer.
 | 
					
						
							|  |  |  | 		if LF in File.Wbuf.Data'Range then | 
					
						
							|  |  |  | 			while File.Wbuf.Pos < LF loop | 
					
						
							|  |  |  | 				OS.File.Write (File.File, File.Wbuf.Data(File.Wbuf.Pos + 1 .. LF), L); | 
					
						
							|  |  |  | 				File.Wbuf.Pos := File.Wbuf.Pos + L; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if File.Wbuf.Pos >= File.Wbuf.Data'First then | 
					
						
							|  |  |  | 			Compact_Buffer (File.Wbuf); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Length := I - Inbuf'First + 1; | 
					
						
							|  |  |  | 	end Write_Line; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Put_Line (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                    Buffer: in     Slim_String; | 
					
						
							|  |  |  | 	                    Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Inbuf: System_Byte_Array (Buffer'Range); | 
					
						
							|  |  |  | 		for Inbuf'Address use Buffer'Address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		L, I, LF: System_Length; | 
					
						
							|  |  |  | 		X: System_Byte; | 
					
						
							|  |  |  | 		Injected: Standard.Boolean := Standard.False; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		LF := File.Wbuf.Data'First - 1; | 
					
						
							|  |  |  | 		I := Inbuf'First - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while I < Inbuf'Last loop | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			if (File.Option.Bits and OPTION_CRLF_OUT) /= 0 and then  | 
					
						
							|  |  |  | 			   not Injected and then Inbuf(I + 1) = File.Option.LF then | 
					
						
							|  |  |  | 				X := File.Option.CR; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				Injected := Standard.True; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				I := I + 1; | 
					
						
							|  |  |  | 				X := Inbuf(I); | 
					
						
							|  |  |  | 				Injected := Standard.False; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if File.Wbuf.Last >= File.Wbuf.Data'Last then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				-- The internal write buffer is full.
 | 
					
						
							|  |  |  | 				Flush (File); | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				LF := File.Wbuf.Data'First - 1; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			File.Wbuf.Last := File.Wbuf.Last + 1; | 
					
						
							|  |  |  | 			File.Wbuf.Data(File.Wbuf.Last) := X; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			if File.Wbuf.Data(File.Wbuf.Last) = File.Option.LF then  | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				-- Remeber the index of the line terminator
 | 
					
						
							|  |  |  | 				LF := File.Wbuf.Last; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		-- The line terminator was found. Write up to the terminator.
 | 
					
						
							|  |  |  | 		-- Keep the rest in the internal buffer.
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		if LF in File.Wbuf.Data'Range then | 
					
						
							|  |  |  | 			while File.Wbuf.Pos < LF loop | 
					
						
							|  |  |  | 				OS.File.Write (File.File, File.Wbuf.Data(File.Wbuf.Pos + 1 .. LF), L); | 
					
						
							|  |  |  | 				File.Wbuf.Pos := File.Wbuf.Pos + L; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if File.Wbuf.Pos >= File.Wbuf.Data'First then | 
					
						
							|  |  |  | 			Compact_Buffer (File.Wbuf); | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Length := I - Inbuf'First + 1; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	end Put_Line; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| WRITE WIDE STRING
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	procedure Write (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                 Buffer: in     Wide_String; | 
					
						
							| 
									
										
										
										
											2014-06-05 15:26:37 +00:00
										 |  |  | 	                 Length: out    System_Length) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		L, I: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		I := Buffer'First - 1; | 
					
						
							|  |  |  | 		while I < Buffer'Last loop | 
					
						
							|  |  |  | 			I := I + 1; | 
					
						
							|  |  |  | 			declare | 
					
						
							|  |  |  | 				Tmp: Slim_String := Wide_To_Slim(Buffer(I..I)); | 
					
						
							|  |  |  | 				Tmp2: System_Byte_Array(Tmp'Range); | 
					
						
							|  |  |  | 				for Tmp2'Address use Tmp'Address; | 
					
						
							|  |  |  | 			begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				L := File.Wbuf.Last + Tmp2'Length; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				if L > File.Wbuf.Data'Last then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					-- The multi-byte sequence for the current character
 | 
					
						
							|  |  |  | 					-- can't fit into the internal buffer. Flush the
 | 
					
						
							|  |  |  | 					-- buffer and attempt to fit it in.
 | 
					
						
							|  |  |  | 					Flush (File); | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					L := File.Wbuf.Pos + Tmp2'Length; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				File.Wbuf.Data(File.Wbuf.Last + 1 .. L) := Tmp2; | 
					
						
							|  |  |  | 				File.Wbuf.Last := L; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			end; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Flush (File); | 
					
						
							|  |  |  | 		Length := I - Buffer'First + 1; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	end Write; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	procedure Write_Line (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                      Buffer: in     Wide_String; | 
					
						
							|  |  |  | 	                      Length: out    System_Length) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		L, I, LF: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		LF := File.Wbuf.Data'First - 1; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		I := Buffer'First - 1; | 
					
						
							|  |  |  | 		while I < Buffer'Last loop | 
					
						
							|  |  |  | 			I := I + 1; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			declare | 
					
						
							|  |  |  | 				Tmp: Slim_String := Wide_To_Slim(Buffer(I..I)); | 
					
						
							|  |  |  | 				Tmp2: System_Byte_Array(Tmp'Range); | 
					
						
							|  |  |  | 				for Tmp2'Address use Tmp'Address; | 
					
						
							|  |  |  | 			begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				L := File.Wbuf.Last + Tmp2'Length; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				if L > File.Wbuf.Data'Last then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					-- The multi-byte sequence for the current character
 | 
					
						
							|  |  |  | 					-- can't fit into the internal buffer. Flush the
 | 
					
						
							|  |  |  | 					-- buffer and attempt to fit it in.
 | 
					
						
							|  |  |  | 					Flush (File); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					L := File.Wbuf.Pos + Tmp2'Length; | 
					
						
							|  |  |  | 					LF := File.Wbuf.Data'First - 1; | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 				if Buffer(I) = Wide_Character'Val(File.Option.LF) then | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 					LF := L; | 
					
						
							|  |  |  | 				end if; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				File.Wbuf.Data(File.Wbuf.Last + 1 .. L) := Tmp2; | 
					
						
							|  |  |  | 				File.Wbuf.Last := L; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			end; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		if LF in File.Wbuf.Data'Range then | 
					
						
							|  |  |  | 			while File.Wbuf.Pos < LF loop | 
					
						
							|  |  |  | 				OS.File.Write (File.File, File.Wbuf.Data(File.Wbuf.Pos + 1 .. LF), L); | 
					
						
							|  |  |  | 				File.Wbuf.Pos := File.Wbuf.Pos + L; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if File.Wbuf.Pos >= File.Wbuf.Data'First then | 
					
						
							|  |  |  | 			Compact_Buffer (File.Wbuf); | 
					
						
							|  |  |  | 		end if; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Length := I - Buffer'First + 1; | 
					
						
							|  |  |  | 	end Write_Line; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	procedure Put_Line (File:   in out File_Record;  | 
					
						
							|  |  |  | 	                    Buffer: in     Wide_String; | 
					
						
							|  |  |  | 	                    Length: out    System_Length) is | 
					
						
							|  |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		F, L, I, LF: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 		X: Wide_String(1..2) := (Wide_Character'Val(File.Option.CR), Wide_Character'Val(File.Option.LF)); | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		LF := File.Wbuf.Data'First - 1; | 
					
						
							|  |  |  | 		I := Buffer'First - 1; | 
					
						
							|  |  |  | 		while I < Buffer'Last loop | 
					
						
							|  |  |  | 			I := I + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			X(2) := Buffer(I); | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 			if (File.Option.Bits and OPTION_CRLF_OUT) /= 0 and then | 
					
						
							|  |  |  | 			   Buffer(I) = Wide_Character'Val(File.Option.LF) then | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				F := 1; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				F := 2; | 
					
						
							|  |  |  | 			end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			declare | 
					
						
							|  |  |  | 				Tmp: Slim_String := Wide_To_Slim(X(F..2)); | 
					
						
							|  |  |  | 				Tmp2: System_Byte_Array(Tmp'Range); | 
					
						
							|  |  |  | 				for Tmp2'Address use Tmp'Address; | 
					
						
							|  |  |  | 			begin | 
					
						
							|  |  |  | 				L := File.Wbuf.Last + Tmp2'Length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if L > File.Wbuf.Data'Last then | 
					
						
							|  |  |  | 					-- The multi-byte sequence for the current character
 | 
					
						
							|  |  |  | 					-- can't fit into the internal buffer. Flush the
 | 
					
						
							|  |  |  | 					-- buffer and attempt to fit it in.
 | 
					
						
							|  |  |  | 					Flush (File); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					L := File.Wbuf.Pos + Tmp2'Length; | 
					
						
							|  |  |  | 					LF := File.Wbuf.Data'First - 1; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-21 16:31:49 +00:00
										 |  |  | 				if Buffer(I) = Wide_Character'Val(File.Option.LF) then  | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 					LF := L; | 
					
						
							|  |  |  | 				end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				File.Wbuf.Data(File.Wbuf.Last + 1 .. L) := Tmp2; | 
					
						
							|  |  |  | 				File.Wbuf.Last := L; | 
					
						
							|  |  |  | 			end; | 
					
						
							|  |  |  | 		end loop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if LF in File.Wbuf.Data'Range then | 
					
						
							|  |  |  | 			while File.Wbuf.Pos < LF loop | 
					
						
							|  |  |  | 				OS.File.Write (File.File, File.Wbuf.Data(File.Wbuf.Pos + 1 .. LF), L); | 
					
						
							|  |  |  | 				File.Wbuf.Pos := File.Wbuf.Pos + L; | 
					
						
							|  |  |  | 			end loop; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if File.Wbuf.Pos >= File.Wbuf.Data'First then | 
					
						
							|  |  |  | 			Compact_Buffer (File.Wbuf); | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Length := I - Buffer'First + 1; | 
					
						
							|  |  |  | 	end Put_Line; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							|  |  |  | 	--| FLUSH AND DRAIN
 | 
					
						
							|  |  |  | 	--|-----------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	procedure Flush (File: in out File_Record) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		L: System_Length; | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		while not Is_Empty(File.Wbuf)  loop | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			--begin
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 				OS.File.Write (File.File, File.Wbuf.Data(File.Wbuf.Pos + 1 .. File.Wbuf.Last), L); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 			--exception
 | 
					
						
							|  |  |  | 			--	when Would_Block_Exception =>
 | 
					
						
							|  |  |  | 			--		-- Flush must write all it can.
 | 
					
						
							|  |  |  | 			--		null;
 | 
					
						
							|  |  |  | 			--	when others => 
 | 
					
						
							|  |  |  | 			--		raise;
 | 
					
						
							|  |  |  | 			--end;
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 			File.Wbuf.Pos := File.Wbuf.Pos + L; | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 		end loop; | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Set_Length (File.Wbuf, 0); | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | 	end Flush; | 
					
						
							|  |  |  | 	                  | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	procedure Drain (File: in out File_Record) is | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 		pragma Assert (Is_Open(File)); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2014-06-19 14:13:19 +00:00
										 |  |  | 		Set_Length (File.Wbuf, 0); | 
					
						
							| 
									
										
										
										
											2014-06-06 16:44:45 +00:00
										 |  |  | 	end Drain; | 
					
						
							| 
									
										
										
										
											2014-06-17 15:23:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-04 17:15:52 +00:00
										 |  |  | end File; |