indexing
	cluster: "file_system_objects"
	namespace: "candidate"
	description: "List of properties from real file system object."
	original_author: "Justin Finnerty"
	original_date: "July 2005"
	current_date: "$Date: 2005/09/28 13:39:09 $"
	current_author: "$Author: finnerty $"
	revision: "$Revision: 2.3 $"
   -- $Log: posix_fso_prop.ge,v $
   -- Revision 2.3  2005/09/28 13:39:09  finnerty
   -- Updated to work with ISE
   --
   -- Revision 2.2  2005/09/05 02:35:01  finnerty
   -- Updated to conform to cursors/containers in the GOBO library and
   -- test programs compile with SE and VE.
   --
   -- Revision 2.1  2005/09/02 08:08:43  finnerty
   -- Renamed *.e to *.ge for gepp
   --
   -- Revision 2.0  2005/08/26 23:30:22  finnerty
   -- == alpha version ==
   --
   -- Revision 1.2  2005/08/12 06:55:48  finnerty
   -- Turned into factory for FSO_PROPERTIES.
   --
   -- Revision 1.1  2005/08/10 02:18:15  finnerty
   -- FSO_PROPERTIES descendent for supported POSIX systems.
   --
   -- Revision 1.2  2005/08/09 13:47:53  finnerty
   -- Changes for alpha test. UNIX version in FSO_PROPERTIES heirarchy.
   --
   -- Revision 1.1  2005/08/08 12:03:42  finnerty
   -- Made concrete version of FSO_PROPERTIES for UNiX.
   --
   --

class POSIX_FSO_PROP
	-- List of properties from real POSIX compliant file system object.

inherit
	FACTORY_ARG[STRING,FSO_PROPERTIES]
#ifdef SE
insert
	DISPOSABLE
#else
   MEMORY
		redefine
			dispose
		end
#endif
   FSO_FILE_TYPE

creation {ANY}
	make

feature {ANY}
	-- status report
	is_null: BOOLEAN is
			-- Is the C object NULL
		do
#ifdef SE
			Result := m_stat.is_null
#else
#ifdef ISE
			Result := m_stat.to_integer_32 = 0
#else
			Result := m_stat.to_integer = 0
#endif
#endif
		end
feature {ANY}
	-- procedures
	dispose is
			-- Get rid of any C resources
		do
			if not is_null then
				posix_free_stat(m_stat)
			end
		end

	new (a_path: STRING): FSO_PROPERTIES is
			-- Attempt to fetch properties for a path.
		require else
			not is_null
		local
			l_result: INTEGER
			l_exist: BOOLEAN
			l_size: INTEGER
#ifdef SE
			l_type: INTEGER_8
#else
			l_type: INTEGER
#endif
			l_atime, l_ctime, l_mtime: DT_DATE_TIME
#ifdef ISE
			l_path: C_STRING
#endif
		do
#ifdef ISE
			!!l_path.make (a_path)
			l_result := posix_set_stat(l_path.item, m_stat)
#else
			l_result := posix_set_stat(a_path.to_external, m_stat)
#endif
			if l_result = 0 then
				l_exist := True
				l_size := posix_size(m_stat)
				if 0 /= posix_block_device(m_stat) then
					l_type := Block
				elseif 0 /= posix_character_device(m_stat) then
					l_type := Character
				elseif 0 /= posix_directory(m_stat) then
					l_type := Directory
				elseif 0 /= posix_file(m_stat) then
					l_type := File
				elseif 0 /= posix_pipe(m_stat) then
					l_type := Pipe
				elseif 0 /= posix_socket(m_stat) then
					l_type := Socket
				elseif 0 /= posix_symlink (m_stat) then
					l_type := Symlink
				else
					l_type := Other
				end
				!!l_atime.make_from_epoch (posix_access (m_stat))
				!!l_ctime.make_from_epoch (posix_change (m_stat))
				!!l_mtime.make_from_epoch (posix_mod (m_stat))
			else
				l_exist := False
				l_type := Other
				l_size := 0
				!!l_atime.make_from_epoch (0)
				!!l_ctime.make_from_epoch (0)
				!!l_mtime.make_from_epoch (0)
			end
			!!Result.make (l_exist, l_type, l_size, l_atime, l_ctime, l_mtime)
		ensure then
			-- `Result.exists' implies valid properties
			Result /= Void
		end

feature {NONE}
	make is
			-- Initialise factory object
		do
			m_stat := posix_make_stat
		ensure
			not is_null
 		end

feature {NONE}
	-- C datum
	m_stat: POINTER
			-- Pointer to the C stat structure

feature {NONE}
	-- C creation/destruction routines
	posix_make_stat: POINTER is
			-- Allocate a C 'stat' structure
		external "C" end
	posix_free_stat (stat_ptr: POINTER) is
			-- Release a C 'stat' structure
		external "C" end

feature {NONE}
	-- C procedure to query real file system 

	posix_set_stat (a_path, stat_ptr: POINTER): INTEGER is
			-- Retrieve data for `a_path' in `stat_ptr'
		external "C" end
	
feature {NONE}
	-- C queries
	posix_size(stat_ptr: POINTER): INTEGER is
			-- Read file size from `stat_ptr'
		external	"C" end

	posix_block_device (stat_ptr: POINTER): INTEGER is
			-- Test data from `stat_ptr' for file mode
		external "C" end
	posix_character_device (stat_ptr: POINTER): INTEGER is
			-- Test data from `stat_ptr' for file mode
		external "C" end
	posix_directory (stat_ptr: POINTER): INTEGER is 
			-- Test data from `stat_ptr' for file mode
		external "C" end
	posix_file (stat_ptr: POINTER): INTEGER is 
			-- Test data from `stat_ptr' for file mode
		external "C" end
	posix_pipe (stat_ptr: POINTER): INTEGER is 
			-- Test data from `stat_ptr' for file mode
		external "C" end
	posix_socket (stat_ptr: POINTER): INTEGER is 
			-- Test data from `stat_ptr' for file mode
		external "C" end
	posix_symlink (stat_ptr: POINTER): INTEGER is 
			-- Test data from `stat_ptr' for file mode
		external "C" end

	posix_access (stat_ptr: POINTER): INTEGER is 
			-- Read access time from `stat_ptr'
		external "C" end
	posix_change (stat_ptr: POINTER): INTEGER is 
			-- Read change time from `stat_ptr'
		external "C" end
	posix_mod (stat_ptr: POINTER): INTEGER is 
			-- Read modification time from `stat_ptr'
		external "C" end
end -- class POSIX_FSO_PROP
