/// <summary> /// Builds a CDB file from a CDB-format <see cref="Stream"/>, excluding /// records with data matching keys in `ignoreCdb'. /// </summary> /// <param name="stream">The <see cref="Stream"/> to read from.</param> /// <param name="cdbFilepath">The CDB file to create.</param> /// <param name="tempFilepath">The temporary file to use when creating the /// CDB file.</param> /// <param name="ignoreCdb">If the data for an entry matches a key in this /// CDB file, the entry will not be added to the new file.</param> /// <exception cref="System.IO.IOException">if an error occurs rebuilding the /// CDB file.</exception> public static void Make(Stream stream, string cdbFilepath, string tempFilepath, CdbReader ignoreCdb) { /* Create the CdbMake object. */ using (CdbWriter cdbMake = new CdbWriter(tempFilepath)) { /* Process the data file. */ int ch; while (true) { /* Read and process a byte. */ ch = stream.ReadByte(); if (ch == -1) { break; } if (ch == '\n') { break; } if (ch != '+') { throw new ArgumentException("input file not in correct format"); } /* Get the key length. */ int klen = 0; for (;;) { ch = stream.ReadByte(); if (ch == ',') { break; } if ((ch < '0') || (ch > '9')) { throw new ArgumentException("input file not in correct format"); } if (klen > 429496720) { throw new ArgumentException("key length is too big"); } klen = klen * 10 + (ch - '0'); } /* Get the data length. */ int dlen = 0; for (;;) { ch = stream.ReadByte(); if (ch == ':') { break; } if ((ch < '0') || (ch > '9')) { throw new ArgumentException("input file not in correct format"); } if (dlen > 429496720) { throw new ArgumentException("data length is too big"); } dlen = dlen * 10 + (ch - '0'); } /* Read in the key. */ byte[] key = new byte[klen]; for (int i = 0; i < klen; i++) { /* Read the character. */ ch = stream.ReadByte(); if (ch == -1) { throw new ArgumentException("input file is truncated"); } /* Store the character. */ key[i] = unchecked ((byte)(ch & 0xff)); } /* Read key/data separator characters. */ ch = stream.ReadByte(); if (ch != '-') { throw new ArgumentException("input file not in correct format"); } ch = stream.ReadByte(); if (ch != '>') { throw new ArgumentException("input file not in correct format"); } /* Read in the data. */ byte[] data = new byte[dlen]; for (int i = 0; i < dlen; i++) { /* Read the character. */ ch = stream.ReadByte(); if (ch == -1) { throw new ArgumentException("input file is truncated"); } /* Store the character. */ data[i] = unchecked ((byte)(ch & 0xff)); } /* Add the key/data pair to the database if it is not in * ignoreCdb. */ if ((ignoreCdb == null) || (ignoreCdb.Find(data) == null)) { cdbMake.Add(key, data); } /* Read the terminating LF. */ ch = stream.ReadByte(); if (ch != '\n') { throw new ArgumentException("input file not in correct format"); } } } /* Rename the data file. */ File.Move(tempFilepath, cdbFilepath); }
/// <summary> /// Builds a CDB file from a CDB-format text file, excluding records /// with data matching keys in `ignoreCdb'. /// </summary> /// <param name="dataFilePath">The CDB data file to read.</param> /// <param name="cdbFilePath">The CDB file to create.</param> /// <param name="tempFilePath">The temporary file to use when creating the /// CDB file.</param> /// <param name="ignoreCdb">If the data for an entry matches a key in this /// CDB file, the entry will not be added to the new file.</param> /// <exception cref="System.IO.IOException">if an error occurs rebuilding the /// CDB file.</exception> public static void Make(string dataFilePath, string cdbFilePath, string tempFilePath, CdbReader ignoreCdb) { /* Open the data file. */ using (FileStream fileStream = new FileStream(dataFilePath, FileMode.CreateNew, FileAccess.ReadWrite)) { /* Build the database. */ Make(fileStream, cdbFilePath, tempFilePath, ignoreCdb); } }