}// ----------------------------------------- /// <summary> /// Load a previously saved JSON settings file /// </summary> /// <param name="file">The JSON file to load</param> /// <returns>Success 1 OK,0 ERROR</returns> public bool loadJson(string file) { if (!File.Exists(file)) { ERROR = "File:" + file + "does not exist"; return(false); } string loadedJSONText; try{ loadedJSONText = File.ReadAllText(file); } catch (IOException e) { ERROR = e.ToString(); return(false); } catch (UnauthorizedAccessException) { ERROR = "Unauthorized Access"; return(false); } // -- JSON Get var js = new JavaScriptSerializer(); // Note: Should never throw error because it was created internally Dictionary <string, object> data = js.Deserialize <Dictionary <string, object> >(loadedJSONText); // -- Version check, defaults to 1 if field missing int versionLoaded = 1; if (data.ContainsKey("version")) { versionLoaded = int.Parse(data["version"].ToString()); } // -- Backwards Compatibility :: switch (versionLoaded) { case 1: // Convert V1 to V2 int ssize = (int)data["sectorSize"]; foreach (Dictionary <string, object> t in (ArrayList)data["tracks"]) { t["diskFileSize"] = (int)t["sectorSize"] * ssize; t["diskFile"] = null; t["isData"] = (bool)!((t["type"] as string) == "AUDIO"); } goto case 2; case 2: // Convert V2 to V3 string CDT = null; // If any is data, then set to the data type. int diskFiles = 0; // Count tracks with diskfiles set bool anyAudio = false; // Is there any audio track? foreach (Dictionary <string, object> t in (ArrayList)data["tracks"]) { t["trackType"] = t["type"]; t["indexes"] = t["indexAr"]; // Array is the same t["storedFileName"] = t["filename"]; t["byteSize"] = t["diskFileSize"]; t["md5"] = ""; // New field if (!anyAudio && t["trackType"].ToString() == "AUDIO") { anyAudio = true; } // Capture the first data format of any track: if ((bool)t["isData"] && CDT == null) { CDT = t["trackType"].ToString(); } if (t["diskFile"] != null) { diskFiles++; } } // New/Renamed properties : data["audio"] = anyAudio ? "??? kbps" : ""; data["cdType"] = CDT ?? "AUDIO"; data["totalSize"] = data["imageSize"]; data["multiFile"] = (diskFiles > 1) && (diskFiles == (data["tracks"] as ArrayList).Count); break; default: break; } // -- At this point the data is properly in v3 format. // -- Read tracks :: tracks = new List <CueTrack>(); foreach (Dictionary <string, object> t in (ArrayList)data["tracks"]) { var tr = new CueTrack((int)t["trackNo"], t["trackType"].ToString()); tr.sectorSize = (int)t["sectorSize"]; tr.sectorStart = (int)t["sectorStart"]; tr.byteSize = (int)t["byteSize"]; tr.pregapMinutes = (int)t["pregapMinutes"]; tr.pregapSeconds = (int)t["pregapSeconds"]; tr.pregapMillisecs = (int)t["pregapMillisecs"]; tr.storedFileName = (string)t["storedFileName"]; tr.md5 = (string)t["md5"]; foreach (Dictionary <string, object> ind in (ArrayList)t["indexes"]) { tr.addIndex((int)ind["no"], (int)ind["minutes"], (int)ind["seconds"], (int)ind["millisecs"]); } tracks.Add(tr); } // -- cd info data :: CD_TITLE = data["cdTitle"].ToString(); CD_TYPE = data["cdType"].ToString(); CD_TOTAL_SIZE = (int)data["totalSize"]; CD_AUDIO_QUALITY = data["audio"].ToString(); MULTIFILE = (bool)data["multiFile"]; SECTOR_SIZE = (int)data["sectorSize"]; // Some Checks :: if (tracks[0].byteSize == 0) { calculateTracksByteSize(); // Single File Multi Tracks } if (tracks.Count > 1 && tracks[1].sectorStart == 0) { calculateTracksSectorStart(); // Multi File Multi Track } return(true); }// -----------------------------------------
}// ----------------------------------------- /* * Reads a CUE file, line by line, used in load(); * CUE SHEET INFO : http://wiki.hydrogenaud.io/index.php?title=Cue_sheet * This is not a complete Cue Parser, just a basic one * that can read game disks. A track of data and tracks of CDDA audio. */ int cue_parser(string line) { // Get FILE image name if (line.ToUpper().StartsWith("FILE")) { openTrack = null; // Close any open Track // Try to get the filename within the quotes after FILE var ff = Regex.Split(line, "[\"\']"); if (ff.Length < 3) { // Because Array should be like [] {"FILE","GAME NAME.BIN", ... ,"BINARY"} ERROR = "Could not get filename"; return(0); } // [SAFEGUARD] if (!new string[] { "BINARY", "WAVE", "MP3" }.Contains(ff.Last().ToUpper().Trim())) { ERROR = "Unsupported File Type, or identifier missing. Supported = {BINARY,WAVE,MP3}"; return(0); } // First and last elements are not needed openFile = string.Join("'", ff, 1, ff.Length - 2); return(1); // No reason to check for other cases } // -- FILE // Get Track NO and track TYPE if (line.ToUpper().StartsWith("TRACK")) { openTrack = null; // Close any open Track Match m = Regex.Match(line, @"^\s*TRACK\s+(\d+)\s+(\S+)", RegexOptions.IgnoreCase); if (m.Success) { int trackNo = int.Parse(m.Groups[1].Value); string trackType = m.Groups[2].Value.ToUpper(); // [SAFEGUARD] Check to see if Track Type is valid if (getSectorsByDataType(trackType) == 0) { ERROR = "Unsupported TRACK type:" + trackType; return(0); } // [SAFEGUARD] Check to see if the trackNO is already defined in the tracks foreach (var t in tracks) { if (t.trackNo == trackNo) { ERROR = "TRACK Number already defined"; return(0); } } CueTrack tr = new CueTrack(trackNo, trackType); openTrack = tr; tr.trackFile = openFile; openFile = null; tracks.Add(tr); } else { ERROR = "Cannot parse TRACK line"; return(0); } return(1); } // -- TRACK // -- if (line.ToUpper().StartsWith("INDEX")) { if (openTrack == null) { ERROR = "INDEX not inside a TRACK"; return(0); } Match m = Regex.Match(line, @"^\s*INDEX\s+(\d+)\s+(\d{1,2}):(\d{1,2}):(\d{1,2})", RegexOptions.IgnoreCase); if (m.Success) { var indexNo = int.Parse(m.Groups[1].Value); if (openTrack.indexExists(indexNo)) { ERROR = String.Format("Duplicate Index on track {0}", openTrack.trackNo); return(0); } openTrack.addIndex(indexNo, int.Parse(m.Groups[2].Value), int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value)); } else { ERROR = "Cannot parse INDEX line"; return(0); } return(1); } // -- INDEX // -- if (line.ToUpper().StartsWith("PREGAP")) { if (openTrack == null) { ERROR = "INDEX not inside a TRACK"; return(0); } Match m = Regex.Match(line, @"^\s*PREGAP\s+(\d{1,2}):(\d{1,2}):(\d{1,2})", RegexOptions.IgnoreCase); if (m.Success) { openTrack.setGap(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value), int.Parse(m.Groups[3].Value)); } else { ERROR = "Cannot parse PREGAP line"; return(0); } return(1); } // - PREGAP // -- // Title can be either at ROOT is used as the CD title, or inside a Track if (line.ToUpper().StartsWith("TITLE")) { // Currently only used as CD title, and only works with titles inside "" if (openTrack == null) { Match m = Regex.Match(line, ".+\"(.+)\"$"); if (m.Success) { CD_TITLE = m.Value; } else { ERROR = "Can't parse TITLE"; return(0); } } } // -- TITLE // Skip Comments // if (line.ToUpper().StartsWith("REM")) return 1; -- Everything else will return 1 return(1); }// -----------------------------------------