libroken: Build on windows
[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 # include <sys/types.h>
31 # include <string.h>
32 # include <errno.h>
33 #else
34 # include "afs/sysincludes.h"
35 # include "afsincludes.h"
36 #endif
37
38 #include <rx/rx.h>
39 #include <rx/rx_opaque.h>
40
41
42 /*!
43  * Generate a new opaque object
44  *
45  * Allocate a new opaque object, and copy datalen bytes from data into it.
46  * The caller should dispose of the resulting object using rx_opaque_free or
47  * rx_opaque_zeroFree.
48  *
49  * @param data
50  *      A pointer to the data to copy into the object
51  * @param datalen
52  *      The number of bytes of data to copy
53  * @returns
54  *      A pointer to the allocated opaque object.
55  */
56
57 struct rx_opaque *
58 rx_opaque_new(void *data, size_t datalen)
59 {
60     struct rx_opaque *opaque = rxi_Alloc(sizeof(struct rx_opaque));
61     if (opaque != NULL)
62         rx_opaque_populate(opaque, data, datalen);
63     return opaque;
64 }
65
66 /*!
67  * Allocate space within an existing opaque object
68  *
69  * Allocate length bytes of data within an existing opaque object. This will
70  * overwrite (without freeing) any data that is already held within the
71  * object.
72  *
73  * @param buf
74  *      The opaque object
75  * @param length
76  *      The number of bytes to allocate
77  * @returns
78  *      0 on success, ENOMEM if the memory cannot be allocated.
79  */
80
81 int
82 rx_opaque_alloc(struct rx_opaque *buf, size_t length)
83 {
84     void *mem = rxi_Alloc(length);
85     if (mem == NULL)
86         return ENOMEM;
87     buf->val = mem;
88     buf->len = length;
89     memset(buf->val, 0, buf->len);
90
91     return 0;
92 }
93
94 /*!
95  * Populate an existing opaque object
96  *
97  * Copy datalen bytes from data into an existing opaque object. This allocates
98  * new data space within the object, and will replace (without freeing) any
99  * data that is already held within the object.
100  *
101  * @param to
102  *      The opaque object to populate
103  * @param length
104  *      The number of bytes to allocate
105  * @returns
106  *      0 on sucess, ENOMEM if memory cannot be allocated
107  */
108
109 int
110 rx_opaque_populate(struct rx_opaque *to, void *data, size_t datalen)
111 {
112     int code;
113     to->len = 0;
114     to->val = NULL;
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 }