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