Changeset 4498:1396b66d445d in roaraudio for libroar/caps.c
- Timestamp:
- 10/13/10 02:23:02 (13 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libroar/caps.c
r4497 r4498 36 36 #include "libroar.h" 37 37 38 int roar_caps_to_msg(struct roar_message * mes, struct roar_caps * caps, void ** data) { 39 char * datap; 40 size_t needlen = 4; 41 42 if ( mes == NULL || caps == NULL ) 43 return -1; 44 45 needlen += caps->len; 46 47 if ( needlen > sizeof(mes->data) ) { 48 if ( data == NULL ) 49 return -1; 50 51 if ( (*data = malloc(needlen)) == NULL ) 52 return -1; 53 54 datap = *data; 55 } else { 56 datap = mes->data; 57 } 58 59 datap[0] = caps->version; 60 datap[1] = caps->type; 61 datap[2] = (caps->flags & 0xFF00) >> 8; 62 datap[3] = caps->flags & 0xFF; 63 64 if ( caps->len != 0 ) { 65 memcpy(&(datap[4]), caps->data, caps->len); 66 } 67 68 mes->datalen = needlen; 69 70 return 0; 71 } 72 73 int roar_caps_from_msg(struct roar_caps * caps, struct roar_message * mes, void * data) { 74 char * datap; 75 76 if ( mes == NULL || caps == NULL ) 77 return -1; 78 79 if ( data != NULL ) { 80 datap = data; 81 } else { 82 datap = mes->data; 83 } 84 85 // versin check. 86 if ( datap[0] != 0 || mes->datalen < 4 ) 87 return -1; 88 89 memset(caps, 0, sizeof(struct roar_caps)); 90 91 caps->version = datap[0]; 92 caps->type = datap[1]; 93 caps->flags = (datap[2] << 8) | datap[3]; 94 95 if ( mes->datalen == 4 ) { 96 caps->data = NULL; 97 caps->len = 0; 98 } else { 99 caps->data = &(datap[4]); 100 caps->len = mes->datalen - 4; 101 } 102 103 return 0; 104 } 105 106 int roar_caps_stds(struct roar_connection * con, struct roar_stds ** out, struct roar_stds * in, int flags) { 107 struct roar_message mes; 108 struct roar_caps caps; 109 char * data = NULL; 110 size_t i; 111 112 if ( flags == -1 ) 113 flags = 0; 114 115 if ( con == NULL ) 116 return -1; 117 118 if ( out != NULL ) 119 flags |= ROAR_CF_REQUEST; 120 121 if ( (flags & ROAR_CF_REQUEST) && out == NULL ) 122 return -1; 123 124 if ( in != NULL ) 125 if ( in->stds_len == 0 ) 126 in = NULL; 127 128 memset(&caps, 0, sizeof(caps)); 129 130 caps.version = 0; 131 caps.type = ROAR_CT_STANDARDS; 132 caps.flags = flags; 133 134 memset(&mes, 0, sizeof(mes)); 135 136 if ( in != NULL ) { 137 // we use a hack here to avoid double alloc: 138 // first pass the data in native byte order. 139 // after we got a buffer swap in-buffer. 140 caps.data = in->stds; 141 caps.len = in->stds_len * 4; 142 } 143 144 if ( roar_caps_to_msg(&mes, &caps, &data) == -1 ) 145 return -1; 146 147 if ( in != NULL ) { 148 if ( data == NULL ) { 149 for (i = 0; i < in->stds_len; i++) { 150 ((uint32_t*)mes.data)[i+1] = ROAR_HOST2NET32(((uint32_t*)mes.data)[i+1]); 151 } 152 } else { 153 for (i = 0; i < in->stds_len; i++) { 154 ((uint32_t*)data)[i+1] = ROAR_HOST2NET32(((uint32_t*)data)[i+1]); 155 } 156 } 157 } 158 159 mes.cmd = ROAR_CMD_CAPS; 160 161 if ( roar_req(con, &mes, &data) == -1 ) 162 return -1; 163 164 if ( mes.cmd != ROAR_CMD_OK ) { 165 if ( data != NULL ) 166 free(data); 167 return -1; 168 } 169 170 if ( roar_caps_from_msg(&caps, &mes, data) == -1 ) { 171 if ( data != NULL ) 172 free(data); 173 return -1; 174 } 175 176 // check if response matches the request: 177 if ( caps.version != 0 || caps.type != ROAR_CT_STANDARDS || (caps.len & 0x3) != 0 ) { 178 if ( data != NULL ) 179 free(data); 180 return -1; 181 } 182 183 if ( out != NULL ) { 184 *out = roar_stds_new(caps.len/4); 185 if ( *out == NULL ) { 186 if ( data != NULL ) 187 free(data); 188 return -1; 189 } 190 191 for (i = 0; i < (*out)->stds_len; i++) { 192 (*out)->stds[i] = ROAR_NET2HOST32(((uint32_t*)caps.data)[i+1]); 193 } 194 } 195 196 if ( data != NULL ) 197 free(data); 198 199 return 0; 200 } 201 202 struct roar_stds * roar_stds_new(size_t len) { 203 struct roar_stds * ret; 204 205 if ( len == 0 ) 206 return NULL; 207 208 ret = roar_mm_malloc(sizeof(struct roar_stds)); 209 210 if ( ret == NULL ) 211 return NULL; 212 213 memset(ret, 0, sizeof(struct roar_stds)); 214 215 ret->stds_len = len; 216 ret->stds = roar_mm_malloc(len*sizeof(uint32_t)); 217 218 if ( ret->stds == NULL ) { 219 roar_mm_free(ret); 220 return NULL; 221 } 222 223 memset(ret->stds, 0, len*sizeof(uint32_t)); 224 225 return ret; 226 } 227 228 int roar_stds_free(struct roar_stds * stds) { 229 if ( stds == NULL ) 230 return -1; 231 232 if ( stds->stds != NULL ) 233 roar_mm_free(stds->stds); 234 235 roar_mm_free(stds); 236 237 return 0; 238 } 239 38 240 //ll
Note: See TracChangeset
for help on using the changeset viewer.