Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / rx_opaque.c
1 /*
2 * Copyright (c) 2010 Your File System Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include <afsconfig.h>
26 #include <afs/param.h>
27
28 #ifndef KERNEL
29 # include <roken.h>
30 #else
31 # include "afs/sysincludes.h"
32 # include "afsincludes.h"
33 #endif
34
35 #include <rx/rx.h>
36 #include <rx/rx_opaque.h>
37
38
39 /*!
40 * Generate a new opaque object
41 *
42 * Allocate a new opaque object, and copy datalen bytes from data into it.
43 * The caller should dispose of the resulting object using rx_opaque_free or
44 * rx_opaque_zeroFree.
45 *
46 * @param data
47 * A pointer to the data to copy into the object
48 * @param datalen
49 * The number of bytes of data to copy
50 * @returns
51 * A pointer to the allocated opaque object.
52 */
53
54 struct rx_opaque *
55 rx_opaque_new(void *data, size_t datalen)
56 {
57 struct rx_opaque *opaque = rxi_Alloc(sizeof(struct rx_opaque));
58 if (opaque != NULL)
59 rx_opaque_populate(opaque, data, datalen);
60 return opaque;
61 }
62
63 /*!
64 * Allocate space within an existing opaque object
65 *
66 * Allocate length bytes of data within an existing opaque object. This will
67 * overwrite (without freeing) any data that is already held within the
68 * object.
69 *
70 * @param buf
71 * The opaque object
72 * @param length
73 * The number of bytes to allocate
74 * @returns
75 * 0 on success, ENOMEM if the memory cannot be allocated.
76 */
77
78 int
79 rx_opaque_alloc(struct rx_opaque *buf, size_t length)
80 {
81 void *mem = rxi_Alloc(length);
82 if (mem == NULL)
83 return ENOMEM;
84 buf->val = mem;
85 buf->len = length;
86 memset(buf->val, 0, buf->len);
87
88 return 0;
89 }
90
91 /*!
92 * Populate an existing opaque object
93 *
94 * Copy datalen bytes from data into an existing opaque object. This allocates
95 * new data space within the object, and will replace (without freeing) any
96 * data that is already held within the object.
97 *
98 * @param to
99 * The opaque object to populate
100 * @param length
101 * The number of bytes to allocate
102 * @returns
103 * 0 on sucess, ENOMEM if memory cannot be allocated
104 */
105
106 int
107 rx_opaque_populate(struct rx_opaque *to, const void *data, size_t datalen)
108 {
109 int code;
110 to->len = 0;
111 to->val = NULL;
112
113 if (data == NULL || datalen == 0)
114 return 0;
115
116 code = rx_opaque_alloc(to, datalen);
117 if (code)
118 return code;
119 memcpy(to->val, data, datalen);
120 return 0;
121 }
122
123 /*!
124 * Copy data from one opaque object to another
125 *
126 * Make a copy of the data held within one existing opaque object into
127 * another. This allocates new data space within the destination object,
128 * and will replace (without freeing) any data that is already held within
129 * this object.
130 *
131 * @param to
132 * To object to copy to
133 * @param from
134 * The object to copy data from
135 * @returns
136 * 0 on success, ENOMEM if memory cannot be allocated
137 */
138
139 int
140 rx_opaque_copy(struct rx_opaque *to, const struct rx_opaque *from)
141 {
142 return rx_opaque_populate(to, from->val, from->len);
143 }
144
145 /*!
146 * Free the contents of an opaque object
147 *
148 */
149 void
150 rx_opaque_freeContents(struct rx_opaque *buf) {
151 if (buf->val) {
152 rxi_Free(buf->val, buf->len);
153 }
154 buf->len = 0;
155 buf->val = NULL;
156 }
157
158 /*!
159 * Zero, then free, the contents of an opaque object
160 */
161 void
162 rx_opaque_zeroFreeContents(struct rx_opaque *buf) {
163 if (buf->val)
164 memset(buf->val, 0, buf->len);
165 rx_opaque_freeContents(buf);
166 }
167
168 /*!
169 * Free an opaque object
170 *
171 * This frees the contents of the object, then frees the object itself
172 */
173
174 void
175 rx_opaque_free(struct rx_opaque **buf) {
176 rx_opaque_freeContents(*buf);
177 rxi_Free(*buf, sizeof(struct rx_opaque));
178 *buf = NULL;
179 }
180
181 /*!
182 * Zero, then free an opaque object
183 *
184 * This zeros the contents of an opaque object, frees those contents,
185 * then frees the object itself.
186 */
187
188 void
189 rx_opaque_zeroFree(struct rx_opaque **buf) {
190 rx_opaque_zeroFreeContents(*buf);
191 rxi_Free(*buf, sizeof(struct rx_opaque));
192 *buf = NULL;
193 }