WIP: Refactoring file parser
This commit is contained in:
		@ -9,6 +9,7 @@
 | 
				
			|||||||
plugins {
 | 
					plugins {
 | 
				
			||||||
    // Apply the application plugin to add support for building a CLI application in Java.
 | 
					    // Apply the application plugin to add support for building a CLI application in Java.
 | 
				
			||||||
    id 'application'
 | 
					    id 'application'
 | 
				
			||||||
 | 
					    id 'checkstyle'
 | 
				
			||||||
    id 'org.openjfx.javafxplugin' version '0.0.13'
 | 
					    id 'org.openjfx.javafxplugin' version '0.0.13'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,52 +1,24 @@
 | 
				
			|||||||
package school_project;
 | 
					package school_project.Parsers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import school_project.Map;
 | 
				
			||||||
 | 
					import school_project.Piece;
 | 
				
			||||||
import school_project.Utils.Bitwise;
 | 
					import school_project.Utils.Bitwise;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MapParser {
 | 
					public class BinaryParser implements FileParser {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public Map getLevel(File file) throws IOException {
 | 
				
			||||||
     * Parse the file and create a Map with its shape and pieces setup
 | 
					 | 
				
			||||||
     * @param file file to parse
 | 
					 | 
				
			||||||
     * @return Map Object parsed with file data
 | 
					 | 
				
			||||||
     * @see "TODO: Add Specification when done"
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static Map ParseMapFile(File file) throws IllegalArgumentException, IllegalAccessException, IOException {
 | 
					 | 
				
			||||||
        Map ret;
 | 
					        Map ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Get the file and check that this file exists and can be read
 | 
					 | 
				
			||||||
        FileInputStream fileStream = new FileInputStream(file);
 | 
					        FileInputStream fileStream = new FileInputStream(file);
 | 
				
			||||||
        if(!file.isFile()) throw new IllegalArgumentException("The argument should be a file");
 | 
					 | 
				
			||||||
        if(!file.canRead()) throw new IllegalAccessException("This file can't be read");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Read the file an array of byte, then look for the HEADER (SMS) and then the FOOTER (SME)
 | 
					        byte[] level_data = ExtractLevelData(fileStream);
 | 
				
			||||||
        // Then Put everything that is in between in level_data[]
 | 
					 | 
				
			||||||
        byte[] bytes = fileStream.readAllBytes();
 | 
					 | 
				
			||||||
        int start_position = 0, end_position = 0;
 | 
					 | 
				
			||||||
        for (int i = 0; i < bytes.length; i++) {
 | 
					 | 
				
			||||||
            if(bytes[i] == 83 && bytes[i+1] == 77 && bytes[i+2] == 83){ // SMS
 | 
					 | 
				
			||||||
                start_position = i+3;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (int i = start_position; i < bytes.length; i++) {
 | 
					        ret = new Map(ExtractMapFromLevelData(level_data));
 | 
				
			||||||
            if(bytes[i] == 83 && bytes[i+1] == 77 && bytes[i+2] == 69){ // SME
 | 
					 | 
				
			||||||
                end_position = i;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        byte[] level_data = Arrays.copyOfRange(bytes, start_position, end_position);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Get the 2 first byte as the map width and height
 | 
					 | 
				
			||||||
        // Then get the map data. This map data is every bit of the byte that represent either a true if it is a 1 or false if it is a 0
 | 
					 | 
				
			||||||
        int map_width = level_data[0], map_height = level_data[1];
 | 
					 | 
				
			||||||
        byte[] map_data = Arrays.copyOfRange(level_data, 2, 2 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0));
 | 
					 | 
				
			||||||
        boolean[][] map_matrix = BuildMatrixFromBytes(map_width, map_height, map_data);
 | 
					 | 
				
			||||||
        ret = new Map(map_matrix);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: 3/18/23 Cursor: have to make this into a method 
 | 
				
			||||||
        // Get the amount of pieces
 | 
					        // Get the amount of pieces
 | 
				
			||||||
        // For each of these pieces, get the size of the piece on 1 octet, 4 byte are for width then 4 byte are for height
 | 
					        // For each of these pieces, get the size of the piece on 1 octet, 4 byte are for width then 4 byte are for height
 | 
				
			||||||
        // the same method as the map is used to get the piece shape.
 | 
					        // the same method as the map is used to get the piece shape.
 | 
				
			||||||
@ -67,6 +39,45 @@ public class MapParser {
 | 
				
			|||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the Map Matrix out of the level data
 | 
				
			||||||
 | 
					     * @param level_data full data of the level without header and footer
 | 
				
			||||||
 | 
					     * @return boolean matrix of the map
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static boolean[][] ExtractMapFromLevelData(byte[] level_data){
 | 
				
			||||||
 | 
					        int map_width = level_data[0], map_height = level_data[1];
 | 
				
			||||||
 | 
					        byte[] map_data = Arrays.copyOfRange(level_data, 2, 2 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0));
 | 
				
			||||||
 | 
					        return BuildMatrixFromBytes(map_width, map_height, map_data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Extract Level data from file content
 | 
				
			||||||
 | 
					     * @param fileStream
 | 
				
			||||||
 | 
					     * @return Level data as an array of byte
 | 
				
			||||||
 | 
					     * @throws IOException Expected if we can't read the file
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static byte[] ExtractLevelData(FileInputStream fileStream) throws IOException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        byte[] bytes = fileStream.readAllBytes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int start_position = 0, end_position = 0;
 | 
				
			||||||
 | 
					        for (int i = 0; i < bytes.length; i++) {
 | 
				
			||||||
 | 
					            if(bytes[i] == 83 && bytes[i+1] == 77 && bytes[i+2] == 83){ // SMS
 | 
				
			||||||
 | 
					                start_position = i+3;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = start_position; i < bytes.length; i++) {
 | 
				
			||||||
 | 
					            if(bytes[i] == 83 && bytes[i+1] == 77 && bytes[i+2] == 69){ // SME
 | 
				
			||||||
 | 
					                end_position = i;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Arrays.copyOfRange(bytes, start_position, end_position);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Build a boolean Matrix From a byte array
 | 
					     * Build a boolean Matrix From a byte array
 | 
				
			||||||
     * Each Byte is composed of 8 bit, each bit is 1 or 0
 | 
					     * Each Byte is composed of 8 bit, each bit is 1 or 0
 | 
				
			||||||
							
								
								
									
										23
									
								
								app/src/main/java/school_project/Parsers/FileParser.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/src/main/java/school_project/Parsers/FileParser.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					package school_project.Parsers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import school_project.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.FileNotFoundException;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface FileParser {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Parse the file and create a Map with its shape and pieces setup
 | 
				
			||||||
 | 
					     * Ignore the rest of the file! (ie: save data)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param file file to parse
 | 
				
			||||||
 | 
					     * @return Map Object parsed with file data
 | 
				
			||||||
 | 
					     * @see "TODO: Add Specification when done"
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Map getLevel(File file) throws IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: 3/18/23 tonitch: Add getSavedData, for when piece could be added to map file
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					package school_project.Parsers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.NotSerializableException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This is used to find the right parser to parser a save/level file.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * <p>
 | 
				
			||||||
 | 
					 * Mor file format can be added in the future by adding a new class that implement parser and making it recognisable by
 | 
				
			||||||
 | 
					 * the CreateParser class
 | 
				
			||||||
 | 
					 * </p>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author tonitch
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class FileParserFactory {
 | 
				
			||||||
 | 
					    public static FileParser createParser(File file) throws NotSerializableException{
 | 
				
			||||||
 | 
					        if(isBinaryFile(file))
 | 
				
			||||||
 | 
					            return new BinaryParser();
 | 
				
			||||||
 | 
					        else if (isTextFile(file))
 | 
				
			||||||
 | 
					            return new TxtParser();
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            throw new NotSerializableException("This file format is not supported");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if the file is a binary file suited for parsing
 | 
				
			||||||
 | 
					     * @return true if it is a binary File
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static boolean isBinaryFile(File file){
 | 
				
			||||||
 | 
					        // TODO: 3/18/23
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if the file is a text file
 | 
				
			||||||
 | 
					     * @return true if it is a text File
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static boolean isTextFile(File file){
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					        // TODO: 3/18/23
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								app/src/main/java/school_project/Parsers/TxtParser.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/src/main/java/school_project/Parsers/TxtParser.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					package school_project.Parsers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import school_project.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class TxtParser implements FileParser{
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Map getLevel(File file) {
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					        // TODO: 3/18/23  
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user