Home | History | Annotate | Download | only in libese
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "include/ese/ese.h"
     18 
     19 static inline uint32_t min_u32(uint32_t a, uint32_t b) { return a < b ? a : b; }
     20 
     21 ESE_API uint32_t ese_sg_length(const struct EseSgBuffer *bufs, uint32_t cnt) {
     22   const struct EseSgBuffer *buf = bufs;
     23   uint32_t len = 0;
     24   if (!bufs || cnt == 0) {
     25     return 0;
     26   }
     27   while (buf < bufs + cnt) {
     28     /* In reality, this is probably corruption or a mistake. */
     29     if (ESE_UINT32_MAX - len < buf->len) {
     30       return ESE_UINT32_MAX;
     31     }
     32     len += buf->len;
     33     buf++;
     34   }
     35   return len;
     36 }
     37 
     38 ESE_API uint32_t ese_sg_to_buf(const struct EseSgBuffer *src, uint32_t src_cnt,
     39                                uint32_t start_at, uint32_t length,
     40                                uint8_t *dst) {
     41   const struct EseSgBuffer *buf = src;
     42   uint32_t remaining = length;
     43   if (!src || src_cnt == 0) {
     44     return 0;
     45   }
     46   while (remaining && buf < src + src_cnt) {
     47     if (start_at > buf->len) {
     48       start_at -= buf->len;
     49       buf++;
     50       continue;
     51     }
     52     uint32_t copy_len = min_u32(remaining, buf->len - start_at);
     53     ese_memcpy(dst, buf->c_base + start_at, copy_len);
     54     dst += copy_len;
     55     remaining -= copy_len;
     56     start_at = 0;
     57     buf++;
     58   }
     59   return length - remaining;
     60 }
     61 
     62 ESE_API uint32_t ese_sg_from_buf(struct EseSgBuffer *dst, uint32_t dst_cnt,
     63                                  uint32_t start_at, uint32_t length,
     64                                  const uint8_t *src) {
     65   const struct EseSgBuffer *buf = dst;
     66   uint32_t remaining = length;
     67   if (!dst || dst_cnt == 0) {
     68     return 0;
     69   }
     70 
     71   while (remaining && buf < dst + dst_cnt) {
     72     if (start_at >= buf->len) {
     73       start_at -= buf->len;
     74       buf++;
     75       continue;
     76     }
     77     uint32_t copy_len = min_u32(remaining, buf->len - start_at);
     78     ese_memcpy(buf->base + start_at, src, copy_len);
     79     src += copy_len;
     80     remaining -= copy_len;
     81     start_at = 0;
     82     buf++;
     83   }
     84   return length - remaining;
     85 }
     86