?? bintools.c
字號(hào):
// ----------------------------------------------------------------------------// 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);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -