1 /*
2  * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
3  * Copyright (c) 1999 - 2003 Simon Peter <dn.tlp@gmx.net>, et al.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * database.h - AdPlug database class
20  * Copyright (c) 2002 Riven the Mage <riven@ok.ru>
21  * Copyright (c) 2002, 2003 Simon Peter <dn.tlp@gmx.net>
22  */
23 
24 #ifndef H_ADPLUG_DATABASE
25 #define H_ADPLUG_DATABASE
26 
27 #include <iostream>
28 #include <string>
29 #include <binio.h>
30 
31 class CAdPlugDatabase
32 {
33 public:
34   class CKey
35   {
36   public:
37     unsigned short	crc16;
38     unsigned long	crc32;
39 
CKey()40     CKey() {};
41     CKey(binistream &in);
42 
43     bool operator==(const CKey &key);
44 
45   private:
46     void make(binistream &in);
47   };
48 
49   class CRecord
50   {
51   public:
52     typedef enum { Plain, SongInfo, ClockSpeed } RecordType;
53 
54     RecordType	type;
55     CKey	key;
56     std::string	filetype, comment;
57 
58     static CRecord *factory(RecordType type);
59     static CRecord *factory(binistream &in);
60 
CRecord()61     CRecord() {}
~CRecord()62     virtual ~CRecord() {}
63 
64     void write(binostream &out);
65 
66     bool user_read(std::istream &in, std::ostream &out);
67     bool user_write(std::ostream &out);
68 
69   protected:
70     virtual void read_own(binistream &in) = 0;
71     virtual void write_own(binostream &out) = 0;
72     virtual unsigned long get_size() = 0;
73     virtual bool user_read_own(std::istream &in, std::ostream &out) = 0;
74     virtual bool user_write_own(std::ostream &out) = 0;
75   };
76 
77   CAdPlugDatabase();
78   ~CAdPlugDatabase();
79 
80   bool	load(std::string db_name);
81   bool	load(binistream &f);
82   bool	save(std::string db_name);
83   bool	save(binostream &f);
84 
85   bool	insert(CRecord *record);
86 
87   void	wipe(CRecord *record);
88   void	wipe();
89 
90   CRecord *search(CKey const &key);
91   bool lookup(CKey const &key);
92 
93   CRecord *get_record();
94 
95   bool	go_forward();
96   bool	go_backward();
97 
98   void	goto_begin();
99   void	goto_end();
100 
101 private:
102   static const unsigned short hash_radix;
103 
104   class DB_Bucket
105   {
106   public:
107     unsigned long	index;
108     bool		deleted;
109     DB_Bucket		*chain;
110 
111     CRecord		*record;
112 
113     DB_Bucket(unsigned long nindex, CRecord *newrecord, DB_Bucket *newchain = 0);
114     ~DB_Bucket();
115   };
116 
117   DB_Bucket	**db_linear;
118   DB_Bucket	**db_hashed;
119 
120   unsigned long	linear_index, linear_logic_length, linear_length;
121 
122   unsigned long make_hash(CKey const &key);
123 };
124 
125 class CPlainRecord: public CAdPlugDatabase::CRecord
126 {
127 public:
CPlainRecord()128   CPlainRecord() { type = Plain; }
129 
130 protected:
read_own(binistream & in)131   virtual void read_own(binistream &in) {}
write_own(binostream & out)132   virtual void write_own(binostream &out) {}
get_size()133   virtual unsigned long get_size() { return 0; }
user_read_own(std::istream & in,std::ostream & out)134   virtual bool user_read_own(std::istream &in, std::ostream &out) { return true; }
user_write_own(std::ostream & out)135   virtual bool user_write_own(std::ostream &out) { return true; }
136 };
137 
138 class CInfoRecord: public CAdPlugDatabase::CRecord
139 {
140 public:
141   std::string	title;
142   std::string	author;
143 
144   CInfoRecord();
145 
146 protected:
147   virtual void read_own(binistream &in);
148   virtual void write_own(binostream &out);
149   virtual unsigned long get_size();
150   virtual bool user_read_own(std::istream &in, std::ostream &out);
151   virtual bool user_write_own(std::ostream &out);
152 };
153 
154 class CClockRecord: public CAdPlugDatabase::CRecord
155 {
156 public:
157   float	clock;
158 
159   CClockRecord();
160 
161 protected:
162   virtual void read_own(binistream &in);
163   virtual void write_own(binostream &out);
164   virtual unsigned long get_size();
165   virtual bool user_read_own(std::istream &in, std::ostream &out);
166   virtual bool user_write_own(std::ostream &out);
167 };
168 
169 #endif
170