⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bintools.c

📁 Open DMT Client C Source code
💻 C
📖 第 1 页 / 共 2 页
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description://  Binary encoding/decoding. //  Tools to encode/decode binary data.// ---// Change History://  2006/01/04  Martin D. Flynn//     -Initial release//  2007/01/28  Martin D. Flynn//     -WindowsCE port.//     -Added 'p' format to support "padded" strings.// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#define SKIP_TRANSPORT_MEDIA_CHECK // only if TRANSPORT_MEDIA not used in this file #include "custom/defaults.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <ctype.h>#include "custom/log.h"#include "tools/stdtypes.h"#include "tools/strtools.h"#include "tools/gpstools.h"#include "tools/bintools.h"// ----------------------------------------------------------------------------/* initialize buffer */Buffer_t *binBuffer(Buffer_t *bf, UInt8 *data, UInt16 dataSize, BufferType_t type){    if (bf) {        BUFFER_TYPE(bf)         = type;        BUFFER_PTR(bf)          = data;        BUFFER_PTR_SIZE(bf)     = dataSize;        BUFFER_DATA_SIZE(bf)    = dataSize;        BUFFER_DATA_LENGTH(bf)  = (type == BUFFER_SOURCE)? dataSize : 0;        BUFFER_DATA(bf)         = data;    }    return bf;}/* reset buffer to initial state */void binResetBuffer(Buffer_t *bf){    if (bf) {        BUFFER_DATA(bf)= BUFFER_PTR(bf);        if (BUFFER_TYPE(bf) == BUFFER_SOURCE) {            BUFFER_DATA_LENGTH(bf) = (UInt16)BUFFER_PTR_SIZE(bf);            BUFFER_DATA_SIZE(bf)   = (UInt16)BUFFER_PTR_SIZE(bf);        } else        if (BUFFER_TYPE(bf) == BUFFER_DESTINATION) {            BUFFER_DATA_LENGTH(bf) = (UInt16)0;            BUFFER_DATA_SIZE(bf)   = (UInt16)BUFFER_PTR_SIZE(bf);        }    }}/* advance buffer pointer by 'len' bytes */void binAdvanceBuffer(Buffer_t *bf, int len){    // data is being removed from this buffer    if (bf && (len > 0)) {        BUFFER_DATA(bf) += len; // move pointer to next field        if (BUFFER_TYPE(bf) == BUFFER_SOURCE) {            // data is being removed from this buffer            // 'dataLen' is the number of bytes still available in buffer            if (len > BUFFER_DATA_LENGTH(bf)) { len = BUFFER_DATA_LENGTH(bf); }            BUFFER_DATA_LENGTH(bf) -= len; // remaining length is being decreased        } else        if (BUFFER_TYPE(bf) == BUFFER_DESTINATION) {            // data is being added to this buffer            // 'dataLen' is the number of bytes we've placed in the buffer            // 'dataSize' is the number of bytes we have left to place data            if (len > BUFFER_DATA_SIZE(bf)) { len = BUFFER_DATA_SIZE(bf); }            BUFFER_DATA_LENGTH(bf) += len; // length is being increased            BUFFER_DATA_SIZE(bf)   -= len; // remaining size is being decreased        }    }}// ----------------------------------------------------------------------------/* initialize buffer */FmtBuffer_t *binFmtBuffer(FmtBuffer_t *fb, UInt8 *data, UInt16 dataSize, char *fmt, UInt16 fmtSize){    if (fb) {        binBuffer((Buffer_t*)fb, data, dataSize, BUFFER_DESTINATION); // always destination        fb->fmtSize  = fmtSize;        fb->fmtLen   = 0;        fb->fmtPtr   = (UInt8*)fmt;        fb->fmt      = fmt;    }    return fb;}// ----------------------------------------------------------------------------void binAppendFmtField(FmtBuffer_t *fb, UInt16 len, char ch){    if (fb && fb->fmt && (fb->fmtSize >= 6)) {        sprintf(fb->fmt, "%%%d%c", len, ch);        int slen     = strlen(fb->fmt);        fb->fmt     += slen;        fb->fmtLen  += slen;        fb->fmtSize -= slen;    }}void binAppendFmt(FmtBuffer_t *fb, const char *fmt){    int fmtLen = strlen(fmt);    if (fb && fb->fmt && (fb->fmtSize >= fmtLen)) {        strcpy(fb->fmt, fmt);        fb->fmt     += fmtLen;        fb->fmtLen  += fmtLen;        fb->fmtSize -= fmtLen;    }}// ----------------------------------------------------------------------------/* advance buffer pointer by 'len' bytes */void binAdvanceFmtBuffer(FmtBuffer_t *fb, int len){    binAdvanceBuffer((Buffer_t*)fb, len);}// ----------------------------------------------------------------------------// return the minimum number of bytes that will accuately represent this value// The return value will be at-least 1, and at most 4int binGetMinimumInt32Size(UInt32 val, utBool isSigned){    UInt8 mask = (isSigned && (val & 0x80000000L))? 0xFF : 0x00;    int n;    for (n = 3; n >= 1; n--) { // <-- only look at the 3 most-significant bytes        UInt8 x = (UInt8)((val >> (n * 8)) & 0xFF);        if (x != mask) { break; }    }    // 'n' will be '0' if no 'mismatch' was found, thus returning '1'    return n + 1;}// ----------------------------------------------------------------------------/* encode 32-bit value into byte array (Big-Endian) */UInt8 *binEncodeInt32(UInt8 *buf, int cnt, UInt32 val, utBool signExtend){    // - This function places the least-significant bytes of the value 'val' into the    // byte array 'buf'. It is left to the developer to ensure that the size of the    // buffer is large enough to accomodate the value stored in 'val'.    // - 'signExtend' is needed only if 'cnt' is > 4.    if (buf && (cnt > 0)) {                /* fill excess space */        if (cnt > 4) {            UInt8 fill = (signExtend && (val & 0x80000000L))? 0xFF : 0x00;            memset(buf, cnt - 4, fill);            buf += cnt - 4;            cnt = 4;        }        /* copy in value */        int n;        for (n = cnt - 1; n >= 0; n--) {            buf[n] = (UInt8)(val & 0xFF);            val >>= 8;        }            }        return buf;}/* decode byte array into 32-bit value (Native-Endian) */UInt32 binDecodeInt32(const UInt8 *buf, int cnt, utBool signExtend){    // This function decodes the numeric value in 'buf' and returns the resulting    // value as a 32-bit unsigned integer.  If 'signExtend' is true, then sign    // extension will be performed and the returned value can be cast to a signed    // integer to obtain a signed value.    if (buf && (cnt > 0)) {        UInt32 val = (signExtend && (buf[0] & 0x80))? -1L : 0L;        int n;        for (n = 0; n < cnt; n++) {            val = (val << 8) | buf[n];        }        return val;    } else {        return 0L;    }}// ----------------------------------------------------------------------------// Binary format://      %<length><type>// Length://      0..X - fixed field length specifier//      *    - variable field length specifier (argument MUST be of type 'int')// Valid types://      i - signed integer (argument MUST be of type UInt32 or Int32)//      u - unsigned integer (argument MUST be of type UInt32 or Int32)//      x - unsigned integer (argument MUST be of type UInt32 or Int32)//      s - null terminated string (argument must be a pointer to a null-terminated string)//      b - fixed length binary (argument must be a pointer to a byte array)//      g - gps point (argument MUST be a pointer to a GPSShort_t structure)//      z - zero-filled field (no argument)// Example://      This will place the 2 LSBs of 'a', followed by at-most the first 5 bytes of 's'//      into the specified buffer://          binPrintf(buf, sizeof(buf), "%2u%*s", (UInt32)a, 5, s);// Notes://      - The compiler won't validate the format against the actual argument types as it//      does with the 'printf' and 'scanf' functions, so special care must be taken to//      insure that all numeric arguments are always specified as 32-bit variables, and //      lengths are specified as 16-bit variables.int binPrintf(UInt8 *buf, int bufSize, const char *fmt, ...){    va_list ap;    va_start(ap, fmt);    FmtBuffer_t bb,*fb=binFmtBuffer(&bb,buf,bufSize,(char*)0,0); // BUFFER_DESTINATION    int len = binFmtVPrintf(fb, fmt, ap);    va_end(ap);    return len;}int binBufPrintf(Buffer_t *buf, const char *fmt, ...){    if (buf && (BUFFER_TYPE(buf) == BUFFER_DESTINATION)) {        va_list ap;        va_start(ap, fmt);        FmtBuffer_t bb,*fb=binFmtBuffer(&bb,BUFFER_DATA(buf),BUFFER_DATA_SIZE(buf),(char*)0,0);        int len = binFmtVPrintf(fb, fmt, ap);        if (len >= 0) {            binAdvanceBuffer(buf, len);        }        va_end(ap);        return len;    } else {        logERROR(LOGSRC,"Buffer is not designated for BUFFER_DESTINATION\n");        return -1;    }}int binFmtPrintf(FmtBuffer_t *fb, const char *fmt, ...){    va_list ap;    va_start(ap, fmt);    int len = binFmtVPrintf(fb, fmt, ap);    va_end(ap);    return len;}int binVPrintf(UInt8 *buf, UInt16 bufSize, const char *fmt, va_list ap){    FmtBuffer_t bb, *fb = binFmtBuffer(&bb, buf, bufSize, (char*)0, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -