/// <summary> /// Can automatically decompress XML if it is compressed /// </summary> /// <param name="raw"></param> /// <returns></returns> public static string AutoXml(string raw) { try { //validation if (!string.IsNullOrEmpty(raw)) { //test for validity var isAlreadyXml = IsValidXml(raw); //run accordingly if (isAlreadyXml) { return(raw); } else { //decompression may now be required var decompressed = GZipCompressor.DecompressString(raw); //test for XML validity if (IsValidXml(decompressed)) { return(decompressed); } } } } catch (Exception) { //nothing } //default return(@""); }
/// <summary> /// Create a new record from a GZipped Base64 string /// </summary> /// <param name="compressedRaw">The raw representation of the PxzRecord to load</param> /// <returns></returns> public static PxzRecord FromRawForm(string compressedRaw) { var decompressedXml = GZipCompressor.DecompressString(compressedRaw); return(Serializers.StringToPxzRecord(decompressedXml)); }
/// <summary> /// Load an existing PXZ file from disk /// </summary> /// <param name="path">The file to load</param> public void Load(string path) { try { //can't load a non-existent file if (!System.IO.File.Exists(path)) { return; } //clear all lists and assign the new location Location = path; Records.Clear(); FileIndex.RecordReference.Clear(); //item names to load const string idxName = @"index"; const string dirName = @"records"; //read the PXZ file into memory using var zip = ZipFile.Read(path); //load the raw file index into memory var idxFile = zip[idxName]; //the index can't be null! if (idxFile == null) { if (!ParseSilent) { UIMessages.Error(@"PXZ index couldn't be found or it isn't valid"); } return; } //raw gzip index string (base64) string idxString; //extract and save the index to a new stream using (var idxStream = new MemoryStream()) { idxFile.Extract(idxStream); //ERROR LINE idxStream.Position = 0; idxString = new StreamReader(idxStream).ReadToEnd(); } //Gzip decompress var idxByte = GZipCompressor.DecompressString(idxString); var index = Serializers.StringToPxzIndex(idxByte); //if this gets flipped to true, it's potentially bad news var tamperedWith = false; //load all records into memory foreach (var recFile in index.RecordReference.Select( r => $"{dirName}/{r.StoredName}") .Select(recName => zip[recName])) { //byte stream for the raw record using var recStream = new MemoryStream(); //grab data from the file and store in memory recFile.Extract(recStream); recStream.Position = 0; //open a new reader for the memory block using var reader = new StreamReader(recStream); //jump through the memory stream and turn it into Base64 var recRaw = reader.ReadToEnd(); //serialise rawXml into a usable PxzRecord var rec = PxzRecord.FromRawForm(recRaw); //sync Encrypted with ProtectedRecord (native object can't do this) rec.ProtectedRecord = rec.Content.Encrypted; //verify checksums on the record to ensure authenticity tamperedWith = !rec.ChecksumValid; //finally, index and store the record Records.Add(rec); FileIndex.RecordReference.Add(rec.Header.Naming); } //apply new values FileIndex = index; //check authenticity flag, and warn if it's been altered if (tamperedWith) { if (!ParseSilent) { UIMessages.Warning("Content has been modified\n\nThe MD5 checksums stored do not match the checksums calculated, which is an indication that the contents may have been altered outside of the PXZ handler. The file will continue loading after you close this message."); } } } catch (Exception ex) { if (!ParseSilent) { UIMessages.Error(ex.ToString()); } } }