1/* $FreeBSD: src/lib/libc/nls/msgcat.h,v 1.9 2005/02/01 16:04:55 phantom Exp $ */
2
3#ifndef _MSGCAT_H_
4#define _MSGCAT_H_
5
6
7/***********************************************************
8Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
9
10                        All Rights Reserved
11
12Permission to use, copy, modify, and distribute this software and its
13documentation for any purpose and without fee is hereby granted,
14provided that the above copyright notice appear in all copies and that
15both that copyright notice and this permission notice appear in
16supporting documentation, and that Alfalfa's name not be used in
17advertising or publicity pertaining to distribution of the software
18without specific, written prior permission.
19
20ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26SOFTWARE.
27
28If you make any modifications, bugfixes or other changes to this software
29we'd appreciate it if you could send a copy to us so we can keep things
30up-to-date.  Many thanks.
31				Kee Hinckley
32				Alfalfa Software, Inc.
33				267 Allston St., #3
34				Cambridge, MA 02139  USA
35				nazgul@alfalfa.com
36
37******************************************************************/
38
39/*
40 * Magic definitions
41 */
42
43#define MCMagicLen	8
44#define MCMagic		"*nazgul*"
45
46#define MCMajorVer	1
47#define MCMinorVer	0
48
49/* For or'd constants */
50#define MCMakeId(s,m)		(u_int32_t) ( ((unsigned short)s << (sizeof(short)*8)) \
51						 | (unsigned short)m )
52
53
54/*
55 * Critical note here.  Sets and Messages *MUST* be stored in ascending
56 * order.  There are stored that way (by specification) in the original
57 * data file, however in the process of merging in new stuff you might
58 * mix that up.  Don't!  The catget stuff does a binary search and will
59 * totally lose it if these aren't in order (not contiguous mind you, just
60 * in order.  If this turns out to be a major problem this could be enhanced
61 * by adding a 'sorted' flag to the db, and sorting msgs and sets at load
62 * time if things aren't sorted, but I'd like not to have to do that.
63 */
64
65/*
66 * I have tried here to define data structures which can be used
67 * while the catalog is on disk, and at runtime.
68 * This is rather dangerous of course, but I think it can be done without
69 * overly increasing the memory usage, and it makes loading and storing
70 * somewhat simpler and less prone to accidents.  I have also tried to
71 * define on disk data structures which can be updated in place, so that
72 * with a very large catalog (e.g. all system errors) you don't have to
73 * load everything in memory in order to add or update one set.  With
74 * this in mind there are "invalid" flags which allow items to be
75 * invalidated and thus not loaded at runtime.  Note however that although
76 * I pay attention to these when I load the DB, I do not currently use
77 * them in gencat (it just reads everything into memory), so there is
78 * no guarantee that this will all work.
79 */
80
81/*
82 * MCOffsetT - Union to handle both disk and runtime pointers
83 */
84typedef union {
85    off_t	off;
86    char	*str;
87    void	*ptr;
88    struct _MCMsgT	*msg;
89    struct _MCSetT	*set;
90} MCOffsetT;
91
92#ifdef __LP64__
93#pragma pack(4)
94#endif /* __LP64__ */
95/*
96 * MCMsgT - Message structure (disk and runtime)
97 */
98typedef struct _MCMsgT {
99    int32_t	msgId;		/* Id of this message */
100    MCOffsetT	msg;		/* Relative offset on disk or pointer in memory */
101    int32_t	invalid;	/* Valid on disk, loaded in memory */
102} MCMsgT;
103
104/*
105 * MCSetT - Set structure (disk and runtime)
106 */
107typedef struct _MCSetT {
108    int32_t	setId;		/* Id of this set */
109    off_t	nextSet;	/* Offset of next set on disk */
110    union {
111	off_t	firstMsg;	/* Offset to first Msg (while on disk) */
112	MCMsgT	*msgs;		/* Pointer to array of msgs (in mem, loaded) */
113    } u;
114    MCOffsetT	data;		/* Offset to data, or pointer to data */
115    int32_t	dataLen;	/* Length of data area on disk */
116    int32_t	numMsgs;	/* Number of messages */
117    int32_t	invalid;	/* Valid on disk, loaded in memory */
118} MCSetT;
119#ifdef __LP64__
120#pragma pack()
121#endif /* __LP64__ */
122
123/*
124 * MCCatT - Runtime catalog pointer
125 */
126typedef struct {
127    FILE        *fp;            /* File descriptor of catalog (if load-on-demand) */
128    int32_t	numSets;	/* Number of sets */
129    MCSetT	*sets;		/* Pointer to the sets */
130    off_t	firstSet;	/* Offset of first set on disk */
131} MCCatT;
132
133/*
134 * MCHeaderT - Disk file header
135 */
136typedef struct {
137    char	magic[MCMagicLen];	/* Magic cookie "*nazgul*" */
138    int32_t	majorVer;		/* ++ on incompatible changes */
139    int32_t	minorVer;		/* ++ on compatible changes */
140    int32_t	flags;			/* Informational flags */
141    int32_t	numSets;		/* Number of valid Sets */
142    off_t	firstSet;		/* Offset of first set on disk */
143} MCHeaderT;
144
145/* Some flags */
146#define MC68KByteOrder	0x01
147#define MCn86ByteOrder	0x02
148
149#endif /* !_MSGCAT_H_ */
150