void ExportToDisk(VxSchemaElement elem, VxSchemaChecksum sum, bool isbackup) { // Make some kind of attempt to run on Windows. string filename = wv.PathJoin(exportdir, elem.type, elem.name); // Make directories Directory.CreateDirectory(Path.GetDirectoryName(filename)); string suffix = ""; if (isbackup) { int i = 1; while(File.Exists(filename + "-" + i)) i++; suffix = "-" + i; } filename += suffix; log.print("Writing {0}\n", filename); File.WriteAllBytes(filename, elem.ToStringWithHeader(sum).ToUTF8()); }
// Reads a file from an on-disk exported schema, and sets the schema // element parameter's text field, if the schema element isn't null. // Returns a new VxSchemaChecksum object containing the checksum. // Returns true if the file passes its MD5 validation. // If it returns false, elem and sum may be set to null. static bool ReadSchemaFile(string filename, string type, string name, out VxSchemaElement elem, out VxSchemaChecksum sum) { elem = null; sum = null; FileInfo fileinfo = new FileInfo(filename); // Read the entire file into memory. C#'s file IO sucks. byte[] bytes = File.ReadAllBytes(filename); // Find the header line int ii; for (ii = 0; ii < bytes.Length; ii++) if (bytes[ii] == '\n') break; if (ii == bytes.Length) return false; // Read the header line Encoding utf8 = Encoding.UTF8; string header = utf8.GetString(bytes, 0, ii).Replace("\r", ""); // Skip the newline if (bytes[ii] == '\n') ii++; // Read the body string body = utf8.GetString(bytes, ii, bytes.Length - ii); elem = VxSchemaElement.create(type, name, body, false); // Parse the header line char[] space = {' '}; string[] headers = header.Split(space, 3); string prefix = headers[0]; string header_md5 = headers.Length >= 2 ? headers[1] : ""; string dbsum = headers.Length >= 3 ? headers[2] : ""; if (prefix != "!!SCHEMAMATIC") return false; // Compute the hash of the rest of the file byte[] md5 = MD5.Create().ComputeHash(bytes, ii, (int)fileinfo.Length - ii); string content_md5 = md5.ToHex().ToLower(); IEnumerable<ulong> sumlist; // If the MD5 sums don't match, we want to make it obvious that the // database and local file aren't in sync, so we don't load any actual // checksums. if (String.Compare(header_md5, content_md5, true) == 0) { string errctx = wv.fmt("Error while reading file {0}: ", filename); sumlist = VxSchemaChecksum.ParseSumString(dbsum, errctx); } else { log.print(WvLog.L.Info, "Checksum mismatch for {0}\n", filename); sumlist = new List<ulong>(); } sum = new VxSchemaChecksum(elem.key, sumlist); return true; }