renamed the package to libgedcom-dev
[gedcom-parse.git] / doc / gom.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>Gedcom object model in C</title>
2   
3                                                               
4   <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"></head><body text="#000000" bgcolor="#ffffff" link="#000099" vlink="#990099" alink="#000099">
5                  
6 <h1 align="center">Gedcom object model in C</h1>
7          <br>
8                  
9 <h2>Index</h2>
10                
11 <ul>
12           <li><a href="#Main_functions">Main functions</a></li>
13
14     <li><a href="#Object_model_structure">Object model structure</a></li>
15   <ul>
16     <li><a href="#Object_lists">Object lists</a><br>
17     </li>
18   </ul>
19
20
21     
22   <ul>
23     <li><a href="#User_data">User data</a></li>
24   </ul>
25   <li><a href="#Other_functions">Modifying the object model</a></li>
26   <ul>
27     <li><a href="#Manipulating_strings">Manipulating strings</a></li><li><a href="#Adding_and_removing_records">Adding and removing records</a></li>
28     <li><a href="#Adding_rem_and_moving_xref">Adding, removing and moving cross-references</a><br>
29     </li>
30     <li><a href="#Adding_removing_and_moving">Adding, removing and moving sub-structures</a><br>
31     </li>
32
33   </ul><li><a href="#Writing_the_object_model_to_file">Writing the object model to file</a><br>
34 <br>
35     </li>
36
37
38
39   
40
41          <li><a href="gomxref.html">C object model details</a><br>
42             </li>
43
44                
45 </ul>
46                
47 <hr width="100%" size="2">         
48
49 <h2><a name="Main_functions"></a>Main functions<br>
50
51 </h2>
52 There are two ways to start with a GEDCOM object model (after having called <code>gedcom_init</code>): either by starting from scratch, or by starting from a given GEDCOM file. &nbsp;This is done via the following two functions:<br>
53 <blockquote><code>int <b>gom_parse_file</b> (const char* file_name);<br>
54   </code>
55   <blockquote>This initializes the object model by parsing the GEDCOM file given by <code>file_name</code>. &nbsp;It returns 0 on success and 1 on failure.<br>
56   </blockquote>
57 </blockquote>
58 <blockquote><code>int <b>gom_new_model</b> ();<br>
59   </code>
60   <blockquote>This starts an empty model. &nbsp;Actually, this is done by processing the file "<code>new.ged</code>" in the gedcom-parse data directory.<br>
61   </blockquote>
62 </blockquote>
63 In the GEDCOM object model, all the data is immediately available after calling <code>gom_parse_file()</code> or <code>gom_new_model()</code>. &nbsp;For this, an entire model based on C structs is used. &nbsp;These structs are documented <a href="file:///home/verthezp/src/external/gedcom-parse/doc/gomxref.html">here</a>,
64 and follow the GEDCOM syntax quite closely. &nbsp;Each of the records in
65 a GEDCOM file are modelled by a separate struct, and some common sub-structures
66 have their own struct definition.<br>
67 <br>
68
69 The following functions are available to get at these structs:<br>
70 <ul>
71   <li>First, there are two functions to get the header record and the submission
72 record (there can be only one of them in a GEDCOM file):<br>
73     <blockquote><code>struct header* &nbsp; &nbsp; &nbsp;<b>gom_get_header</b>();<br>
74 struct submission* &nbsp;<b>gom_get_submission</b>();<br>
75       </code></blockquote>
76   </li>
77   <li>Further, for each of the other records, there are two functions, one
78 to get the first of such records, and one to get a record via its cross-reference
79 tag in the GEDCOM file:<br>
80     <blockquote><code>struct XXX* &nbsp; <b>gom_get_first_XXX</b>();<br>
81 struct XXX* &nbsp; <b>gom_get_XXX_by_xref</b>(const char* xref);</code><br>
82     </blockquote>
83   </li>
84 </ul>
85 <blockquote>The <code><b>XXX</b></code> stands for one of the following: <code><b>family</b>, </code><code><b>individual</b>, <b>multimedia</b>, <b>note</b>, <b>repository</b>, <b>source</b>, <b>submitter</b>, <b>user_rec</b></code>.<br>
86 </blockquote>
87 <hr width="100%" size="2">
88 <h2><a name="Object_model_structure"></a>Object model structure<br>
89
90 </h2>
91 <h3><a name="Object_lists"></a>Object lists<br>
92 </h3>
93 All records of a certain type are linked together in a linked list. &nbsp;The
94 above functions only give access to the first record of each linked list.
95 &nbsp;The others can be accessed by traversing the linked list via the <code>next</code> member of the structs. &nbsp;This means that e.g. the following piece of code will traverse the linked list of family records:<br>
96 <blockquote><code>struct family* fam;<br>
97   <br>
98 for (fam = gom_get_first_family() ; fam ; fam = fam-&gt;next) {<br>
99 &nbsp; ...<br>
100 }</code><br>
101 </blockquote>
102 The <code>next</code> member of the last element in the list is guaranteed to have the <code>NULL</code> value.<br>
103 <br>
104 Actually, the linked list is a doubly-linked list: each record also has a <code>previous</code> member. &nbsp;But for implementation reasons the behaviour of this <code>previous</code> member on the edges of the linked list will not be guaranteed, i.e. it can be circular or terminated with <code>NULL</code>, no assumptions can be made in the application code.<br>
105 <br>
106 This linked-list model applies also to all sub-structures of the main record structs, i.e. each struct that has a <code>next </code>and <code>previous</code>
107 member follows the above conventions. &nbsp;This means that the following
108 piece of code traverses all children of a family (see the details of the
109 different structs <a href="gomxref.html">here</a>):<br>
110 <blockquote><code>struct family* fam = ...;<br>
111   <br>
112 struct xref_list* xrl;<br>
113 for (xrl = fam-&gt;children ; xrl ; xrl = xrl-&gt;next) {<br>
114 &nbsp; ...<br>
115 }</code> <br>
116 </blockquote>
117 Note that all character strings in the object model are encoded in UTF-8 (<a href="file:///home/verthezp/src/external/gedcom-parse/doc/encoding.html">Why UTF-8?</a>), but see <a href="#Manipulating_strings">below</a> for how to convert these automatically.<br>
118 <h3><a name="User_data"></a>User data</h3>
119
120
121 Each of the structs has an extra member called <code>extra</code> (of type <code>struct user_data*</code>).
122 &nbsp;This gathers all non-standard GEDCOM tags within the scope of the struct
123 in a flat linked list, no matter what the internal structure of the non-standard
124 tags is. &nbsp;Each element of the linked list has:<br>
125 <ul>
126   <li>a level: the level number in the GEDCOM file</li>
127   <li>a tag: the tag given in the GEDCOM file</li>
128   <li>a value: the value, which can be a string value or a cross-reference value (one of the two will be non-NULL)<br>
129   </li>
130 </ul>
131 This way, none of the information in the GEDCOM file is lost, even the non-standard information.<br>
132 <br>
133 <hr width="100%" size="2">
134 <h2><a name="Other_functions"></a>Modifying the object model</h2>Note that the date manipulations are described <a href="interface.html#date_value">here</a>.<br>
135
136 <h3><a name="Manipulating_strings"></a>Manipulating strings<br>
137 </h3>
138 There are some functions available to retrieve and change strings in the
139 Gedcom object model, depending whether you use UTF-8 strings in your application
140 or locale-defined strings.<br>
141 <br>
142 The following functions retrieve and set the string in UTF-8 encoding:<br>
143 <blockquote><code>char* <b>gom_get_string</b> (char* data);<br>
144 char* <b>gom_set_string</b> (char** data, const char* str_in_utf8);</code><br>
145 </blockquote>
146 The first function is in fact superfluous, because it just returns the <code>data</code>, but it is there for symmetry with the functions given below for the locale-defined input and output. &nbsp;<br>
147 <br>
148 The second function returns the new value if successful, or <code>NULL</code>
149 if an error occurred (e.g. failure to allocate memory or the given string is not a valid UTF-8 string). &nbsp;It makes a
150 copy of the input string to store it in the object model. &nbsp;It also takes
151 care of deallocating the old value of the data if needed. &nbsp;Note that
152 the set function needs the address of the data variable, to be able to modify
153 it. &nbsp;In the case of an error, the target data variable is not modified.<br>
154 <br>
155 Examples of use of these strings would be, e.g. for retrieving and setting the system ID in the header:<br>
156 <blockquote><code>struct header* head = gom_get_header();</code><code></code><br>
157   <code>char* oldvalue = gom_get_string(head-&gt;source.id);<br>
158 char* newvalue = "My_Gedcom_Tool";<br>
159   </code><br>
160   <code>if (gom_set_string(&amp;head-&gt;source.id, newvalue)) {<br>
161 &nbsp; printf("Modified system id from %s to %s\n", oldvalue, newvalue);<br>
162 }</code><br>
163 </blockquote>
164 <br>
165 A second couple of functions retrieve and set the string in the format defined by the current locale:<br>
166 <blockquote><code>char* <b>gom_get_string_for_locale</b> (char* data, int* conversion_failures);<br>
167 char* <b>gom_set_string_for_locale</b> (char** data, const char* str_in_locale)</code>;<br>
168 </blockquote>
169 The use of these functions is the same as the previous ones, but e.g. in
170 the "en_US" locale the string will be returned by the first function in the
171 ISO-8859-1 encoding and the second function expects the <code>str_in_locale</code> to be in this encoding. &nbsp;Conversion to and from UTF-8 for the object model is done on the fly.<br>
172 <br>
173 Since the conversion from UTF-8 to the locale encoding is not always possible,
174 the get function has a second parameter that can return the number of conversion
175 failures for the result string. &nbsp;Pass a pointer to an integer if you
176 want to know this. &nbsp;You can pass <code>NULL</code> if you're not interested. &nbsp;The function returns <code>NULL</code>
177 if an error occurred (e.g. if the given string is not a valid string for
178 the current locale); in that case the target data variable is not modified.<br>
179 <br>
180 <h3><a name="Adding_and_removing_records"></a>Adding and removing records</h3>
181 For each of the record types, there are two functions to add and remove records:
182 <blockquote><code>struct XXX* &nbsp; <b>gom_new_XXX</b>(const char* xref);<br>
183 int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>gom_delete_XXX</b>(struct XXX* obj);</code><br>
184     </blockquote>
185
186   
187 The <code><b>XXX</b></code> stands for one of the following: <code><b>family</b>, </code><code><b>individual</b>, <b>multimedia</b>, <b>note</b>, <b>repository</b>, <b>source</b>, <b>submitter</b>, <b>user_rec</b></code>.<br>
188 <br>
189 For submission records, the <code><b>gom_delete_submission()</b></code> has no parameters (since there can be only one such object anyway).<br>
190 <br>
191 When creating new records, the application is responsible for making sure
192 that mandatory fields (according to the GEDCOM spec) are filled in afterwards.
193 &nbsp;In a later release, there will be checks in <code>gom_write_file</code> when something is missing.<br>
194 <br>
195 <h3><a name="Adding_rem_and_moving_xref"></a>Adding, removing and moving cross-references<br>
196 </h3>
197 For struct members that are of type <code>struct xref_value</code>, the following function is available:<br>
198 <blockquote><code>struct xref_value* &nbsp;<b>gom_set_xref</b>(struct xref_value** data, const char* xref);</code><br>
199     </blockquote>
200 This function modifies the <code>data</code> variable to point to the given <code>xref</code>, taking care of unreferencing the old value, and referencing the new value. &nbsp;If an error occurs, <code>NULL</code> is returned (and the <code>data</code> variable is not changed). &nbsp;If xref is <code>NULL</code>, the data is set to <code>NULL</code>.<br>
201 <br>
202 For struct members that are of type <code>struct xref_list</code>, the following functions are available:<br>
203 <blockquote><code>struct xref_list* &nbsp; <b>gom_add_xref</b>(struct xref_list** data, const char* xref);<br>
204 int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>&nbsp; &nbsp; &nbsp; gom_remove_xref</b>(struct xref_list** data, const char* xref);<br>
205 int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>gom_move_xref</b>(Gom_direction dir, </code><code>struct xref_list** data, const char* xref);</code><br>
206     </blockquote>
207 The first function adds the given <code>xref</code> to the end of the <code>data</code> list. &nbsp;The second function removes the given <code>xref</code> from the <code>data</code> list (if present; if not present an error is generated and 1 is returned).<br>
208 <br>
209 The third function moves the given <code>xref </code>up or down the <code>data</code> list, depending on the <code>dir</code> parameter, which can be:<br>
210 <ul>
211   <li><code>MOVE_UP</code></li>
212   <li><code>MOVE_DOWN</code></li>
213 </ul>
214 Again, an error is generated and 1 is returned if the given xref is not part
215 of the list. &nbsp;If the xref cannot be moved up (because the first in the
216 list) or down (because the last in the list), a warning is generated, but
217 the function still returns success (0).<br>
218 <h3><a name="Adding_removing_and_moving"></a>Adding, removing and moving substructures<br>
219 </h3>
220 For struct members that are just a single value, the following functions are available:<br>
221 <blockquote><code>struct XXX* &nbsp; <b>gom_set_new_XXX</b>(struct XXX** data);<br>
222 int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>gom_delete_XXX</b>(struct XXX** data);</code><br>
223     </blockquote>
224 This is the case for <b><code>XXX</code></b> equal to <b><code>address</code></b>, <b><code>change_date</code></b> or <b><code>place</code></b>. &nbsp;The first function creates a new substructure and assigns it to <code>data</code> (<code>NULL</code> is returned if there was already a value). &nbsp;The second function deletes the value from <code>data</code>.<br>
225 <br>
226 Note: for <code>change_date</code> structs there is also the following short-cut function, which updates the date and time directly:<br>
227 <blockquote><code>int <b>gom_update_timestamp</b> (struct change_date** obj, time_t tval);<br></code></blockquote>
228 For struct members that are a list (as described <a href="#Object_lists">here</a>), the following functions are available:<br>
229 <blockquote><code>struct XXX* &nbsp; <b>gom_add_new_XXX</b>(struct XXX** data);<br>
230 int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>gom_remove_XXX</b>(struct XXX** data, struct XXX* obj);</code><br>
231   <code>int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>gom_move_XXX</b>(Gom_direction dir, struct XXX** data, struct XXX* obj);</code><br>
232     </blockquote>
233
234 This is the case for all <code>XXX</code> structs that have a <code>next</code> and <code>previous</code> member. &nbsp;The first function creates a new substructure and adds it to the end of the <code>data</code> list. &nbsp;The second function deletes the object from the <code>data</code> list (if present; if not present, an error is generated and 1 is returned).<br>
235 <br>
236 The third function moves the given <code>obj</code> up or down the <code>data</code> list, depending on the <code>dir</code> parameter, similar to the xref functions above.<br>
237 <br>
238
239 <hr width="100%" size="2">
240 <h2><a name="Writing_the_object_model_to_file"></a>Writing the object model to file<br>
241 </h2>
242 Writing the current object model to a file is simply done using the following function:<br>
243 <blockquote><code>int <b>gom_write_file</b> (const char* filename, int* total_conv_fails);<br></code></blockquote>
244 This writes the model to the file <code>filename</code>. &nbsp;The second parameter can return the total number of conversion failures (pass&nbsp;<code>NULL</code><code></code> if you're not interested). &nbsp;The functions in <a href="usage.html#Controlling_some_settings">this section</a> can be used before <code>gom_write_file</code> to control some settings.<br>
245 <br>
246 Before you write the file, you can update the timestamp in the header using the following function:<br>
247 <blockquote><code>int <b>gom_header_update_timestamp</b> (time_t tval);<br></code></blockquote>
248 This sets the <code>date</code> and <code>time</code> fields of the header to the time indicated by <code>tval</code>.
249 &nbsp;The function returns 0 on success, non-zero if an error occurred. &nbsp;Typically,
250 the function would be used as follows, to set the current time in the timestamp:<br>
251 <blockquote><code>int result;<br>
252 result = gom_header_update_timestamp(time(NULL));</code><br>
253 </blockquote>
254 <hr width="100%" size="2"><br>
255
256 <pre><font size="-1">$Id$<br>$Name$</font><br></pre>
257
258                                                                         
259                   
260 <pre>                    </pre>
261                                                                         
262                                                         
263 <br>
264 <br>
265 <br>
266 <br>
267 <br>
268 <br>
269 <br>
270 <br>
271 <br>
272 <br>
273 </body></html>