作者写了4年C语言,3年java,2年android,n种脚本,发现这些东西都没有大不了的,无非是换个叫法。
有一天要写个C语言的客户端长连接buffer,觉得直觉用数组还是觉得不太好,就把java nio中的buffer给照葫芦画瓢抄了过来,哈哈,感觉不错。
其实很多时候你需要的东西,直接可以从其他语言的底层copy,比你从网上找的不知道那个小瘪三菜鸡写的靠谱1W倍。
好了下面是代码,不懂的搜java的niobuffer,里面有注释
//
// Created by WenYF on 2016/11/2.
//
#include "buffer.h"
typedef struct ifbuffer_struct {
int position;
int limit;
int mark;
int size;
byte *data;
BOOL flip;
} ifbuffer;
// 构造
void* if_buffer_new(int size) {
if (size < 0) {
return NULL;
} else {
int i;
ifbuffer *buffer = (ifbuffer*) malloc (sizeof(ifbuffer));
buffer->data = (byte*) malloc (sizeof(byte) * size);
buffer->size = size;
memset(buffer->data, 0, sizeof(byte) * size);
if_buffer_clear(buffer);
return buffer;
}
}
// 释放
void if_buffer_delete(void *buf) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
if (buffer->data) {
free(buffer->data);
}
free(buffer);
}
}
// return all data array
byte* if_buffer_array(void *buf) {
if (!buf) {
return NULL;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
return buffer->data;
}
}
// limit - position
int if_buffer_remaining(void *buf) {
if (!buf) {
return 0;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
return buffer->limit - buffer->position;
}
}
// 是否还有数据
BOOL if_buffer_hasRemaining(void *buf) {
if (!buf) {
return FALSE;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
return (buffer->limit - buffer->position) > 0 ? TRUE : FALSE;
}
}
// position ++
void if_buffer_put(void *buf, byte one) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->data[buffer->position++] = one;
}
}
// position += length
void if_buffer_putBytes(void *buf, byte *data, int length) {
if (!buf) {
return;
} else {
int i;
ifbuffer *buffer = (ifbuffer*)buf;
for (i = 0; i < length && buffer->position < buffer->limit; i++) {
buffer->data[buffer->position++] = data[i];
}
}
}
// position 置为 mark
void if_buffer_reset(void *buf) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->position = buffer->mark;
}
}
// mark = -1, position = 0
void if_buffer_rewind(void *buf) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->mark = -1;
buffer->position = 0;
}
}
// mark = -1, position = 0, limit = size
void if_buffer_clear(void *buf) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->mark = -1;
buffer->position = 0;
buffer->limit = buffer->size;
buffer->flip = FALSE;
}
}
// mark = position
void if_buffer_mark(void *buf) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->mark = buffer->position;
}
}
// limit = position, position = 0, mark = -1
void if_buffer_flip(void *buf) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->limit = buffer->position;
buffer->position = 0;
buffer->mark = -1;
buffer->flip = TRUE;
}
}
static void showNotFlipNotice(ifbuffer *buffer) {
if (!buffer->flip) {
logW("do you forget call flip()? ignore if you have done it!");
}
}
// position++
byte if_buffer_get(void *buf) {
if (!buf) {
return 0;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
showNotFlipNotice(buffer);
if (buffer->position >= buffer->limit) {
return 0;
} else {
return buffer->data[buffer->position++];
}
}
}
// position += 2
short if_buffer_getShort(void *buf) {
if (!buf) {
return 0;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
showNotFlipNotice(buffer);
if (buffer->position + 1 >= buffer->limit) {
return 0;
} else {
short st = (short)0;
short h = buffer->data[buffer->position++];
short l = buffer->data[buffer->position++];
st = st | (h << 8);
st = st | l;
return st;
}
}
}
// position += 4
int if_buffer_getInt(void *buf) {
if (!buf) {
return 0;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
showNotFlipNotice(buffer);
if (buffer->position + 3 >= buffer->limit) {
return 0;
} else {
int it = 0;
int hh = buffer->data[buffer->position++];
int hl = buffer->data[buffer->position++];
int lh = buffer->data[buffer->position++];
int ll = buffer->data[buffer->position++];
it = it | (hh << 24);
it = it | (hl << 16);
it = it | (lh << 8);
it = it | ll;
return it;
}
}
}
// position += length
void if_buffer_getBytes(void *buf, byte *data, int length) {
if (!buf) {
return;
} else {
int i;
ifbuffer *buffer = (ifbuffer*)buf;
showNotFlipNotice(buffer);
for (i = 0; i < length && buffer->position < buffer->limit; i++) {
data[i] = buffer->data[buffer->position++];
}
}
}
// set position
void if_buffer_setPosition(void *buf, int position) {
if (!buf) {
return;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
buffer->position = position;
}
}
// return position
int if_buffer_position(void *buf) {
if (!buf) {
return -1;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
return buffer->position;
}
}
// return limit
int if_buffer_limit(void *buf) {
if (!buf) {
return -1;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
return buffer->limit;
}
}
// return size
int if_buffer_size(void *buf) {
if (!buf) {
return -1;
} else {
ifbuffer *buffer = (ifbuffer*)buf;
return buffer->size;
}
}
static char* if_buffer_str_cat(char *dst, char *str) {
return strcat(dst, str);
}
// print hex
void if_buffer_printHex(void *buf) {
#ifndef IFCLIENT_ENABLE_DEBUG
return;
#endif
if (!buf) {
return;
} else {
int i;
char tmp[4] = {0};
ifbuffer *buffer = (ifbuffer*)buf;
byte *data = buffer->data + buffer->position;
int length = buffer->limit - buffer->position;
char *dst = (char*) malloc (sizeof(char) * length * 4);
memset(dst, 0, sizeof(char) * length * 4);
for (i = 0; i < length; i++) {
if (i == 0) {
sprintf(tmp, "%02x", buffer->data[i]);
if_buffer_str_cat(dst, tmp);
} else if (i % 16 == 0) {
sprintf(tmp, "\n%x", buffer->data[i]);
if_buffer_str_cat(dst, tmp);
} else {
sprintf(tmp, " %02x", buffer->data[i]);
if_buffer_str_cat(dst, tmp);
}
}
logD("%s", dst);
free(dst);
}
}
有需要的可以直接看GIT上的代码,很简单,轻量级。
下一篇,跨平台C语言长连接之quene数据结构