mirror of
https://github.com/yasuhirokimura/db18
synced 2026-06-08 18:29:23 +00:00
158 lines
5.3 KiB
HTML
158 lines
5.3 KiB
HTML
<?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 18.1.40</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>
|