Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ac_buffer_reader.c Source File

ac_buffer_reader.c

00001 /*
00002  * Copyright (c) 2017, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 /**
00018  * \file buffer_reader.c
00019  * \copyright Copyright (c) ARM Ltd 2015
00020  * \author Donatien Garnier
00021  */
00022 
00023 #include "acore/ac_buffer_reader.h"
00024 #include "acore/ac_macros.h"
00025 
00026 #include "string.h"
00027 
00028 #define VOID
00029 #define ENSURE_READ_LENGTH(pBuf, n) do{ if( ac_buffer_reader_readable(pBuf) < n ) { return; } }while(0);
00030 
00031 static inline void update_buf(ac_buffer_t *pBuf)
00032 {
00033     while (ac_buffer_size(pBuf) == 0) {
00034         if (ac_buffer_next(pBuf) != NULL) {
00035             ac_buffer_t *pNext = ac_buffer_next(pBuf);
00036             ac_buffer_init(pBuf, ac_buffer_data(pNext), ac_buffer_size(pNext));
00037             pBuf->pNext = ac_buffer_next(pNext);
00038         } else if (pBuf->data != NULL) {
00039             ac_buffer_init(pBuf, NULL, 0);
00040         } else {
00041             return;
00042         }
00043     }
00044 }
00045 
00046 void ac_buffer_read_be(ac_buffer_t *pBuf, uint8_t *buf, size_t size)
00047 {
00048     ENSURE_READ_LENGTH(pBuf, size);
00049     buf += size;
00050     while (size > 0) {
00051         buf--;
00052         *buf = *ac_buffer_data(pBuf);
00053         pBuf->data++;
00054         pBuf->size--;
00055         update_buf(pBuf);
00056         size--;
00057     }
00058 }
00059 
00060 void ac_buffer_read_le(ac_buffer_t *pBuf, uint8_t *buf, size_t size)
00061 {
00062     ENSURE_READ_LENGTH(pBuf, size);
00063     while (size > 0) {
00064         size_t cpy = ac_buffer_size(pBuf);
00065         cpy = MIN(cpy, size);
00066         memcpy(buf, ac_buffer_data(pBuf), cpy);
00067         pBuf->data += cpy;
00068         pBuf->size -= cpy;
00069         update_buf(pBuf);
00070         size -= cpy;
00071         buf += cpy;
00072     }
00073 }
00074 
00075 void ac_buffer_read_n_skip(ac_buffer_t *pBuf, size_t size)
00076 {
00077     ENSURE_READ_LENGTH(pBuf, size);
00078     while (size > 0) {
00079         size_t cpy = ac_buffer_size(pBuf);
00080         cpy = MIN(cpy, size);
00081         pBuf->data += cpy;
00082         pBuf->size -= cpy;
00083         update_buf(pBuf);
00084         size -= cpy;
00085     }
00086 }
00087 
00088 size_t ac_buffer_reader_readable(const ac_buffer_t *pBuf)
00089 {
00090     size_t r = 0;
00091     while (pBuf != NULL) {
00092         r += ac_buffer_size(pBuf);
00093         pBuf = ac_buffer_next(pBuf);
00094     }
00095     return r;
00096 }
00097 
00098 const uint8_t *ac_buffer_reader_current_buffer_pointer(ac_buffer_t *pBuf)
00099 {
00100     update_buf(pBuf);
00101     return ac_buffer_data(pBuf);
00102 }
00103 
00104 size_t ac_buffer_reader_current_buffer_length(ac_buffer_t *pBuf)
00105 {
00106     update_buf(pBuf);
00107     return ac_buffer_size(pBuf);
00108 }
00109 
00110 bool ac_buffer_reader_cmp_bytes(const ac_buffer_t *pBuf, const uint8_t *bytes, size_t length)
00111 {
00112     ac_buffer_t reader;
00113 
00114     if (length > ac_buffer_reader_readable(pBuf)) {
00115         return false;
00116     }
00117 
00118     ac_buffer_dup(&reader, pBuf);
00119 
00120     while (length > 0) {
00121         size_t sz = ac_buffer_reader_current_buffer_length(&reader);
00122         if (sz > length) {
00123             sz = length;
00124         }
00125         int c = memcmp(ac_buffer_reader_current_buffer_pointer(&reader), bytes, sz);
00126         if (c) {
00127             return false;
00128         }
00129         length -= sz;
00130         bytes += sz;
00131         ac_buffer_read_n_skip(&reader, sz);
00132     }
00133 
00134     return true;
00135 }
00136 
00137 bool ac_buffer_reader_cmp(const ac_buffer_t *pBuf1, const ac_buffer_t *pBuf2)
00138 {
00139     ac_buffer_t reader1;
00140     ac_buffer_t reader2;
00141 
00142     if (ac_buffer_reader_readable(pBuf1) != ac_buffer_reader_readable(pBuf2)) {
00143         return false;
00144     }
00145 
00146     ac_buffer_dup(&reader1, pBuf1);
00147     ac_buffer_dup(&reader2, pBuf2);
00148 
00149     size_t length = ac_buffer_reader_readable(pBuf1);
00150     while (length > 0) {
00151         size_t sz1 = ac_buffer_reader_current_buffer_length(&reader1);
00152         size_t sz2 = ac_buffer_reader_current_buffer_length(&reader2);
00153 
00154         size_t sz = MIN(sz1, sz2);
00155 
00156         int c = memcmp(ac_buffer_reader_current_buffer_pointer(&reader1), ac_buffer_reader_current_buffer_pointer(&reader2), sz);
00157         if (c) {
00158             return false;
00159         }
00160         length -= sz;
00161         ac_buffer_read_n_skip(&reader1, sz);
00162         ac_buffer_read_n_skip(&reader2, sz);
00163     }
00164 
00165     return true;
00166 }