Linux: correct use of atomic_add and atomic_sub functions
[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 <sys/types.h>
30 # include <string.h>
31 # include <errno.h>
32 #else
33 # include "afs/sysincludes.h"
34 # include "afsincludes.h"
35 #endif
36
37 #include <rx/rx.h>
38 #include <rx/rx_opaque.h>
39
40
41 /*!
42  * Generate a new opaque object
43  *
44  * Allocate a new opaque object, and copy datalen bytes from data into it.
45  * The caller should dispose of the resulting object using rx_opaque_free or
46  * rx_opaque_zeroFree.
47  *
48  * @param data
49  *      A pointer to the data to copy into the object
50  * @param datalen
51  *      The number of bytes of data to copy
52  * @returns
53  *      A pointer to the allocated opaque object.
54  */
55
56 struct rx_opaque *
57 rx_opaque_new(void *data, size_t datalen)
58 {
59     struct rx_opaque *opaque = rxi_Alloc(sizeof(struct rx_opaque));
60     if (opaque != NULL)
61         rx_opaque_populate(opaque, data, datalen);
62     return opaque;
63 }
64
65 /*!
66  * Allocate space within an existing opaque object
67  *
68  * Allocate length bytes of data within an existing opaque object. This will
69  * overwrite (without freeing) any data that is already held within the
70  * object.
71  *
72  * @param buf
73  *      The opaque object
74  * @param length
75  *      The number of bytes to allocate
76  * @returns
77  *      0 on success, ENOMEM if the memory cannot be allocated.
78  */
79
80 int
81 rx_opaque_alloc(struct rx_opaque *buf, size_t length)
82 {
83     void *mem = rxi_Alloc(length);
84     if (mem == NULL)
85         return ENOMEM;
86     buf->val = mem;
87     buf->len = length;
88     memset(buf->val, 0, buf->len);
89
90     return 0;
91 }
92
93 /*!
94  * Populate an existing opaque object
95  *
96  * Copy datalen bytes from data into an existing opaque object. This allocates
97  * new data space within the object, and will replace (without freeing) any
98  * data that is already held within the object.
99  *
100  * @param to
101  *      The opaque object to populate
102  * @param length
103  *      The number of bytes to allocate
104  * @returns
105  *      0 on sucess, ENOMEM if memory cannot be allocated
106  */
107
108 int
109 rx_opaque_populate(struct rx_opaque *to, void *data, size_t datalen)
110 {
111     int code;
112     to->len = 0;
113     to->val = NULL;
114
115     code = rx_opaque_alloc(to, datalen);
116     if (code)
117         return code;
118     memcpy(to->val, data, datalen);
119     return 0;
120 }
121
122 /*!
123  * Copy data from one opaque object to another
124  *
125  * Make a copy of the data held within one existing opaque object into
126  * another. This allocates new data space within the destination object,
127  * and will replace (without freeing) any data that is already held within
128  * this object.
129  *
130  * @param to
131  *      To object to copy to
132  * @param from
133  *      The object to copy data from
134  * @returns
135  *      0 on success, ENOMEM if memory cannot be allocated
136  */
137
138 int
139 rx_opaque_copy(struct rx_opaque *to, const struct rx_opaque *from)
140 {
141     return rx_opaque_populate(to, from->val, from->len);
142 }
143
144 /*!
145  * Free the contents of an opaque object
146  *
147  */
148 void
149 rx_opaque_freeContents(struct rx_opaque *buf) {
150     if (buf->val) {
151         rxi_Free(buf->val, buf->len);
152     }
153     buf->len = 0;
154     buf->val = NULL;
155 }
156
157 /*!
158  * Zero, then free, the contents of an opaque object
159  */
160 void
161 rx_opaque_zeroFreeContents(struct rx_opaque *buf) {
162     if (buf->val)
163         memset(buf->val, 0, buf->len);
164     rx_opaque_freeContents(buf);
165 }
166
167 /*!
168  * Free an opaque object
169  *
170  * This frees the contents of the object, then frees the object itself
171  */
172
173 void
174 rx_opaque_free(struct rx_opaque **buf) {
175     rx_opaque_freeContents(*buf);
176     rxi_Free(*buf, sizeof(struct rx_opaque));
177     *buf = NULL;
178 }
179
180 /*!
181  * Zero, then free an opaque object
182  *
183  * This zeros the contents of an opaque object, frees those contents,
184  * then frees the object itself.
185  */
186
187 void
188 rx_opaque_zeroFree(struct rx_opaque **buf) {
189     rx_opaque_zeroFreeContents(*buf);
190     rxi_Free(*buf, sizeof(struct rx_opaque));
191     *buf = NULL;
192 }