1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "utils.h" 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar* 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbuff_addc (char* buff, char* buffEnd, int c) 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int avail = buffEnd - buff; 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (avail <= 0) /* already in overflow mode */ 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff; 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (avail == 1) { /* overflowing, the last byte is reserved for zero */ 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[0] = 0; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff + 1; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[0] = (char) c; /* add char and terminating zero */ 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[1] = 0; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff + 1; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar* 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbuff_adds (char* buff, char* buffEnd, const char* s) 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int slen = strlen(s); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff_addb(buff, buffEnd, s, slen); 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar* 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbuff_addb (char* buff, char* buffEnd, const void* data, int len) 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int avail = (buffEnd - buff); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (avail <= 0 || len <= 0) /* already overflowing */ 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len > avail) 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = avail; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(buff, data, len); 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff += len; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* ensure there is a terminating zero */ 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buff >= buffEnd) { /* overflow */ 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[-1] = 0; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[0] = 0; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar* 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbuff_add (char* buff, char* buffEnd, const char* format, ... ) 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int avail; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project avail = (buffEnd - buff); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (avail > 0) { 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list args; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nn; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(args, format); 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nn = vsnprintf( buff, avail, format, args); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(args); 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nn < 0) { 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* some C libraries return -1 in case of overflow, 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * but they will also do that if the format spec is 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * invalid. We assume ADB is not buggy enough to 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * trigger that last case. */ 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nn = avail; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (nn > avail) { 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nn = avail; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff += nn; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* ensure that there is a terminating zero */ 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buff >= buffEnd) 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[-1] = 0; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buff[0] = 0; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buff; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 107