implementation module StdDynamicError

import StdEnv;

:: DynamicError
	= DYN_OK
	
	// errors from dynamic linker
	| DYN_NOT_FOUND !String
	
// Encoded DynamicError-constructors
CODE_DYN_OK				:== 0;
CODE_DYN_NOT_FOUND		:== 1;
		
// Message format
DYN_MESSAGE_LENGTH		:== 0;
DYN_MESSAGE_ID			:== 4;
DYN_BASIC_ERROR_SIZE	:== 8;					// length, error id, arg0 ... argN with N >= 0

instance toString DynamicError
where
	toString e=:DYN_OK						
		= FromIntToString DYN_BASIC_ERROR_SIZE +++ FromIntToString (toInt e)
	toString e=:(DYN_NOT_FOUND file_name)	
		# error_size
			= DYN_BASIC_ERROR_SIZE + (size file_name) + 1;
		= FromIntToString error_size +++ FromIntToString (toInt e) +++ file_name;
		
instance fromString DynamicError
where
	fromString error_message
		# message_size
			= FromStringToInt error_message DYN_MESSAGE_LENGTH
		# message_id
			= FromStringToInt error_message DYN_MESSAGE_ID
		= case message_id of 
			CODE_DYN_OK			-> DYN_OK
			CODE_DYN_NOT_FOUND	
				# file_not_found
					= error_message % (DYN_BASIC_ERROR_SIZE,dec message_size)
				-> DYN_NOT_FOUND file_not_found
		
instance toInt DynamicError
where
	toInt DYN_OK				= 	CODE_DYN_OK
	toInt (DYN_NOT_FOUND _)		= 	CODE_DYN_NOT_FOUND
	
// copied from pdExtInt; utilities
FromIntToString :: !Int -> !String
FromIntToString v
	= { (toChar v), (toChar (v>>8)), (toChar (v>>16)), (toChar (v>>24)) }
	
FromStringToInt :: !String !Int -> !Int
FromStringToInt array i
	= (toInt v0)+(toInt v1<<8)+(toInt v2<<16)+(toInt v3<<24)
where
	v0
		= array.[i]
	v1
		= array.[i+1]
	v2 
		= array.[i+2]
	v3  
		= array.[i+3]