1f854db0bSPawel Jakub Dawidek /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 33728855aSPedro F. Giffuni * 4f854db0bSPawel Jakub Dawidek * Copyright (c) 2005 Ivan Voras <ivoras@gmail.com> 5f854db0bSPawel Jakub Dawidek * All rights reserved. 6f854db0bSPawel Jakub Dawidek * 7f854db0bSPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 8f854db0bSPawel Jakub Dawidek * modification, are permitted provided that the following conditions 9f854db0bSPawel Jakub Dawidek * are met: 10f854db0bSPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 11f854db0bSPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 12f854db0bSPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 13f854db0bSPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 14f854db0bSPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 15f854db0bSPawel Jakub Dawidek * 16f854db0bSPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17f854db0bSPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18f854db0bSPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19f854db0bSPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20f854db0bSPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21f854db0bSPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22f854db0bSPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23f854db0bSPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24f854db0bSPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25f854db0bSPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26f854db0bSPawel Jakub Dawidek * SUCH DAMAGE. 27f854db0bSPawel Jakub Dawidek */ 28f854db0bSPawel Jakub Dawidek 29f854db0bSPawel Jakub Dawidek // $Id: binstream.c,v 1.1 2006/07/05 10:47:54 ivoras Exp $ 30f854db0bSPawel Jakub Dawidek 31f854db0bSPawel Jakub Dawidek #include <sys/cdefs.h> 32f854db0bSPawel Jakub Dawidek __FBSDID("$FreeBSD$"); 33f854db0bSPawel Jakub Dawidek 34f854db0bSPawel Jakub Dawidek #include <sys/endian.h> 35f854db0bSPawel Jakub Dawidek #include <sys/param.h> 36f854db0bSPawel Jakub Dawidek 37f854db0bSPawel Jakub Dawidek #include <geom/virstor/binstream.h> 38f854db0bSPawel Jakub Dawidek 39f854db0bSPawel Jakub Dawidek /* "Open" a binary stream for reading */ 40f854db0bSPawel Jakub Dawidek void 41f854db0bSPawel Jakub Dawidek bs_open(bin_stream_t * bs, void *data) 42f854db0bSPawel Jakub Dawidek { 43f854db0bSPawel Jakub Dawidek bs->data = (char *)data; 44f854db0bSPawel Jakub Dawidek bs->pos = 0; 45f854db0bSPawel Jakub Dawidek } 46f854db0bSPawel Jakub Dawidek 47f854db0bSPawel Jakub Dawidek /* "Reset" position in binary stream to zero */ 48f854db0bSPawel Jakub Dawidek void 49f854db0bSPawel Jakub Dawidek bs_reset(bin_stream_t * bs) 50f854db0bSPawel Jakub Dawidek { 51f854db0bSPawel Jakub Dawidek bs->pos = 0; 52f854db0bSPawel Jakub Dawidek } 53f854db0bSPawel Jakub Dawidek 54f854db0bSPawel Jakub Dawidek /* Write a zero-terminated string; return next position */ 55f854db0bSPawel Jakub Dawidek unsigned 56f854db0bSPawel Jakub Dawidek bs_write_str(bin_stream_t * bs, char *data) 57f854db0bSPawel Jakub Dawidek { 58f854db0bSPawel Jakub Dawidek int len = 0; 59f854db0bSPawel Jakub Dawidek do { 60f854db0bSPawel Jakub Dawidek *(bs->data + bs->pos + len) = *data; 61f854db0bSPawel Jakub Dawidek len++; 62f854db0bSPawel Jakub Dawidek } while (*(data++) != '\0'); 63f854db0bSPawel Jakub Dawidek bs->pos += len; 64f854db0bSPawel Jakub Dawidek return bs->pos; 65f854db0bSPawel Jakub Dawidek } 66f854db0bSPawel Jakub Dawidek 67f854db0bSPawel Jakub Dawidek /* Write an arbitrary buffer; return next position */ 68f854db0bSPawel Jakub Dawidek unsigned 69f854db0bSPawel Jakub Dawidek bs_write_buf(bin_stream_t * bs, char *data, unsigned data_size) 70f854db0bSPawel Jakub Dawidek { 71f854db0bSPawel Jakub Dawidek unsigned i; 72f854db0bSPawel Jakub Dawidek for (i = 0; i < data_size; i++) 73f854db0bSPawel Jakub Dawidek *(bs->data + bs->pos + i) = *(data + i); 74f854db0bSPawel Jakub Dawidek bs->pos += data_size; 75f854db0bSPawel Jakub Dawidek return bs->pos; 76f854db0bSPawel Jakub Dawidek } 77f854db0bSPawel Jakub Dawidek 78f854db0bSPawel Jakub Dawidek /* Write a 8bit uint; return next position. */ 79f854db0bSPawel Jakub Dawidek unsigned 80f854db0bSPawel Jakub Dawidek bs_write_u8(bin_stream_t * bs, uint8_t data) 81f854db0bSPawel Jakub Dawidek { 82f854db0bSPawel Jakub Dawidek *((uint8_t *) (bs->data + bs->pos)) = data; 83f854db0bSPawel Jakub Dawidek return ++(bs->pos); 84f854db0bSPawel Jakub Dawidek } 85f854db0bSPawel Jakub Dawidek 86f854db0bSPawel Jakub Dawidek /* Write a 16bit uint; return next position. */ 87f854db0bSPawel Jakub Dawidek unsigned 88f854db0bSPawel Jakub Dawidek bs_write_u16(bin_stream_t * bs, uint16_t data) 89f854db0bSPawel Jakub Dawidek { 90f854db0bSPawel Jakub Dawidek le16enc(bs->data + bs->pos, data); 91f854db0bSPawel Jakub Dawidek return (bs->pos += 2); 92f854db0bSPawel Jakub Dawidek } 93f854db0bSPawel Jakub Dawidek 94f854db0bSPawel Jakub Dawidek /* Write a 32bit uint; return next position. */ 95f854db0bSPawel Jakub Dawidek unsigned 96f854db0bSPawel Jakub Dawidek bs_write_u32(bin_stream_t * bs, uint32_t data) 97f854db0bSPawel Jakub Dawidek { 98f854db0bSPawel Jakub Dawidek le32enc(bs->data + bs->pos, data); 99f854db0bSPawel Jakub Dawidek return (bs->pos += 4); 100f854db0bSPawel Jakub Dawidek } 101f854db0bSPawel Jakub Dawidek 102f854db0bSPawel Jakub Dawidek /* Write a 64bit uint; return next position. */ 103f854db0bSPawel Jakub Dawidek unsigned 104f854db0bSPawel Jakub Dawidek bs_write_u64(bin_stream_t * bs, uint64_t data) 105f854db0bSPawel Jakub Dawidek { 106f854db0bSPawel Jakub Dawidek le64enc(bs->data + bs->pos, data); 107f854db0bSPawel Jakub Dawidek return (bs->pos += 8); 108f854db0bSPawel Jakub Dawidek } 109f854db0bSPawel Jakub Dawidek 110f854db0bSPawel Jakub Dawidek /* Read a 8bit uint & return it */ 111f854db0bSPawel Jakub Dawidek uint8_t 112f854db0bSPawel Jakub Dawidek bs_read_u8(bin_stream_t * bs) 113f854db0bSPawel Jakub Dawidek { 114f854db0bSPawel Jakub Dawidek uint8_t data = *((uint8_t *) (bs->data + bs->pos)); 115f854db0bSPawel Jakub Dawidek bs->pos++; 116f854db0bSPawel Jakub Dawidek return data; 117f854db0bSPawel Jakub Dawidek } 118f854db0bSPawel Jakub Dawidek 119f854db0bSPawel Jakub Dawidek /* 120f854db0bSPawel Jakub Dawidek * Read a null-terminated string from stream into a buffer; buf_size is size 121f854db0bSPawel Jakub Dawidek * of the buffer, including the final \0. Returns buf pointer or NULL if 122f854db0bSPawel Jakub Dawidek * garbage input. 123f854db0bSPawel Jakub Dawidek */ 124f854db0bSPawel Jakub Dawidek char* 125f854db0bSPawel Jakub Dawidek bs_read_str(bin_stream_t * bs, char *buf, unsigned buf_size) 126f854db0bSPawel Jakub Dawidek { 127f854db0bSPawel Jakub Dawidek unsigned len = 0; 128f854db0bSPawel Jakub Dawidek char *work_buf = buf; 129f854db0bSPawel Jakub Dawidek if (buf == NULL || buf_size < 1) 130f854db0bSPawel Jakub Dawidek return NULL; 131f854db0bSPawel Jakub Dawidek do { 132f854db0bSPawel Jakub Dawidek *work_buf = *(bs->data + bs->pos + len); 133f854db0bSPawel Jakub Dawidek } while (len++ < buf_size - 1 && *(work_buf++) != '\0'); 134f854db0bSPawel Jakub Dawidek *(buf + buf_size - 1) = '\0'; 135f854db0bSPawel Jakub Dawidek bs->pos += len; 136f854db0bSPawel Jakub Dawidek return buf; 137f854db0bSPawel Jakub Dawidek } 138f854db0bSPawel Jakub Dawidek 139f854db0bSPawel Jakub Dawidek /* Read an arbitrary buffer. */ 140f854db0bSPawel Jakub Dawidek void 141f854db0bSPawel Jakub Dawidek bs_read_buf(bin_stream_t * bs, char *buf, unsigned buf_size) 142f854db0bSPawel Jakub Dawidek { 143f854db0bSPawel Jakub Dawidek unsigned i; 144f854db0bSPawel Jakub Dawidek for (i = 0; i < buf_size; i++) 145f854db0bSPawel Jakub Dawidek *(buf + i) = *(bs->data + bs->pos + i); 146f854db0bSPawel Jakub Dawidek bs->pos += buf_size; 147f854db0bSPawel Jakub Dawidek } 148f854db0bSPawel Jakub Dawidek 149f854db0bSPawel Jakub Dawidek /* Read a 16bit uint & return it */ 150f854db0bSPawel Jakub Dawidek uint16_t 151f854db0bSPawel Jakub Dawidek bs_read_u16(bin_stream_t * bs) 152f854db0bSPawel Jakub Dawidek { 153f854db0bSPawel Jakub Dawidek uint16_t data = le16dec(bs->data + bs->pos); 154f854db0bSPawel Jakub Dawidek bs->pos += 2; 155f854db0bSPawel Jakub Dawidek return data; 156f854db0bSPawel Jakub Dawidek } 157f854db0bSPawel Jakub Dawidek 158f854db0bSPawel Jakub Dawidek /* Read a 32bit uint & return it */ 159f854db0bSPawel Jakub Dawidek uint32_t 160f854db0bSPawel Jakub Dawidek bs_read_u32(bin_stream_t * bs) 161f854db0bSPawel Jakub Dawidek { 162f854db0bSPawel Jakub Dawidek uint32_t data = le32dec(bs->data + bs->pos); 163f854db0bSPawel Jakub Dawidek bs->pos += 4; 164f854db0bSPawel Jakub Dawidek return data; 165f854db0bSPawel Jakub Dawidek } 166f854db0bSPawel Jakub Dawidek 167f854db0bSPawel Jakub Dawidek /* Read a 64bit uint & return it */ 168f854db0bSPawel Jakub Dawidek uint64_t 169f854db0bSPawel Jakub Dawidek bs_read_u64(bin_stream_t * bs) 170f854db0bSPawel Jakub Dawidek { 171f854db0bSPawel Jakub Dawidek uint64_t data = le64dec(bs->data + bs->pos); 172f854db0bSPawel Jakub Dawidek bs->pos += 8; 173f854db0bSPawel Jakub Dawidek return data; 174f854db0bSPawel Jakub Dawidek } 175