implementation module StdDynamicFileIO import StdEnv import StdDynamicLowLevelInterface import memory_mapped_files import StdDynamic import DynID from DynamicUtilities import ends, WriteLong, NF /* matyas */ import Directory DS_LIBRARIES_DIR :== "libraries"; DS_SYSTEM_DYNAMICS_DIR :== "system dynamics"; dynamicDatabaseDirectory :: String dynamicDatabaseDirectory= DYNAMICS_DIR +++ "\\" +++ DS_SYSTEM_DYNAMICS_DIR +++ "\\"; libtypDatabaseDirectory :: String libtypDatabaseDirectory= DYNAMICS_DIR +++ "\\" +++ DS_LIBRARIES_DIR +++ "\\"; DYNAMICS_DIR :== "C:\\Documents and Settings\\MIJN_COMPUTER\\Desktop\\Clean\\Dynamics"; splitFileName :: String -> (String,String) /* Gives back ("c:\\windows\\desktop\\","filename.ext") from "c:\\windows\\desktop\\filename.ext" */ splitFileName a #ra= reverse (fromString a) #(fileName,path)= span ((<>)'\\') ra = (function path, function fileName) where function= toString o reverse /* gen_unique_name was simply copied from directory_structure, because it didn't export it. */ gen_unique_name :: Int String String *a -> (String,*a) |FileSystem a gen_unique_name i base_path_name extension files # path_name = base_path_name +++ "_" +++ toString i +++ "c." +++ extension # ((ok,path),files) = pd_StringToPath path_name files | not ok = abort "gen_unique_name: could not convert to path" # ((dir_error,_),files) = getFileInfo path files | dir_error == DoesntExist = (path_name,files) = gen_unique_name (inc i) base_path_name extension files /* \matyas */ // file_name should contain an *absolute* path readDynamic :: String *f -> (Bool,Dynamic,*f) | FileSystem f readDynamic file_name files # file_name = create_dynamic_file_name file_name; /* matyas */ #! (ok,userFile,files) = fopen file_name FReadText files |not ok = (False,undef,files) #(databaseFileName,userFile)= freadline userFile # databaseFileName= (%) databaseFileName (0,(size databaseFileName)-2) //for deleting the "\n". // open dynamic; dynamic rts accesses file contai #! (ok,dynamic_header=:{block_table_i,graph_i},databaseFile,files) = open_dynamic_as_binary (dynamicDatabaseDirectory+++databaseFileName) files /* \matyas */ | not ok #! (_,files) = close_dynamic_as_binary databaseFile files = (False,undef,files) // initializes the dynamic info-structure (gdid) #! (ok,gdid,databaseFile) = init_dynamic (dynamicDatabaseDirectory+++databaseFileName) dynamic_header databaseFile | not ok = abort "readDynamic: error; more detailled error information must be implemented"; // construct top-level dynamic #! dyn = build_block (NF make_start_node_index) (NF { gdid & gdid.di_dummy = ""}) #! (_,files) = close_dynamic_as_binary databaseFile files # (_,files) = fclose userFile files = (ok,dyn,files) writeDynamic :: String Dynamic *f -> (Bool,*f) | FileSystem f /* this version of writeDynamic writes the dynamic with an md5 checksum as name in the "dynamicDatabaseDirectory" directory and writes a file for the user in the required directory with extension "dyn", which is the user's 'link' to the dynamic. That file contains only the name of the real dynamic file. matyas */ writeDynamic file_name dynamic_value files # file_name = create_dynamic_file_name file_name /* matyas */ # (ok,encoded_dynamic) = dynamic_to_string dynamic_value | not ok = (False,files) # contentOfSystemDynamicFile = write_encoded_dynamic encoded_dynamic #databaseFileName = toString (createDynIDFromString contentOfSystemDynamicFile) #databaseFilePath_as_string = (dynamicDatabaseDirectory+++databaseFileName) #! (ok,databaseFile,files) = fopen databaseFilePath_as_string FWriteData files | not ok # (_,files) = fclose databaseFile files = (False,files) #! databaseFile = fwrites contentOfSystemDynamicFile databaseFile /* \matyas */ # (ok,files) = fclose databaseFile files | not ok = (False,files) /* matyas */ //giving a "link" file to the user... # (ok,userFile,files)= fopen file_name FWriteData files |not(ok)= (False,files) #userFile= fwrites (databaseFileName+++"\n") userFile //the ID is in that file. //ID in this case is e.g. "af12g42a3aa234ab2f324b34f2345bf5" # (ok,files) = fclose userFile files /* \matyas */ = (ok,files) /* matyas */ //the type of this function is changed. It gives back the string which //will be written in the systemDynamicFile instead of writing it. where // write_encoded_dynamic :: String -> String write_encoded_dynamic {ed_encoded_graph,ed_dynamic_rts_info} // Offset/Size # (s_ed_encoded_graph,ed_encoded_graph) = usize ed_encoded_graph # ed_encoded_graph = WriteLong ed_encoded_graph (DYNAMIC_RTS_INFO_OFFSET - HEADER_SIZE_OFFSET) s_ed_encoded_graph # (s_ed_dynamic_rts_info,ed_dynamic_rts_info) = usize ed_dynamic_rts_info # ed_encoded_graph = WriteLong ed_encoded_graph (DYNAMIC_RTS_INFO_SIZE - HEADER_SIZE_OFFSET) s_ed_dynamic_rts_info = ed_encoded_graph+++ed_dynamic_rts_info /* // this is the part which is not necessary #! file = fwrites ed_encoded_graph file #! file = fwrites ed_dynamic_rts_info file = file */ where s_ed_dynamic_rts_info = size ed_dynamic_rts_info /* \matyas */