1 /*
2  * nghttp3
3  *
4  * Copyright (c) 2019 nghttp3 contributors
5  * Copyright (c) 2016 nghttp2 contributors
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 #include "nghttp3_rcbuf.h"
27 
28 #include <assert.h>
29 
30 #include "nghttp3_mem.h"
31 #include "nghttp3_str.h"
32 
nghttp3_rcbuf_new(nghttp3_rcbuf ** rcbuf_ptr,size_t size,const nghttp3_mem * mem)33 int nghttp3_rcbuf_new(nghttp3_rcbuf **rcbuf_ptr, size_t size,
34                       const nghttp3_mem *mem) {
35   uint8_t *p;
36 
37   p = nghttp3_mem_malloc(mem, sizeof(nghttp3_rcbuf) + size);
38   if (p == NULL) {
39     return NGHTTP3_ERR_NOMEM;
40   }
41 
42   *rcbuf_ptr = (void *)p;
43 
44   (*rcbuf_ptr)->mem_user_data = mem->mem_user_data;
45   (*rcbuf_ptr)->free = mem->free;
46   (*rcbuf_ptr)->base = p + sizeof(nghttp3_rcbuf);
47   (*rcbuf_ptr)->len = size;
48   (*rcbuf_ptr)->ref = 1;
49 
50   return 0;
51 }
52 
nghttp3_rcbuf_new2(nghttp3_rcbuf ** rcbuf_ptr,const uint8_t * src,size_t srclen,const nghttp3_mem * mem)53 int nghttp3_rcbuf_new2(nghttp3_rcbuf **rcbuf_ptr, const uint8_t *src,
54                        size_t srclen, const nghttp3_mem *mem) {
55   int rv;
56   uint8_t *p;
57 
58   rv = nghttp3_rcbuf_new(rcbuf_ptr, srclen + 1, mem);
59   if (rv != 0) {
60     return rv;
61   }
62 
63   (*rcbuf_ptr)->len = srclen;
64   p = (*rcbuf_ptr)->base;
65 
66   if (srclen) {
67     p = nghttp3_cpymem(p, src, srclen);
68   }
69 
70   *p = '\0';
71 
72   return 0;
73 }
74 
75 /*
76  * Frees |rcbuf| itself, regardless of its reference cout.
77  */
nghttp3_rcbuf_del(nghttp3_rcbuf * rcbuf)78 void nghttp3_rcbuf_del(nghttp3_rcbuf *rcbuf) {
79   nghttp3_mem_free2(rcbuf->free, rcbuf, rcbuf->mem_user_data);
80 }
81 
nghttp3_rcbuf_incref(nghttp3_rcbuf * rcbuf)82 void nghttp3_rcbuf_incref(nghttp3_rcbuf *rcbuf) {
83   if (rcbuf->ref == -1) {
84     return;
85   }
86 
87   ++rcbuf->ref;
88 }
89 
nghttp3_rcbuf_decref(nghttp3_rcbuf * rcbuf)90 void nghttp3_rcbuf_decref(nghttp3_rcbuf *rcbuf) {
91   if (rcbuf == NULL || rcbuf->ref == -1) {
92     return;
93   }
94 
95   assert(rcbuf->ref > 0);
96 
97   if (--rcbuf->ref == 0) {
98     nghttp3_rcbuf_del(rcbuf);
99   }
100 }
101 
nghttp3_rcbuf_get_buf(const nghttp3_rcbuf * rcbuf)102 nghttp3_vec nghttp3_rcbuf_get_buf(const nghttp3_rcbuf *rcbuf) {
103   nghttp3_vec res = {rcbuf->base, rcbuf->len};
104   return res;
105 }
106 
nghttp3_rcbuf_is_static(const nghttp3_rcbuf * rcbuf)107 int nghttp3_rcbuf_is_static(const nghttp3_rcbuf *rcbuf) {
108   return rcbuf->ref == -1;
109 }
110