1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "los_seq_buf.h" 33#include "los_typedef.h" 34#include <stdlib.h> 35#include "securec.h" 36 37static int ExpandSeqBuf(struct SeqBuf *seqBuf, size_t oldCount) 38{ 39 char *newBuf = NULL; 40 int ret; 41 42 if ((seqBuf == NULL) || (seqBuf->buf == NULL)) { 43 return -LOS_NOK; 44 } 45 46 if (seqBuf->size >= SEQBUF_LIMIT_SIZE) { 47 goto EXPAND_FAILED; 48 } 49 50 newBuf = (char*)malloc(seqBuf->size <<= 1); 51 if (newBuf == NULL) { 52 goto EXPAND_FAILED; 53 } 54 (void)memset_s(newBuf + oldCount, seqBuf->size - oldCount, 0, seqBuf->size - oldCount); 55 56 ret = memcpy_s(newBuf, seqBuf->size, seqBuf->buf, oldCount); 57 if (ret != LOS_OK) { 58 free(newBuf); 59 goto EXPAND_FAILED; 60 } 61 seqBuf->count = oldCount; 62 63 free(seqBuf->buf); 64 seqBuf->buf = newBuf; 65 66 return LOS_OK; 67EXPAND_FAILED: 68 free(seqBuf->buf); 69 seqBuf->buf = NULL; 70 seqBuf->count = 0; 71 seqBuf->size = 0; 72 73 return -LOS_NOK; 74} 75 76struct SeqBuf *LosBufCreat(void) 77{ 78 struct SeqBuf *seqBuf = NULL; 79 80 seqBuf = (struct SeqBuf *)malloc(sizeof(struct SeqBuf)); 81 if (seqBuf == NULL) { 82 errno = -LOS_ENOMEM; 83 return NULL; 84 } 85 (void)memset_s(seqBuf, sizeof(struct SeqBuf), 0, sizeof(struct SeqBuf)); 86 87 return seqBuf; 88} 89 90int LosBufVprintf(struct SeqBuf *seqBuf, const char *fmt, va_list argList) 91{ 92 bool needreprintf = FALSE; 93 int bufLen; 94 95 if (seqBuf == NULL) { 96 return -LOS_EPERM; 97 } 98 99 if (seqBuf->buf == NULL) { 100 seqBuf->size = SEQBUF_PAGE_SIZE; 101 seqBuf->buf = (char *)malloc(seqBuf->size); 102 if (seqBuf->buf == NULL) { 103 return -LOS_ENOMEM; 104 } 105 (void)memset_s(seqBuf->buf, seqBuf->size, 0, seqBuf->size); 106 seqBuf->count = 0; 107 } 108 109 do { 110 bufLen = vsnprintf_s(seqBuf->buf + seqBuf->count, seqBuf->size - seqBuf->count, 111 seqBuf->size - seqBuf->count - 1, fmt, argList); 112 if (bufLen >= 0) { 113 /* succeed write. */ 114 seqBuf->count += bufLen; 115 return 0; 116 } 117 if (seqBuf->buf[seqBuf->count] == '\0') { 118 free(seqBuf->buf); 119 seqBuf->buf = NULL; 120 break; 121 } 122 123 needreprintf = TRUE; 124 125 if (ExpandSeqBuf(seqBuf, seqBuf->count) != 0) { 126 break; 127 } 128 } while (needreprintf); 129 130 return -LOS_NOK; 131} 132 133int LosBufPrintf(struct SeqBuf *seqBuf, const char *fmt, ...) 134{ 135 va_list argList; 136 int ret; 137 138 va_start(argList, fmt); 139 ret = LosBufVprintf(seqBuf, fmt, argList); 140 va_end(argList); 141 142 return ret; 143} 144 145int LosBufRelease(struct SeqBuf *seqBuf) 146{ 147 if (seqBuf == NULL) { 148 return -LOS_EPERM; 149 } 150 151 if (seqBuf->buf != NULL) { 152 free(seqBuf->buf); 153 seqBuf->buf = NULL; 154 } 155 free(seqBuf); 156 157 return LOS_OK; 158} 159