1 /*
2  *  Copyright (C) 2005-2007 Christophe Fergeau
3  *
4  *
5  *  The code contained in this file is free software; you can redistribute
6  *  it and/or modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either version
8  *  2.1 of the License, or (at your option) any later version.
9  *
10  *  This file 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 code; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  iTunes and iPod are trademarks of Apple
20  *
21  *  This product is not supported/written/published by Apple!
22  *
23  * $Id$
24  */
25 
26 
27 #ifndef DB_PARSER_H
28 #define DB_PARSER_H
29 
30 #include <glib.h>
31 
32 struct _MHeader {
33 	unsigned char header_id[4];
34 	gint32 header_len;
35 };
36 
37 typedef struct _MHeader MHeader;
38 
39 struct _MhlHeader {
40 	unsigned char header_id[4];
41 	gint32 header_len;
42 	gint32 num_children;
43 	unsigned char padding[];
44 };
45 
46 typedef struct _MhlHeader MhlHeader;
47 
48 
49 typedef struct _MhbdHeader MhbdHeader;
50 typedef struct _ArtworkDB_MhsdHeader ArtworkDB_MhsdHeader;
51 /*typedef struct _MhsdHeader MhsdHeader;*/
52 typedef struct _MhltHeader MhltHeader;
53 typedef struct _MhlpHeader MhlpHeader;
54 typedef struct _MhypHeader MhypHeader;
55 typedef struct _MhipHeader MhipHeader;
56 typedef struct _MhitHeader MhitHeader;
57 typedef struct _ArtworkDB_MhodHeader ArtworkDB_MhodHeader;
58 /*typedef struct _MhodHeader MhodHeader;*/
59 typedef struct _MhfdHeader MhfdHeader;
60 typedef struct _MhliHeader MhliHeader;
61 typedef struct _MhiiHeader MhiiHeader;
62 typedef struct _MhniHeader MhniHeader;
63 typedef struct _MhlaHeader MhlaHeader;
64 typedef struct _MhbaHeader MhbaHeader;
65 typedef struct _MhlfHeader MhlfHeader;
66 typedef struct _MhifHeader MhifHeader;
67 typedef struct _MhiaHeader MhiaHeader;
68 
69 typedef struct _MhitHeader471 MhitHeader471;
70 /* MHOD typedef mess */
71 typedef struct _ArtworkDB_MhodHeaderString ArtworkDB_MhodHeaderString;
72 typedef struct _MhodHeaderString MhodHeaderString;
73 typedef struct _MhodHeaderSmartPlaylistData MhodHeaderSmartPlaylistData;
74 typedef struct _MhodHeaderSmartPlaylistRuleString MhodHeaderSmartPlaylistRuleString;
75 typedef struct _MhodHeaderSmartPlaylistRuleNonString MhodHeaderSmartPlaylistRuleNonString;
76 typedef struct _MhodHeaderSmartPlaylistRule MhodHeaderSmartPlaylistRule;
77 
78 struct _MhbdHeader {
79 	gchar   header_id[4];
80 	guint32 header_len;
81 	guint32 total_len;
82 	guint32 unknown1;
83 	guint32 version;
84 	guint32 num_children;
85 	guint64 db_id;
86 	guint16 platform;
87 	guint16 unk_0x22;
88 	guint64 id_0x24;
89 	guint32 unk_0x2c;
90 	guint16 hashing_scheme;
91 	guchar  unk_0x32[20];
92 	gchar   language_id[2];
93 	guint64 db_persistent_id;
94 	guint32 unk_0x50;
95 	guint32 unk_0x54;
96 	guchar  hash58[20];
97 	gint32  timezone_offset;
98 	guint16 unk_0x70;
99 	guchar  hash72[46];
100 	guint16 audio_language;
101 	guint16 subtitle_language;
102 	guint16 unk_0xa4;
103 	guint16 unk_0xa6;
104 	guint16 unk_0xa8;
105 	guchar align_0xa9;
106 	guchar hashAB[57];
107 	guchar  padding[];
108 } __attribute__((__packed__));
109 
110 enum MhsdIndexType {
111 	MHSD_TRACK_LIST = 1,
112 	MHSD_PLAYLIST_LIST = 2
113 };
114 
115 enum MhsdPhotoIndexType {
116 	MHSD_IMAGE_LIST = 1,
117 	MHSD_ALBUM_LIST = 2,
118 	MHSD_FILE_LIST = 3
119 };
120 
121 struct _ArtworkDB_MhsdHeader {
122 	unsigned char header_id[4];
123 	gint32 header_len;
124 	gint32 total_len;
125         /* Strangely, the following field is only 16 bits long in the
126 	 * ArtworkDB (it's definitely 32 bits in the iTunesDB). This
127 	 * could well be an error with the first generation of mobile
128 	 * phones with iPod support).
129 	 */
130 	gint16 index;
131         gint16 unknown014;
132 	unsigned char padding[];
133 };
134 
135 struct _iTunesDB_MhsdHeader {
136 	unsigned char header_id[4];
137 	gint32 header_len;
138 	gint32 total_len;
139 	gint32 index;
140 	unsigned char padding[];
141 };
142 struct _MhltHeader {
143 	unsigned char header_id[4];
144 	gint32 header_len;
145 	gint32 num_songs;
146 	unsigned char padding[];
147 };
148 
149 struct _MhlpHeader {
150 	unsigned char header_id[4];
151 	gint32 header_len;
152 	gint32 num_playlists;
153 	unsigned char padding[];
154 };
155 
156 struct _MhypHeader {
157 	unsigned char header_id[4];
158 	gint32 header_len;
159 	gint32 total_len;
160 	gint32 num_mhod;
161 	gint32 num_items;
162 	gint32 hidden;
163 	gint32 timestamp;
164 	gint32 playlist_id;
165 	gint32 unknown3;
166 	gint32 unknown4;
167 	gint32 unknown5;
168 	unsigned char padding[];
169 };
170 
171 struct _MhipHeader {
172 	unsigned char header_id[4];
173 	gint32 header_len;
174 	gint32 total_len;
175 	gint32 unknown1;
176 	gint32 format_id;
177 	gint32 unknown2;
178 	gint32 track_id;
179 	gint32 timestamp;
180 	unsigned char padding[];
181 };
182 
183 /* MHIT header as written by iTunes 4.7.1, the added fields (from unknown17 to
184  * the end of the struct) are pretty useless, so we don't use this struct
185  */
186 struct _MhitHeader471 {
187 	unsigned char header_id[4];
188 	gint32 header_len;
189 	gint32 total_len;
190 	gint32 num_mhod;
191 	gint32 track_id;
192 	gint32 visible;
193 	gint32 filetype;
194 	/* FIXME: endianness issue with the order of the 3 fields above ? */
195 	gint16 type;
196 	gchar  compilation;
197 	gchar  rating;
198 	gint32 date_added;
199 	gint32 size;
200 	gint32 length;
201 	gint32 track_number;
202 	gint32 track_total;
203 	gint32 year;
204 	gint32 bitrate;
205 	/* FIXME: endianness issue with the order of the 2 fields above ? */
206 	gint16 unknown;
207 	gint16 sample_rate;
208 	gint32 volume;
209 	gint32 start_time;
210 	gint32 stop_time;
211 	gint32 sound_check;
212 	gint32 play_count;
213 	gint32 play_count2;
214 	gint32 last_played;
215 	gint32 disc_number;
216 	gint32 disc_total;
217 	gint32 user_id;
218 	gint32 last_modified;
219 	gint32 bookmark_time;
220 	gint64 song_id;
221 	/* FIXME: endianness issue with the order of the 5 fields above ? */
222 	gchar  checked;
223 	gchar  app_rating;
224 	gint16 bpm;
225 	gint16 artwork_count;
226 	gint16 unknown9;
227 	gint32 artwork_size;
228 	gint32 unknown11;
229 	gint32 sample_rate2;
230 	gint32 unknown13;
231 	gint32 unknown14;
232 	gint32 unknown15;
233 	gint32 unknown16;
234 	gint32 unknown17;
235 	gint32 unknown18;
236 	gint32 unknown19;
237 	gint64 song_id2;
238 	gint32 unknown20;
239 	gint32 unknown21;
240 	gint32 unknown22;
241 	gint32 unknown23;
242 	gint32 unknown24;
243 	gint32 unknown25;
244 	gint32 unknown26;
245 	gint32 unknown27;
246 	gint32 unknown28;
247 	gint32 unknown29;
248 	gint32 unknown30;
249 	gint32 unknown31;
250 	gint32 unknown32;
251 	gint32 unknown33;
252 	gint32 unknown34;
253 	gint32 unknown35;
254 	gint32 unknown36;
255 	unsigned char padding[];
256 };
257 
258 struct _MhitHeader {
259 	unsigned char header_id[4];
260 	gint32 header_len;
261 	gint32 total_len;
262 	gint32 num_mhod;
263 	gint32 track_id;
264 	gint32 visible;
265 	gint32 filetype;
266 	/* FIXME: endianness issue with the order of the 3 fields above ? */
267 	gint16 type;
268 	gchar  compilation;
269 	gchar  rating;
270 	gint32 date_added;
271 	gint32 size;
272 	gint32 length;
273 	gint32 track_number;
274 	gint32 track_total;
275 	gint32 year;
276 	gint32 bitrate;
277 	/* FIXME: endianness issue with the order of the 2 fields above ? */
278 	gint16 unknown;
279 	gint16 sample_rate;
280 	gint32 volume;
281 	gint32 start_time;
282 	gint32 stop_time;
283 	gint32 sound_check;
284 	gint32 play_count;
285 	gint32 play_count2;
286 	gint32 last_played;
287 	gint32 disc_number;
288 	gint32 disc_total;
289 	gint32 user_id;
290 	gint32 last_modified;
291 	gint32 bookmark_time;
292 	gint64 song_id;
293 	/* FIXME: endianness issue with the order of the 5 fields above ? */
294 	gchar  checked;
295 	gchar  app_rating;
296 	gint16 bpm;
297 	gint16 artwork_count;
298 	gint16 unknown9;
299 	gint32 artwork_size;
300 	gint32 unknown11;
301 	gint32 sample_rate2;
302 	gint32 unknown13;
303 	gint32 unknown14;
304 	gint32 unknown15;
305 	gint32 unknown16;
306 	unsigned char padding[];
307 };
308 
309 enum MhodEncoding {
310 	MHOD_ENCODING_UTF16 = 0,
311 	MHOD_ENCODING_UTF8 = 1
312 };
313 
314 enum MhodType {
315 	MHOD_TYPE_TITLE = 1,
316 	MHOD_TYPE_LOCATION = 2,
317 	MHOD_TYPE_ALBUM = 3,
318 	MHOD_TYPE_ARTIST = 4,
319 	MHOD_TYPE_GENRE = 5,
320 	MHOD_TYPE_FILETYPE = 6,
321 	MHOD_TYPE_EQ_SETTING = 7,
322 	MHOD_TYPE_COMMENT = 8,
323 	MHOD_TYPE_COMPOSER = 12,
324 	MHOD_TYPE_GROUPING = 13,
325 	MHOD_TYPE_SMART_PLAYLIST_DATA = 50,
326 	MHOD_TYPE_SMART_PLAYLIST_RULES = 51,
327 	MHOD_TYPE_LIBRARY_PLAYLIST_INDEX = 52,
328 	MHOD_TYPE_100 = 100
329 };
330 
331 struct _MhodHeader {
332 	unsigned char header_id[4];
333 	gint32 header_len;
334 	gint32 total_len;
335 	gint32 type;
336 	gint32 unknown1;
337 	gint32 unknown2;
338 };
339 
340 struct _ArtworkDB_MhodHeader {
341 	unsigned char header_id[4];
342 	gint32 header_len;
343 	gint32 total_len;
344     /* Strangely, the following field is only 16 bits long in the
345 	 * ArtworkDB (it's definitely 32 bits in the iTunesDB). This
346 	 * could well be an error with the first generation of mobile
347 	 * phones with iPod support).
348 	 */
349 	gint16 type;
350         gint16 unknown014;
351 	gint32 unknown1;
352 	gint32 unknown2;
353 };
354 
355 struct _MhodHeaderString {
356 	unsigned char header_id[4];
357 	gint32 header_len;
358 	gint32 total_len;
359 	gint32 type; /* < 50 */
360 	gint32 unknown1;
361 	gint32 unknown2;
362 	gint32 position;
363 	gint32 string_len;
364 	gint32 unknown3; /* It was thought that this was string encoding:
365 			  * 0 == UTF-16, 1 == UTF-8, however, recent iTunesDB
366 			  * files have had this set to 1 even with UTF-16 strings.
367 			  * Therefore this is definitely incorrect, and the
368 			  * correct meaning has not yet been discovered yet. */
369 	gint32 unknown4;
370 	unsigned char string[];
371 };
372 
373 enum MhodArtworkType {
374 	MHOD_ARTWORK_TYPE_ALBUM_NAME = 1, /* string:    album name (in the Photo Database) */
375 	MHOD_ARTWORK_TYPE_THUMBNAIL  = 2, /* container: thumbnail image */
376 	MHOD_ARTWORK_TYPE_FILE_NAME  = 3, /* string:    file name */
377 	MHOD_ARTWORK_TYPE_IMAGE      = 5  /* container: full resolution image (in the Photo Database) */
378 };
379 
380 struct _ArtworkDB_MhodHeaderString {
381 	unsigned char header_id[4];
382 	gint32 header_len;
383 	gint32 total_len;
384         gint16 type;
385         gint8  unknown13;
386 	gint8  padding_len;
387 	gint32 unknown1;
388 	gint32 unknown2;
389 	gint32 string_len;
390 	gint8 encoding; /* 0,1: string is UTF8, 2: string is UTF16-LE */
391         gint8 unknown5;
392         gint16 unknown6;
393 	gint32 unknown4;
394         gchar  string[];
395 };
396 
397 enum MhodLimitType {
398 	MHOD_LIMIT_MINUTES = 1,
399 	MHOD_LIMIT_MEGABYTES = 2,
400 	MHOD_LIMIT_SONGS = 3,
401 	MHOD_LIMIT_HOURS = 4,
402 	MHOD_LIMIT_GIGABYTES = 5
403 };
404 
405 enum MhodLimitSortType {
406 	MHOD_LIMIT_SORT_RANDOM = 0x02,
407 	MHOD_LIMIT_SORT_SONG_NAME = 0x03,
408 	MHOD_LIMIT_SORT_ALBUM = 0x04,
409 	MHOD_LIMIT_SORT_ARTIST = 0x05,
410 	MHOD_LIMIT_SORT_GENRE = 0x07,
411 	MHOD_LIMIT_SORT_MOST_RECENTLY_ADDED = 0x10,
412 	MHOD_LIMIT_SORT_MOST_OFTEN_PLAYED = 0x14,
413 	MHOD_LIMIT_SORT_MOST_RECENTLY_PLAYED = 0x15,
414 	MHOD_LIMIT_SORT_HIGHEST_RATING = 0x17
415 };
416 
417 struct _MhodHeaderSmartPlaylistData {
418 	unsigned char header_id[4];
419 	gint32 header_len;
420 	gint32 total_len;
421 	gint32 type; /* 50 */
422 	gint32 unknown1;
423 	gint32 unknown2;
424 	gchar  live_update;
425 	gchar  rules_enable;
426 	gchar  limit_enable;
427 	gchar  limit_type;
428 	gchar  limit_sort;
429 	gchar  unknow3[3];
430 	gint32 limit;
431 	gchar  match_checked_only;
432 	gchar  reverse_limit_sort;
433 	unsigned char padding[];
434 };
435 
436 
437 enum MhodSmartPlaylistRuleFieldType {
438 	MHOD_FIELD_SONG_NAME = 0x02,
439 	MHOD_FIELD_ALBUM = 0x03,
440 	MHOD_FIELD_ARTIST = 0x04,
441 	MHOD_FIELD_BITRATE = 0x05,
442 	MHOD_FIELD_SAMPLE_RATE = 0x06,
443 	MHOD_FIELD_YEAR = 0x07,
444 	MHOD_FIELD_GENRE = 0x08,
445 	MHOD_FIELD_KIND = 0x09,
446 	MHOD_FIELD_DATE_MODIFIED = 0x0a,
447 	MHOD_FIELD_TRACK_NUMBER = 0x0b,
448 	MHOD_FIELD_SIZE = 0x0c,
449 	MHOD_FIELD_TIME = 0x0d,
450 	MHOD_FIELD_COMMENT = 0x0e,
451 	MHOD_FIELD_DATE_ADDED = 0x10,
452 	MHOD_FIELD_COMPOSER = 0x12,
453 	MHOD_FIELD_PLAY_COUNT = 0x16,
454 	MHOD_FIELD_LAST_PLAYED = 0x17,
455 	MHOD_FIELD_DISC_NUMBER = 0x18,
456 	MHOD_FIELD_RATING = 0x19,
457 	MHOD_FIELD_COMPILATION = 0x1f,
458 	MHOD_FIELD_BPM = 0x23,
459 	MHOD_FIELD_GROUPING = 0x27,
460 	MHOD_FIELD_PLAYLIST = 0x28
461 };
462 
463 enum MhodSmartPlaylistRuleAction {
464 	MHOD_RULE_IS = 1 << 0,
465 	MHOD_RULE_CONTAINS = 1 << 1,
466 	MHOD_RULE_BEGINS_WITH = 1 << 2,
467 	MHOD_RULE_ENDS_WITH = 1 << 3,
468 	MHOD_RULE_GREATER_THAN = 1 << 4,
469 	MHOD_RULE_GREATER_THAN_OR_EQUAL_TO = 1 << 5,
470 	MHOD_RULE_LESS_THAN = 1 << 6,
471 	MHOD_RULE_LESS_THAN_OR_EQUAL_TO = 1 << 7,
472 	MHOD_RULE_IN_THE_RANGE = 1 << 8,
473 	MHOD_RULE_IS_THE_LAST = 1 << 9,
474 	MHOD_RULE_NOT = 1 << 24,
475 	MHOD_RULE_STRING = 1 << 25
476 };
477 
478 
479 struct _MhodHeaderSmartPlaylistRuleString {
480 	/* Big endian fields */
481 	gint32 field;
482 	gint32 action;
483 	gchar  padding[44];
484 	gint32 string_len;
485 	gchar  string[];
486 };
487 
488 struct _MhodHeaderSmartPlaylistRuleNonString {
489 	/* Big endian fields */
490 	gint32  field;
491 	gint32  action;
492 	gchar   padding[44];
493 	gint32  length;
494 	guint64 from_value;
495 	gint64  from_date;
496 	guint64 from_unit;
497 	guint64 to_value;
498 	gint64  to_date;
499 	guint64 to_unit;
500 	gchar   unknown[20];
501 };
502 
503 struct _MhodHeaderSmartPlaylistRule {
504 	unsigned char header_id[4];
505 	gint32 header_len;
506 	gint32 total_len;
507 	gint32 type; /* 51 */
508 	gint32 unknown1;
509 	gint32 unknown2;
510 	gchar  rules_id[4];
511 	/* Fields stored in big-endian from there */
512 	gint32 unknown5;
513 	gint32 number_of_rules;
514 	gint32 rules_operator;
515 	gchar  padding[120];
516 	union {
517 		MhodHeaderSmartPlaylistRuleString rule_string;
518 		MhodHeaderSmartPlaylistRuleNonString rule_non_string;
519 	} rule;
520 };
521 
522 
523 
524 struct _MhfdHeader {
525 	unsigned char header_id[4];
526 	gint32 header_len;
527 	gint32 total_len;
528 	gint32 unknown1;
529 	gint32 unknown2; /* always seem to be 1 for older databases,
530 			    in an ArtworkDB generated by iTunes 4.9 or
531 			    above, it's 2. Caution: iTunes7 removes
532 			    the whole database if this field is 1 */
533 	gint32 num_children;
534 	gint32 unknown3;
535 	gint32 next_id;
536 	gint64 unknown5;
537 	gint64 unknown6;
538 	gint8  unknown_flag1;
539 	gint8  unknown_flag2;
540 	gint8  unknown_flag3;
541 	gint8  unknown_flag4;
542 	gint32 unknown8;
543 	gint32 unknown9;
544 	gint32 unknown10;
545 	gint32 unknown11;
546 	unsigned char padding[];
547 };
548 
549 struct _MhliHeader {
550 	unsigned char header_id[4];
551 	gint32 header_len;
552 	gint32 num_children;
553 	unsigned char padding[];
554 };
555 
556 struct _MhiiHeader {
557 	unsigned char header_id[4];
558 	gint32 header_len;
559 	gint32 total_len;
560 	gint32 num_children;
561 	gint32 image_id;
562 	gint64 song_id;
563 	gint32 unknown4;
564 	gint32 rating;
565 	gint32 unknown6;
566 	gint32 orig_date;
567 	gint32 digitized_date;
568 	gint32 orig_img_size;
569 	unsigned char padding[];
570 } __attribute__((__packed__));
571 /* I we don't put the 'packed' attribute above, some 64 bit systems
572  * will pad the 64 bit integer to be aligned to an 8-byte boundary.
573  * Hopefully there won't be any systems around that crash when
574  * accessing 64 bit integers not aligned to 8-byte boundaries. */
575 
576 
577 struct _MhniHeader {
578 	unsigned char header_id[4];
579 	gint32 header_len;
580 	gint32 total_len;
581 	gint32 num_children;
582 	gint32 format_id;
583 	gint32 ithmb_offset;
584 	gint32 image_size;
585 	gint16 vertical_padding;
586 	gint16 horizontal_padding;
587 	gint16 image_height;
588 	gint16 image_width;
589 	unsigned char padding[];
590 };
591 
592 struct _MhlaHeader {
593 	unsigned char header_id[4];
594 	gint32 header_len;
595 	gint32 num_children;
596 	unsigned char padding[];
597 };
598 
599 struct _MhbaHeader {
600 	unsigned char header_id[4];
601 	gint32 header_len;
602 	gint32 total_len;
603 	gint32 num_mhods;  /* number of Data Objects in the List,
604 			      probably always 1 */
605 	gint32 num_mhias;  /* number of pictures in the album */
606 	gint32 album_id;   /* starts out at $64 and increments by 1 */
607 	gint32 unk024;     /* unknown, seems to be always 0 */
608 	gint16 unk028;     /* unknown, seems to be always 0 */
609 	guint8 album_type; /* 1 = master photo list ("Photo Library"),
610 			      2 = normal album, sometimes 4 and 5 */
611 	guint8 playmusic;  /* play music during slideshow (from iPhoto setting) */
612 	guint8 repeat;     /* repeat the slideshow (from iPhoto setting) */
613 	guint8 random;     /* show the slides in random order (from iPhoto
614 			      setting) */
615 	guint8 show_titles;/* show slide captions (from iPhoto setting) */
616 	guint8 transition_direction; /* 0=none, 1=left-to-right,
617 			      2=right-to-left, 3=top-to-bottom,
618 			      4=bottom-to-top (from iPhoto setting) */
619 	gint32 slide_duration; /* in seconds (from iPhoto setting) */
620 	gint32 transition_duration; /* in milliseconds (from iPhoto setting) */
621 	gint32 unk044;     /* unknown, seems to always be 0 */
622 	gint32 unk048;     /* unknown, seems to always be 0 */
623 	gint64 song_id;    /* dbid2 of track in iTunesDB to play during
624 			      slideshow (from iPhoto setting) */
625 	gint32 prev_album_id; /* the id of the previous photoalbum */
626 	unsigned char padding[];
627 };
628 
629 struct _MhlfHeader {
630 	unsigned char header_id[4];
631 	gint32 header_len;
632 	gint32 num_files;
633 	unsigned char padding[];
634 };
635 
636 struct _MhifHeader {
637 	unsigned char header_id[4];
638 	gint32 header_len;
639 	gint32 total_len;
640 	gint32 unknown1;
641 	gint32 format_id;
642 	gint32 image_size;
643 	unsigned char padding[];
644 };
645 
646 struct _MhiaHeader {
647 	unsigned char header_id[4];
648 	gint32 header_len;
649 	gint32 total_len; /* probably the size of the header and all child records;
650 			   * as there aren't any child records this is equal to header length */
651 	gint32 unknown1; /* seems to be zero */
652 	guint32 image_id; /* the id of the mhii record this mhia refers to */
653 	unsigned char padding[];
654 };
655 
656 
657 #endif /* PARSE_DB_H */
658