5.6. File Handling (file.rsl)
(****
*
* Module File defines the objects and operations related to file processing
* in the calendar system.
*
*)
module File;
from CalendarDB import CalendarDB, UserCalendar, UserWorkSpace,
RequiresSaving, GlobalOptions, UserOptions;
from Admin import UserId;
export FileSpace, File;
object FileSpace is File*
description: (*
A FileSpace is an abstract model of a file space in the operating
environment in which the CalendarTool is run. The FileSpace is simply
a collection of zero or more Files, with no other properties modeled
here.
*);
end;
object File is
components: name:FileName and permissions:FilePermissions and
file_type:FileType and data:FileData;
description: (*
A File is an abstraction of a file stored in the file space. It has a
name, permissions, type, and data. These are the components sufficient
to specify the behavior of Calendar Tool file operations.
*);
end File;
object FileName is string
description: (*
The name of a file. The string representation here is an abstraction
of file names used in specific operating environments. Implementations
may obey any syntactic or semantic constraints imposed by a particular
environment.
*);
end;
object FilePermissions is is_readable:IsReadable and is_writable:IsWritable
description: (*
FilePermissions indicate whether a file is readable and/or writable.
*);
end;
object IsReadable is boolean
description: (*
Flag indicating whether a file is readable, which is required to be
true by the FileOpen operation.
*);
end;
object IsWritable is boolean
description: (*
Flag indicating whether a file is writable, which is required to be
true by the FileSave operation.
*);
end;
object FileType is calendar_type:CalendarType or other_type:OtherType
description: (*
The type of file data is either CalendarType data (which we care about)
or any other type of data that can be stored in a file, which we don't
care about.
*);
end FileType;
object CalendarType
description: (*
File data typing tag indicating that a file contains calendar data
created by the Calendar Tool
*);
end CalendarType;
object OtherType
description: (*
File data typing tag indicating that a file contains data other than
calendar data created by the Calendar Tool
*);
end OtherType;
object FileData is UserCalendar
description: (*
The abstract representation of calendar-type FileData is a UserCalendar
object. Calendar Tool implementors may use any concrete file data
representation that accurately holds all UserCalendar components.
*);
end FileData;
operation FileNew is
inputs: uws:UserWorkSpace, go:GlobalOptions;
outputs: uws':UserWorkSpace;
description: (*
Add a new empty calendar to the workspace and make it current.
*);
precondition: ;
postcondition:
(*
* The output workspace has a new empty calendar and that calendar is
* current. The user id of the new calendar is that of the workspace,
* the file is empty, the options are the given global options input,
* and the calendar does not require saving. The calendars in
* positions 1-last in the the input workspace are in positions
* 2-last+1 in the output workspace.
*)
(exists (uc:UserCalendar)
(uc = uws'.calendars[1]) and
(uc.uid = uws.uid) and
(uc.file = nil) and
(uc.options = go) and
(not uc.requires_saving) and
(uc.items = nil) and
(#(uws'.calendars) = #(uws.calendars) +1) and
(forall (i:integer | (i >= 2) and (i <= #(uws.calendars)))
uws'.calendars[i+1] = uws.calendars[i+1]
)
);
end FileNew;
operation FileOpen is
inputs: fs:FileSpace, fn:FileName, uws:UserWorkSpace, go:GlobalOptions;
outputs: fs':FileSpace, uws':UserWorkSpace;
description: (*
Open an existing calendar file of the given name and put the data from
that file in the workspace.
*);
precondition:
(*
* A file of the given name exists in the given file space, the file
* is readable, and the file's data are of type calendar.
*)
exists (file in fs)
(file.name = fn) and
file.permissions.is_readable and
file.file_type?calendar_type;
postcondition:
(*
* The output workspace has a new calendar containing the file data of
* the input file, and that calendar is current. The user id of the
* new calendar is that of the workspace, the options are the given
* global options input, and the calendar does not require saving. The
* calendars in positions 1-last in the the input workspace are in
* positions 2-last+1 in the output workspace.
*)
(exists (uc:UserCalendar)
(uc = uws'.calendars[1]) and
(uc.uid = uws.uid) and
(exists (file in fs)
(file.name = fn) and
(uc.file = file) and
(uc.items = file.data.items)
) and
(uc.options = go) and
(not uc.requires_saving) and
(#(uws'.calendars) = #(uws.calendars) +1) and
(forall (i:integer | (i >= 2) and (i <= #(uws.calendars)))
uws'.calendars[i+1] = uws.calendars[i+1]
)
);
end FileOpen;
operation FileClose is
inputs: fs:FileSpace, uws:UserWorkSpace;
outputs: fs':FileSpace, uws':UserWorkSpace;
description: (*
Close the current calendar if it does not require saving.
*);
precondition:
(*
* The calendar does not require saving.
*)
not (uws.calendars[1].requires_saving);
postcondition:
(*
* The current calendar is deleted from the workspace. The remaining
* calendars, if any, are shifted in position in the list one position
* earlier.
*)
(not (uws.calendars[1] in uws'.calendars)) and
(#(uws'.calendars) = #(uws.calendars) - 1) and
(forall (i:integer | (i >= 1) and (i < #(uws.calendars)))
uws'.calendars[i] = uws.calendars[i+1];
);
end FileClose;
operation FileSave is
inputs: fs:FileSpace, uws:UserWorkSpace;
outputs: fs':FileSpace, uws':UserWorkSpace;
description: (*
If the calendar in the given workspace requires saving, save it in the
given file space.
*);
precondition:
(*
* The given workspace requires saving. Also, there is a writable
* file of the current workspace filename in the given FileSpace. Note
* that the only way the current file could be unwritable is through an
* external change to the file space since the file was opened by the
* Calendar Tool. Note further that this precondition disallows the
* case where the current calendar file has been externally deleted
* since it was opened by the calendar tool. That is, the file must
* both exist and be writable at the time the save is attempted.
*)
(uws.calendars[1].requires_saving)
and
(exists (file in fs)
(file.name = uws.calendars[1].file.name) and
(file.permissions.is_writable));
postcondition:
(*
* There is a calendar-type file in the resulting FileSpace containing
* the current workspace calendar as its file data. In the resulting
* workspace, the requires saving indicator and is false.
*)
(exists (file in fs')
(file.name = uws'.calendars[1].file.name) and
(file.permissions.is_writable) and
(file.file_type?calendar_type) and
(not uws'.calendars[1].requires_saving)
);
end FileSave;
end File;
Prev: options.rsl
| Next: edit.rsl
| Up: spec
| Top: index