* @ingroup pbuf * Copy (part of) the contents of a packet buffer * to an application supplied buffer. * * @param buf the pbuf from which to copy data * @param dataptr the application supplied buffer * @param len length of data to copy (dataptr must be big enough). No more * than buf->tot_len will be copied, irrespective of len * @param offset offset into the packet buffer from where to beg
| 1024 | * @return the number of bytes copied, or 0 on failure |
| 1025 | */ |
| 1026 | u16_t |
| 1027 | pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) |
| 1028 | { |
| 1029 | const struct pbuf *p; |
| 1030 | u16_t left = 0; |
| 1031 | u16_t buf_copy_len; |
| 1032 | u16_t copied_total = 0; |
| 1033 | |
| 1034 | LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); |
| 1035 | LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); |
| 1036 | |
| 1037 | /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ |
| 1038 | for (p = buf; len != 0 && p != NULL; p = p->next) { |
| 1039 | if ((offset != 0) && (offset >= p->len)) { |
| 1040 | /* don't copy from this buffer -> on to the next */ |
| 1041 | offset = (u16_t)(offset - p->len); |
| 1042 | } else { |
| 1043 | /* copy from this buffer. maybe only partially. */ |
| 1044 | buf_copy_len = (u16_t)(p->len - offset); |
| 1045 | if (buf_copy_len > len) { |
| 1046 | buf_copy_len = len; |
| 1047 | } |
| 1048 | /* copy the necessary parts of the buffer */ |
| 1049 | MEMCPY(&((char *)dataptr)[left], &((char *)p->payload)[offset], buf_copy_len); |
| 1050 | copied_total = (u16_t)(copied_total + buf_copy_len); |
| 1051 | left = (u16_t)(left + buf_copy_len); |
| 1052 | len = (u16_t)(len - buf_copy_len); |
| 1053 | offset = 0; |
| 1054 | } |
| 1055 | } |
| 1056 | return copied_total; |
| 1057 | } |
| 1058 | |
| 1059 | /** |
| 1060 | * @ingroup pbuf |
no outgoing calls