implementation module ReadWriteState

import StdString;
import ExtFile;
import State;
//import DebugUtilities;
F a b :== b;
debug_complement normal during_debugging :== normal;

MODULE_SYMBOL						:== 0
LABEL_SYMBOL						:== 1
SECTIONLABEL_SYMBOL					:== 2
IMPORTLABEL_SYMBOL					:== 3
IMPORTEDLABEL_SYMBOL				:== 4
IMPORTEDLABELPLUSOFFSET_SYMBOL		:== 5
IMPORTEDFUNCTIONDESCRIPTOR_SYMBOL	:== 6
EMPTYSYMBOL_SYMBOL					:== 7

// macOS
ALIAS_MODULE						:== 8
IMPORTEDFUNCTIONDESCRIPTORTOCMODULE_SYMBOL	:== 9

// COMPLEMENT VERSION MANAGEMENT
:: ComplementVersion
	= { 
		complement_id	:: !String
	,	major			:: !Int
	,	minor			:: !Int
	};
	
S_COMPLEMENT_ID	:== 8;
	
WriteComplementVersion :: !ComplementVersion !*File -> !*File;
WriteComplementVersion complement_version=:{complement_id,major,minor} output
	#! output = output
		FWS (complement_id % (0,dec S_COMPLEMENT_ID))
		FWI major
		FWI minor
		;
	= output;
	
ReadComplementVersion :: !{#Char} !ComplementVersion !*File !*State -> !*(!Int,!*File,!*State);
ReadComplementVersion state_file_name {complement_id,major,minor} input state
	// check if complement is corrupt
	#! (read_complement_id,input)
		= freads input S_COMPLEMENT_ID;
	| complement_id <> read_complement_id
		#! state 
			= AddMessage (LinkerError ("the complement " +++ state_file_name +++ " has id '" +++ toString read_complement_id +++ "' but the dynamic linker requires '" +++ toString complement_id +++ "'")) state;
		= (minor,input,state);
		
	// check if a major structure change took place
	#! (_,read_major,input)
		= freadi input;
	#! qq
		= "major: " +++ toString major +++ " - read_major: " +++ toString read_major;
		
	| F qq major <> read_major
		#! state
			= AddMessage (LinkerError ("the complement " +++ state_file_name +++ "cannot be processed by the current dynamic linker")) state;
		= (minor,input,state);
		
	// read minor
	#! (_,read_minor,input)
		= freadi input;
	= (read_minor,input,state);
	
ComplementVersion :== sel_platform WinOSComplementVersion MacOSComplementVersion ;
	 
MacOSComplementVersion :: !ComplementVersion;
MacOSComplementVersion
	= {
		complement_id	= "dcmacos\0"
	,	major			= 0
	,	minor			= 0
	};

WinOSComplementVersion :: !ComplementVersion;
WinOSComplementVersion 
	= {
		complement_id	= "dcwinos\0"
	,	major			= 0
	,	minor			= 0
	};	