1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Storing C/C++ structures/objects</title>
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
<link rel="start" href="index.html" title="Berkeley DB Programmer's Reference Guide" />
<link rel="up" href="am_misc.html" title="Chapter 4. Access Method Wrapup" />
<link rel="prev" href="am_misc_partial.html" title="Partial record storage and retrieval" />
<link rel="next" href="am_misc_perm.html" title="Retrieved key/data permanence for C/C++" />
</head>
<body>
<div xmlns="" class="navheader">
<div class="libver">
<p>Library Version 12.1.6.1</p>
</div>
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Storing C/C++
structures/objects</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="am_misc_partial.html">Prev</a> </td>
<th width="60%" align="center">Chapter 4. Access Method Wrapup </th>
<td width="20%" align="right"> <a accesskey="n" href="am_misc_perm.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="am_misc_struct"></a>Storing C/C++
structures/objects</h2>
</div>
</div>
</div>
<p>
Berkeley DB can store any kind of data, that is, it is
entirely 8-bit clean. How you use this depends, to some
extent, on the application language you are using. In the
C/C++ languages, there are a couple of different ways to store
structures and objects.
</p>
<p>
First, you can do some form of run-length encoding and copy
your structure into another piece of memory before storing
it:
</p>
<a id="prog_am23"></a>
<pre class="programlisting">struct {
char *data1;
u_int32_t data2;
...
} info;
size_t len;
u_int8_t *p, data_buffer[1024];
p = &data_buffer[0];
len = strlen(info.data1);
memcpy(p, &len, sizeof(len));
p += sizeof(len);
memcpy(p, info.data1, len);
p += len;
memcpy(p, &info.data2, sizeof(info.data2));
p += sizeof(info.data2);
...
</pre>
<p>
and so on, until all the fields of the structure have been
loaded into the byte array. If you want more examples, see the
Berkeley DB logging routines (for example,
btree/btree_auto.c:__bam_split_log()). This technique is
generally known as "marshalling". If you use this technique,
you must then un-marshall the data when you read it
back:
</p>
<a id="prog_am24"></a>
<pre class="programlisting">struct {
char *data1;
u_int32_t data2;
...
} info;
size_t len;
u_int8_t *p, data_buffer[1024];
...
p = &data_buffer[0];
memcpy(&len, p, sizeof(len));
p += sizeof(len);
info.data1 = malloc(len);
memcpy(info.data1, p, len);
p += len;
memcpy(&info.data2, p, sizeof(info.data2));
p += sizeof(info.data2);
...
</pre>
<p>
and so on.
</p>
<p>
The second way to solve this problem only works if you have
just one variable length field in the structure. In that case,
you can declare the structure as follows:
</p>
<pre class="programlisting">struct {
int a, b, c;
u_int8_t buf[1];
} info;</pre>
<p>
Then, let's say you have a string you want to store in this
structure. When you allocate the structure, you allocate it
as:
</p>
<pre class="programlisting">malloc(sizeof(struct info) + strlen(string));</pre>
<p>
Since the allocated memory is contiguous, you can the
initialize the structure as:
</p>
<pre class="programlisting">info.a = 1;
info.b = 2;
info.c = 3;
memcpy(&info.buf[0], string, strlen(string) + 1);</pre>
<p>
and give it to Berkeley DB to store, with a length
of:
</p>
<pre class="programlisting">sizeof(struct info) + strlen(string);</pre>
<p>
In this case, the structure can be copied out of the
database and used without any additional work.
</p>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="am_misc_partial.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="am_misc.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="am_misc_perm.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Partial record storage and
retrieval </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Retrieved key/data permanence for C/C++</td>
</tr>
</table>
</div>
</body>
</html>
|