* @ingroup pbuf * Same as pbuf_take() but puts data at an offset * * @param buf pbuf to fill with data * @param dataptr application supplied data buffer * @param len length of the application supplied data buffer * @param offset offset in pbuf where to copy dataptr to * * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough */
| 1237 | * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough |
| 1238 | */ |
| 1239 | err_t |
| 1240 | pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset) |
| 1241 | { |
| 1242 | u16_t target_offset; |
| 1243 | struct pbuf *q = pbuf_skip(buf, offset, &target_offset); |
| 1244 | |
| 1245 | /* return requested data if pbuf is OK */ |
| 1246 | if ((q != NULL) && (q->tot_len >= target_offset + len)) { |
| 1247 | u16_t remaining_len = len; |
| 1248 | const u8_t *src_ptr = (const u8_t *)dataptr; |
| 1249 | /* copy the part that goes into the first pbuf */ |
| 1250 | u16_t first_copy_len; |
| 1251 | LWIP_ASSERT("check pbuf_skip result", target_offset < q->len); |
| 1252 | first_copy_len = (u16_t)LWIP_MIN(q->len - target_offset, len); |
| 1253 | MEMCPY(((u8_t *)q->payload) + target_offset, dataptr, first_copy_len); |
| 1254 | remaining_len = (u16_t)(remaining_len - first_copy_len); |
| 1255 | src_ptr += first_copy_len; |
| 1256 | if (remaining_len > 0) { |
| 1257 | return pbuf_take(q->next, src_ptr, remaining_len); |
| 1258 | } |
| 1259 | return ERR_OK; |
| 1260 | } |
| 1261 | return ERR_MEM; |
| 1262 | } |
| 1263 | |
| 1264 | /** |
| 1265 | * @ingroup pbuf |