Fix: add missing includes
[openobex:mainline.git] / lib / obex_hdr_ptr.c
1 /**
2  * @file obex_hdr_ptr.c
3  *
4  * OBEX header releated functions.
5  * OpenOBEX library - Free implementation of the Object Exchange protocol.
6  *
7  * Copyright (c) 2012 Hendrik Sattler, All Rights Reserved.
8  *
9  * OpenOBEX is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU Lesser General Public License as published by the
11  * Free Software Foundation; either version 2.1 of the License, or (at your
12  * option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
17  * for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with OpenOBEX. If not, see <http://www.gnu.org/>.
21  */
22
23 #include "obex_hdr.h"
24 #include "debug.h"
25
26 #ifndef _WIN32
27 #include <arpa/inet.h>
28 #endif
29 #include <string.h>
30
31 struct obex_hdr_ptr {
32         enum obex_hdr_id id;
33         enum obex_hdr_type type;
34         size_t size;
35         const void *value;
36 };
37
38 static
39 void obex_hdr_ptr_destroy(void *self)
40 {
41         free(self);
42 }
43
44 static
45 enum obex_hdr_id obex_hdr_ptr_get_id(void *self)
46 {
47         struct obex_hdr_ptr *ptr = self;
48         return ptr->id;
49 }
50
51 static
52 enum obex_hdr_type obex_hdr_ptr_get_type(void *self)
53 {
54         struct obex_hdr_ptr *ptr = self;
55         return ptr->type;
56 }
57
58 static
59 size_t obex_hdr_ptr_get_data_size(void *self)
60 {
61         struct obex_hdr_ptr *ptr = self;
62         return ptr->size;
63 }
64
65 static
66 const void * obex_hdr_ptr_get_data_ptr(void *self)
67 {
68         struct obex_hdr_ptr *ptr = self;
69         return ptr->value;
70 }
71
72 static
73 bool obex_hdr_ptr_set_data(void *self, const void *data, size_t size)
74 {
75         struct obex_hdr_ptr *ptr = self;
76         ptr->value = data;
77         ptr->size = size;
78         return true;
79 }
80
81 static
82 struct obex_hdr_ops obex_hdr_ptr_ops = {
83         &obex_hdr_ptr_destroy,
84         &obex_hdr_ptr_get_id,
85         &obex_hdr_ptr_get_type,
86         &obex_hdr_ptr_get_data_size,
87         &obex_hdr_ptr_get_data_ptr,
88         &obex_hdr_ptr_set_data,
89         NULL,
90         NULL,
91 };
92
93 struct obex_hdr * obex_hdr_ptr_create(enum obex_hdr_id id,
94                                       enum obex_hdr_type type,
95                                       const void *data, size_t size)
96 {
97         struct obex_hdr_ptr *ptr = malloc(sizeof(*ptr));
98
99         if (!ptr)
100                 return NULL;
101
102         ptr->id = id;
103         ptr->type = type;
104         ptr->size = size;
105         ptr->value = data;
106
107         return obex_hdr_new(&obex_hdr_ptr_ops, ptr);
108 }
109
110 struct obex_hdr * obex_hdr_ptr_parse(const void *msgdata, size_t size)
111 {
112         struct obex_hdr_ptr *ptr;
113         uint16_t hsize;
114
115         if (size < 1)
116                 return NULL;
117
118         ptr = malloc(sizeof(*ptr));
119         if (!ptr)
120                 return NULL;
121
122         ptr->id = ((uint8_t *)msgdata)[0] & OBEX_HDR_ID_MASK;
123         ptr->type = ((uint8_t *)msgdata)[0] & OBEX_HDR_TYPE_MASK;
124
125         switch (ptr->type) {
126         case OBEX_HDR_TYPE_UNICODE:
127         case OBEX_HDR_TYPE_BYTES:
128                 if (size < 3)
129                         goto err;
130                 memcpy(&hsize, (uint8_t *)msgdata + 1, 2);
131                 ptr->size = ntohs(hsize) - 3;
132                 if (size < (3 + ptr->size))
133                         goto err;
134                 ptr->value = (uint8_t *)msgdata + 3;
135                 break;
136
137         case OBEX_HDR_TYPE_UINT8:
138                 if (size < 2)
139                         goto err;
140                 ptr->size = 1;
141                 ptr->value = (uint8_t *)msgdata + 1;
142                 break;
143
144         case OBEX_HDR_TYPE_UINT32:
145                 if (size < 5)
146                         goto err;
147                 ptr->size = 4;
148                 ptr->value = (uint8_t *)msgdata + 1;
149                 break;
150
151         default:
152                 goto err;
153         }
154
155         return obex_hdr_new(&obex_hdr_ptr_ops, ptr);
156
157 err:
158         DEBUG(1, "Header too big.\n");
159         free(ptr);
160         return NULL;
161 }