<commit_before># This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2004-2008 <NAME> <<EMAIL>>
# Copyright 2008 <NAME> <<EMAIL>>
# Copyright 2008 <NAME> <<EMAIL>>
#
# This file is free software, which comes along with NIT.  This software is
# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without  even  the implied warranty of  MERCHANTABILITY or  FITNESS FOR A 
# PARTICULAR PURPOSE.  You can modify it is you want,  provided this header
# is kept unaltered, and a notification of the changes is added.
# You  are  allowed  to  redistribute it and sell it, alone or is a part of
# another product.

# File manipulations (create, read, write, etc.)
module file

intrude import stream
intrude import string
import string_search
import time

in "C Header" `{
	#include <dirent.h>
	#include <string.h>
	#include <sys/types.h>
	#include <sys/stat.h>
	#include <unistd.h>
`}

redef class Object
# Simple I/O

	# Print `objects` on the standard output (`stdout`).
	protected fun printn(objects: Object...)
	do
		sys.stdout.write(objects.to_s)
	end

	# Print an `object` on the standard output (`stdout`) and add a newline.
	protected fun print(object: Object)
	do
		sys.stdout.write(object.to_s)
		sys.stdout.write("\n")
	end

	# Read a character from the standard input (`stdin`).
	protected fun getc: Char
	do
		return sys.stdin.read_char.ascii
	end

	# Read a line from the standard input (`stdin`).
	protected fun gets: String
	do
		return sys.stdin.read_line
	end

	# Return the working (current) directory
	protected fun getcwd: String do return file_getcwd.to_s
	private fun file_getcwd: NativeString is extern "string_NativeString_NativeString_file_getcwd_0"
end

# File Abstract Stream
abstract class FStream
	super IOS
	# The path of the file.
	var path: nullable String = null

	# The FILE *.
	var _file: nullable NativeFile = null

	fun file_stat: FileStat
	do return _file.file_stat end
end

# File input stream
class IFStream
	super FStream
	super BufferedIStream
	# Misc

	# Open the same file again.
	# The original path is reused, therefore the reopened file can be a different file.
	fun reopen
	do
		if not eof then close
		_file = new NativeFile.io_open_read(path.to_cstring)
		end_reached = false
		_buffer_pos = 0
		_buffer.clear
	end

	redef fun close
	do
		var i = _file.io_close
		end_reached = true
	end

	redef fun fill_buffer
	do
		var nb = _file.io_read(_buffer.items, _buffer.capacity)
		if nb <= 0 then
			end_reached = true
			nb = 0
		end
		_buffer.length = nb
		_buffer_pos = 0
	end
	
	# End of file?
	redef var end_reached: Bool = false

	# Open the file at `path` for reading.
	init open(path: String)
	do
		self.path = path
		prepare_buffer(10)
		_file = new NativeFile.io_open_read(path.to_cstring)
		assert not _file.address_is_null else
			print "Error: Opening file at '{path}' failed with '{sys.errno.strerror}'"
		end
	end

	private init do end
	private init without_file do end
end

# File output stream
class OFStream
	super FStream
	super OStream
	
	redef fun write(s)
	do
		assert _writable
		write_native(s.to_cstring, s.length)
	end

	redef fun is_writable do return _writable
	
	redef fun close
	do
		var i = _file.io_close
		_writable = false
	end

	# Is the file open in write mode
	var _writable: Bool
	
	# Write `len` bytes from `native`.
	private fun write_native(native: NativeString, len: Int)
	do
		assert _writable
		var err = _file.io_write(native, len)
		if err != len then<commit_msg>lib/standard/ropes: Adapted write for performance with other String representations.<commit_after># This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2004-2008 <NAME> <<EMAIL>>
# Copyright 2008 <NAME> <<EMAIL>>
# Copyright 2008 <NAME> <<EMAIL>>
#
# This file is free software, which comes along with NIT.  This software is
# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without  even  the implied warranty of  MERCHANTABILITY or  FITNESS FOR A 
# PARTICULAR PURPOSE.  You can modify it is you want,  provided this header
# is kept unaltered, and a notification of the changes is added.
# You  are  allowed  to  redistribute it and sell it, alone or is a part of
# another product.

# File manipulations (create, read, write, etc.)
module file

intrude import stream
intrude import ropes
import string_search
import time

in "C Header" `{
	#include <dirent.h>
	#include <string.h>
	#include <sys/types.h>
	#include <sys/stat.h>
	#include <unistd.h>
`}

redef class Object
# Simple I/O

	# Print `objects` on the standard output (`stdout`).
	protected fun printn(objects: Object...)
	do
		sys.stdout.write(objects.to_s)
	end

	# Print an `object` on the standard output (`stdout`) and add a newline.
	protected fun print(object: Object)
	do
		sys.stdout.write(object.to_s)
		sys.stdout.write("\n")
	end

	# Read a character from the standard input (`stdin`).
	protected fun getc: Char
	do
		return sys.stdin.read_char.ascii
	end

	# Read a line from the standard input (`stdin`).
	protected fun gets: String
	do
		return sys.stdin.read_line
	end

	# Return the working (current) directory
	protected fun getcwd: String do return file_getcwd.to_s
	private fun file_getcwd: NativeString is extern "string_NativeString_NativeString_file_getcwd_0"
end

# File Abstract Stream
abstract class FStream
	super IOS
	# The path of the file.
	var path: nullable String = null

	# The FILE *.
	var _file: nullable NativeFile = null

	fun file_stat: FileStat
	do return _file.file_stat end
end

# File input stream
class IFStream
	super FStream
	super BufferedIStream
	# Misc

	# Open the same file again.
	# The original path is reused, therefore the reopened file can be a different file.
	fun reopen
	do
		if not eof then close
		_file = new NativeFile.io_open_read(path.to_cstring)
		end_reached = false
		_buffer_pos = 0
		_buffer.clear
	end

	redef fun close
	do
		var i = _file.io_close
		end_reached = true
	end

	redef fun fill_buffer
	do
		var nb = _file.io_read(_buffer.items, _buffer.capacity)
		if nb <= 0 then
			end_reached = true
			nb = 0
		end
		_buffer.length = nb
		_buffer_pos = 0
	end
	
	# End of file?
	redef var end_reached: Bool = false

	# Open the file at `path` for reading.
	init open(path: String)
	do
		self.path = path
		prepare_buffer(10)
		_file = new NativeFile.io_open_read(path.to_cstring)
		assert not _file.address_is_null else
			print "Error: Opening file at '{path}' failed with '{sys.errno.strerror}'"
		end
	end

	private init do end
	private init without_file do end
end

# File output stream
class OFStream
	super FStream
	super OStream
	
	redef fun write(s)
	do
		assert _writable
		if s isa FlatText then
			write_native(s.to_cstring, s.length)
		else
			for i in s.substrings do write_native(i.to_cstring, i.length)
		end
	end

	redef fun is_writable do return _writable
	
	redef fun close
	do
		var i = _file.io_close
		_writable = false
	end

	# Is the file open in write mode
	var _writable: Bool
	
	# Write `len` bytes from `native`.
	private fun write_native(native: NativeString, len: Int)
	do
		assert _writable
		var err = _file.io_write(native, len)
		if err != len then
{'fraction_non_alphanumeric': 0.07629960871995528, 'fraction_numerical': 0.006428172163219676, 'mean_word_length': 3.6992777413000657, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5792561', 'n_tokens_mistral': 2579, 'n_tokens_neox': 2401, 'n_words': 913}