1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Mork Reader.
16 *
17 * The Initial Developer of the Original Code is
18 * Google Inc.
19 * Portions created by the Initial Developer are Copyright (C) 2006
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *   Brian Ryner <bryner@brianryner.com> (original author)
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39// Source:
40// http://mxr.mozilla.org/firefox/source/db/morkreader/nsMorkReader.h
41
42#ifndef CHROME_BROWSER_IMPORTER_MORK_READER_H_
43#define CHROME_BROWSER_IMPORTER_MORK_READER_H_
44#pragma once
45
46#include <fstream>
47#include <map>
48#include <string>
49#include <vector>
50
51#include "base/basictypes.h"
52
53class FilePath;
54class ImporterBridge;
55
56// The nsMorkReader object allows a consumer to read in a mork-format
57// file and enumerate the rows that it contains.  It does not provide
58// any functionality for modifying mork tables.
59//
60// References:
61//  http://www.mozilla.org/mailnews/arch/mork/primer.txt
62//  http://www.mozilla.org/mailnews/arch/mork/grammar.txt
63//  http://www.jwz.org/hacks/mork.pl
64class MorkReader {
65 public:
66  // The IDString type has built-in storage for the hex string representation
67  // of a 32-bit row id or atom map key, plus the terminating null.
68  // We use STL string here so that is can be operated with STL containers.
69  typedef std::string IDString;
70
71  // Lists the contents of a series of columns.
72  typedef std::vector<std::string> ColumnDataList;
73
74  // A MorkColumn describes a column of the table.
75  struct MorkColumn {
76    MorkColumn(const IDString& i, const std::string& n) : id(i), name(n) { }
77
78    IDString id;
79    std::string name;
80  };
81  typedef std::vector<MorkColumn> MorkColumnList;
82
83  // The key for each row is the identifier for it, and the data is a pointer
84  // to an array for each column.
85  typedef std::map<IDString, ColumnDataList*> RowMap;
86
87  typedef RowMap::const_iterator iterator;
88
89  MorkReader();
90  ~MorkReader();
91
92  // Read in the given mork file. Returns true on success.
93  // Note: currently, only single-table mork files are supported
94  bool Read(const FilePath& filename);
95
96  // Returns the list of columns in the current table.
97  const MorkColumnList& columns() const { return columns_; }
98
99  // Get the "meta row" for the table.  Each table has at most one meta row,
100  // which records information about the table.  Like normal rows, the
101  // meta row contains columns in the same order as returned by columns().
102  // Returns null if there is no meta row for this table.
103  const ColumnDataList& meta_row() const { return meta_row_; }
104
105  // Normalizes the cell value (resolves references to the value map).
106  // |value| is modified in-place.
107  void NormalizeValue(std::string* value) const;
108
109  // Allow iteration over the table cells using STL iterators. The iterator's
110  // |first| will be the row ID, and the iterator's |second| will be a
111  // pointer to a ColumnDataList containing the cell data.
112  iterator begin() const { return table_.begin(); }
113  iterator end() const { return table_.end(); }
114
115 private:
116  // A convenience typedef for an ID-to-string mapping.
117  typedef std::map<IDString, std::string> StringMap;
118
119  // A convenience typdef for an ID-to-index mapping, used for the column index
120  // hashtable.
121  typedef std::map<IDString, int> IndexMap;
122
123  // Parses a line of the file which contains key/value pairs (either
124  // the column map or the value map). The starting line is parsed starting at
125  // the given index. Additional lines are read from stream_ if the line ends
126  // mid-entry. The pairs are added to the map.
127  bool ParseMap(const std::string& first_line,
128                size_t start_index,
129                StringMap* map);
130
131  // Parses a line of the file which contains a table or row definition,
132  // starting at the given offset within the line.  Additional lines are read
133  // from |stream_| of the line ends mid-row.  An entry is added to |table_|
134  // using the row ID as the key, which contains a column array for the row.
135  // The supplied column hash table maps from column id to an index in
136  // |columns_|.
137  void ParseTable(const std::string& first_line,
138                  size_t start_index,
139                  const IndexMap* column_map);
140
141  // Reads a single logical line from mStream into aLine.
142  // Any continuation lines are consumed and appended to the line.
143  bool ReadLine(std::string* line);
144
145  std::ifstream stream_;
146
147  // Lists the names of the columns for the table.
148  MorkColumnList columns_;
149
150  // Maps hex string IDs to the corrsponding names.
151  StringMap value_map_;
152
153  // The data of the columns in the meta row.
154  ColumnDataList meta_row_;
155
156  // The contents of the mork database. This array pointer is owned by this
157  // class and must be deleted.
158  RowMap table_;
159};
160
161// ImportHistoryFromFirefox2 is the main entry point to the importer.
162void ImportHistoryFromFirefox2(const FilePath& file, ImporterBridge* bridge);
163
164#endif  // CHROME_BROWSER_IMPORTER_MORK_READER_H_
165