BastEt的博客 http://blog.okbase.net/BastEt 简单的用libevent2+lua写简单的http服务器。注:现在只能单线程,也不能自动重新加载,其实只能做最简单的事情。 http://blog.okbase.net/BastEt/archive/2680.html BastEt 2014/4/7 15:43:18 #include

#include
#include
#include

#pragma comment(lib,"libevent2")
#pragma comment(lib,"lua5")

using namespace luabind;

luabind::object evhttp_request_get_inputhdr(lua_State *L,evhttp_request *req)
{
luabind::object result=luabind::newtable(L);
evkeyvalq *headers = evhttp_request_get_input_headers(req);
for (evkeyval *header = headers->tqh_first; header;header = header->next.tqe_next)
{
result[std::string(header->key)]=std::string(header->value);
}
return result;
}

int evhttp_add_out_hdr(evhttp_request *req,const char *key,const char *value)
{
return evhttp_add_header(evhttp_request_get_output_headers(req),key,value);
}

int evhttp_output(evhttp_request *req,const char *buflen,int bufsize)
{
evbuffer *outbuf=evhttp_request_get_output_buffer(req);
evbuffer_add(outbuf,buflen,bufsize);
return 0;
}

int evhttp_output2(evhttp_request *req,const char *buf)
{
return evhttp_output(req,buf,strlen(buf));
}

int evhttp_output3(evhttp_request *req,std::string buf)
{
return evhttp_output(req,buf.c_str(),buf.size());
}

void http_register_lua(lua_State *L)
{
module(L)
[
class_("httprequest"),
def("evhttp_request_get_command", &evhttp_request_get_command),
def("evhttp_request_get_input_header",&evhttp_request_get_inputhdr),
def("evhttp_request_get_uri",&evhttp_request_get_uri),
def("evhttp_add_output_header",&evhttp_add_out_hdr),
def("evhttp_output",&evhttp_output),
//def("evhttp_output",&evhttp_output2),
def("evhttp_output",&evhttp_output3)
];
}

//1、把所有的东东绑定进去。
//2、只绑定需要的
static void http_request_cb(struct evhttp_request *req, void *arg)
{
lua_State *L=(lua_State *)arg;
//这里要取得他的东东,或者是直接用lua来?
evhttp_cmd_type cmd=evhttp_request_get_command(req);

evbuffer *inbuf = evhttp_request_get_input_buffer(req);
//evhttp_send_reply(req, 200, "OK", NULL);


LUABIND_CHECK_STACK(L);

try
{
int ret=call_function(L, "handlehttp",req);
evhttp_send_reply(req, ret, "OK",NULL);
}
catch (luabind::error&)
{
printf("error running function handlehttp: %s",lua_tostring(L, -1));
lua_pop(L, 1);
evhttp_send_error(req, 404, "error running function handlehttp");
}
}

int main(int argc, char* argv[])
{
evthread_use_windows_threads();
event_config *base_cfg=event_config_new();
//event_config_set_flag(base_cfg,EVENT_BASE_FLAG_STARTUP_IOCP);
//event_config_set_num_cpus_hint(base_cfg,ncpucount);
event_base *evt=event_base_new_with_config(base_cfg);
evhttp *http = evhttp_new(evt);
evhttp_set_allowed_methods(http,EVHTTP_REQ_GET|EVHTTP_REQ_POST);
evhttp_bound_socket *listen_socket=evhttp_bind_socket_with_handle(http,"0.0.0.0",80);

lua_State *state=luaL_newstate();
luaL_openlibs(state);
luabind::open(state);
http_register_lua(state);
//第一次执行
luaL_loadfile(state, "D:\\kingsvn\\script\\stkcalc\\debug\\luaweb.lua");
lua_pcall(state, 0, LUA_MULTRET, 0);
evhttp_set_gencb(http,http_request_cb,state);
event_base_dispatch(evt);
return 0;
} ]]>
lua 5.2的一些变化 http://blog.okbase.net/BastEt/archive/2679.html BastEt 2014/4/7 15:43:18 http://pastebin.com/9YGpCZ2F

Lua 5.1 API incompatibility with Lua 5.2 beta rc-2

==Removed==
LUA_GLOBALSINDEX (这个可能要用getglobal来了,)
LUA_ENVIRONINDEX
lua_getfenv
lua_setfenv
luaL_typerror
luaL_putchar
lua_yield

==Compat removed ==
luaI_openlib
luaL_getn
luaL_setn
lua_ref
lua_unref
lua_getref
lua_open
lua_getregistry
lua_getgccount
lua_Chunkreader
lua_Chunkwriter
luaL_reg

==Requires LUA_COMPAT_ALL==
lua_cpcall
lua_strlen
lua_objlen
lua_equal
lua_lessthan

==Signature changed==
lua_pushlstring
lua_pushstring

==Structure changed==
luaL_Buffer
lua_Debug

Other API changes are hidden by macros




]]>
如何替换vc静态库里的全局内存分配器(libcmt.lib)。 http://blog.okbase.net/BastEt/archive/2678.html BastEt 2014/4/7 15:43:18 注:我这里是vc2010的。
SET OUTCMT=newlib\libcmt.lib

LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\malloc.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\free.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\realloc.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\calloc.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\new.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\delete.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\new2.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\delete2.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\align.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\msize.obj %OUTCMT%

LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\heapinit.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\expand.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\heapchk.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\heapwalk.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\heapmin.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\sbheap.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\intel\mt_obj\smalheap.obj %OUTCMT%


LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\mt_obj\recalloc.obj
LIB /IGNORE:4006,4221 /REMOVE:f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\mt_obj\calloc_impl.obj


2、自己写函数,我用的nedmalloc
#include
#include
#include

extern "C"
{
size_t nedmemsize(void * mem);
void nedsetvalue(void *v);
void * nedmalloc(size_t size);
void * nedcalloc(size_t no, size_t size);
void * nedrealloc(void *mem, size_t size);
void nedfree(void *mem);
void * nedmemalign(size_t alignment, size_t bytes);
void * nedmalloc2(size_t size, size_t alignment, unsigned flags);
void * nedrealloc2(void *mem, size_t size, size_t alignment, unsigned flags);
void nedfree2(void *mem, unsigned flags);
int nedmallopt(int parno, int value);
size_t nedmemsize(void *mem);


void * malloc(size_t size)
{
return nedmalloc(size);
}
void * calloc(size_t no, size_t size)
{
return nedcalloc(no,size);
}
void * realloc(void *mem, size_t size)
{
return nedrealloc(mem,size);
}
void free(void *mem)
{
return nedfree(mem);
}
}




extern "C" void* _recalloc(void* p, size_t n, size_t size)
{
void* result = nedrealloc(p, n * size);
memset(result, 0, n * size);
return result;
}

extern "C" void* _calloc_impl(size_t n, size_t size)
{
return nedcalloc(n, size);
}

extern "C" size_t _msize(void* p)
{
return nedmemsize(p);
}

extern "C" intptr_t _get_heap_handle()
{
return 0;
}

// The CRT heap initialization stub.
extern "C" int _heap_init()
{
return 1;
}

// The CRT heap cleanup stub.
extern "C" void _heap_term()
{
}

extern "C" int _set_new_mode(int flag)
{
return 1;
}

// We set this to 1 because part of the CRT uses a check of _crtheap != 0
// to test whether the CRT has been initialized. Once we've ripped out
// the allocators from libcmt, we need to provide this definition so that
// the rest of the CRT is still usable.
extern "C" void* _crtheap = (void*)(1);












void * operator new( size_t cb )
{
return nedmalloc(cb);
}

void operator delete( void * p )
{
nedfree( p );
}

void * operator new[]( size_t cb )
{
void *res = operator new(cb);
return res;
}


void operator delete[]( void * p )
{
operator delete(p);
}

把这个cpp加进你的工程或者生成一个库。
最后就可以了,这样你可以任意自定义你的这些函数了。 ]]>
asio的http服务器 http://blog.okbase.net/BastEt/archive/2677.html BastEt 2014/4/7 15:43:18 这里的加上了keep alive和post的功能,用的全是其他人写好的,别笑话就行了。
http::server::server *pserver=new http::server::server("0.0.0.0","80",1);
new asio::thread(boost::bind(&http::server::server::run,pserver));

http://blog.vckbase.com/Files/BastEt/asiohttpd.zip

注:用的是单独的asio包,这样可能升级比较方便些。

下面这个函数可以看出一共读取了多少,过大的包可以直接关闭掉。
uint64_t recvbytes=htparser_get_bytes_read(_parser);
if(recvbytes>32*1024)
return; ]]>
win下使用freetds来连接sql server http://blog.okbase.net/BastEt/archive/2676.html BastEt 2014/4/7 15:43:18 链接的时候要把缺省的那两个odbc库给去掉,链接到tds的odbc_release下的那个库,
要注意编译tds的时候有个TDS722什么的,这样在连接的时候会使用702协议,有的老协议就使用不了的。(\freetds-0.91\include\tds.h)加上 #define TDS72 1
HENV odbc_env=NULL;
HDBC odbc_conn=NULL;
SQLAllocEnv(&odbc_env);
SQLAllocConnect(odbc_env,&odbc_conn);

char sqlconnstr[256];
//这里一定是Server=???而不是DSN
sprintf(sqlconnstr, "Server=%s;UID=%s;PWD=%s;DATABASE=%s;", "自己填", "自己填", "自己填","");
SQLSMALLINT rc=SQLConnect(odbc_conn,(SQLCHAR *)"210.51.26.239",SQL_NTS,(SQLCHAR *)"SIGNIN_HTQUOTATION2",SQL_NTS,(SQLCHAR *)"lhtK*6q+B->%f-",SQL_NTS);

char tmp[1024];
SQLSMALLINT len;
SQLSMALLINT rc=SQLDriverConnect(odbc_conn,NULL,(SQLCHAR *)sqlconnstr,SQL_NTS,(SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);

HSTMT odbc_stmt=NULL;
SQLAllocStmt(odbc_conn,&odbc_stmt);
rc=SQLExecDirect(odbc_stmt,(SQLCHAR *)"select * from clients",SQL_NTS);
for (rc=SQLFetch(odbc_stmt); rc == SQL_SUCCESS; rc=SQLFetch(odbc_stmt))
{
char buf[256];
SQLLEN retlen=256;
SQLGetData(odbc_stmt,1,SQL_C_CHAR,buf,sizeof(buf),&retlen);

__int64 uid=0;
retlen=sizeof(retlen);
SQLGetData(odbc_stmt,2,SQL_C_SBIGINT,&uid,sizeof(uid),&retlen);

}
SQLFreeStmt(odbc_stmt,SQL_DROP);

SQLDisconnect(odbc_conn);
SQLFreeConnect(odbc_conn);
SQLFreeEnv(odbc_env); ]]>
quickfast 新版中的变化 http://blog.okbase.net/BastEt/archive/2675.html BastEt 2014/4/7 15:43:18 以前是:typedef uint32 field_id_t;

太坑人了。难道以后fieldid有可能是字符串,不是整数?

暂时不太打算升级,这个改起来倒不麻烦,就是没啥大用处啊。

]]>
doxygen生成中文文档的乱码 http://blog.okbase.net/BastEt/archive/2674.html BastEt 2014/4/7 15:43:18 我是这样处理的:
1、用命令行生成(这个可以一次生成,到处使用)
doxygen.exe -w html header.html footer.html style.css
得到三个文件。
2、在那个doxywizard中做的话,output_language是英文(缺省的),所有的其他全是缺省的(什么input encoding啥的)
在html->html_header中输入刚才的header.html所在的目录。
3、生成html文档
如果显示有问题,把刚才生成的style.css直接copy到目标目录中去。 ]]>
晚年张之洞(转) http://blog.okbase.net/BastEt/archive/2673.html BastEt 2014/4/7 15:43:18   当年,津浦铁路督办吕海寰、总办李德顺因强占及廉价收购土地情事为人参劾而连带撤职,载沣在召见军机大臣时提议由唐绍仪接任督办,张之洞以为不可,曰:“唐绍仪不洽舆情,未便继任。”载沣冷笑道:“中堂以乡绅重望,如以为可,谁还能说不可。”张回奏称:“朝廷用人,如不顾舆情,恐怕要激起民变。”载沣说:“有兵在,还怕什么民变。”张愤然:“国家养兵,岂是用来打老百姓的?”君臣不欢而散。张之洞出而咳血,长叹道:“不意闻亡国之言!”次日即病,不再入朝。 ]]> quickfast解析中国的fastfix包--3 http://blog.okbase.net/BastEt/archive/2672.html BastEt 2014/4/7 15:43:18
QQ:43791167,有不对或者好的思路,不妨共享。

一般要修改一些地方,比如说加上decoder的设置模板id,在message里加个成员变量templateid,这样会方便不少。
比如这里可能就可以这样写:
Messages::MessageBuilder &
GenericMessageBuilder::startMessage(
const std::string & applicationType,
const std::string & applicationTypeNamespace,
size_t size,
template_id_t tid)
{
message_.reset(new Messages::Message(size));
message_->setApplicationType(applicationType, applicationTypeNamespace);
message_->settid(tid);
return *this;
}

void
Decoder::decodeMessage(
DataSource & source,
Messages::ValueMessageBuilder & messageBuilder)
这里面就可以:
Messages::ValueMessageBuilder & bodyBuilder(
messageBuilder.startMessage(
templatePtr->getApplicationType(),
templatePtr->getApplicationTypeNamespace(),
templatePtr->fieldCount(),
templateId_));

decodeSegmentBody(source, pmap, templatePtr, bodyBuilder);

还有一些简单的助手函数可以帮助解析。
uint64 getUnsignedInteger2(const field_id_t & identity, uint64 defaultvalue=0)const
{
uint64 value;
if(getUnsignedInteger(identity,value))
return value;
else
return defaultvalue;
}
bool getSignedInteger(const field_id_t & identity, int64 & value)const
{
FieldCPtr field;
bool result = getField(identity, field);
if(result)
{
value = field->toSignedInteger();
}
return result;
}
int64 getSignedInteger2(const field_id_t & identity, int64 defaultvalue=0)const
{
int64 value;
if(getSignedInteger(identity,value))
return value;
else
return defaultvalue;
}
bool getDecimal(const field_id_t & identity, Decimal & value)const
{
FieldCPtr field;
bool result = getField(identity, field);
if(result)
{
value = field->toDecimal();
}
return result;
}
double getDecimal2(const field_id_t & identity, double defaultvalue=0.0f)const
{
Decimal value;
if(getDecimal(identity,value))
return value;
else
return defaultvalue;
}
bool getString(const field_id_t & identity, const StringBuffer *& value)const
{
FieldCPtr field;
bool result = getField(identity, field);
if(result)
{
value = &field->toString();
}
return result;
}
std::string getString2(const field_id_t & identity, const char *defaultstr="")const
{
const StringBuffer *value=NULL;
if(getString(identity,value))
return *value;
else
return defaultstr;
} ]]>
quickfast解析中国的fastfix包--2 http://blog.okbase.net/BastEt/archive/2671.html BastEt 2014/4/7 15:43:18
#pragma once

namespace QuickFAST
{
namespace Messages
{
class FieldSet;
class Sequence;
}
}

extern "C"
{
struct hq_fast_message
{
const QuickFAST::Messages::FieldSet *msg;
};

struct hq_fast_sequence
{
const QuickFAST::Messages::Sequence *seq;
};
int hq_fast_seq_get_size(hq_fast_sequence &sequence);
bool hq_fast_seq_get_msg(hq_fast_sequence &sequence,int index,hq_fast_message &msg);

bool hq_fast_msg_get_uint(hq_fast_message &msg,unsigned int fieldid,unsigned __int64 &value);
bool hq_fast_msg_get_sint(hq_fast_message &msg,unsigned int fieldid,__int64 &value);
bool hq_fast_msg_get_double(hq_fast_message &msg,unsigned int fieldid,double &value);

unsigned __int64 hq_fast_msg_get_uint2(hq_fast_message &msg,unsigned int fieldid,unsigned __int64 defaultvalue=0);
__int64 hq_fast_msg_get_sint2(hq_fast_message &msg,unsigned int fieldid,__int64 defaultvalue=0);
double hq_fast_msg_get_double2(hq_fast_message &msg,unsigned int fieldid,double defaultvalue=0.0f);

int hq_fast_msg_get_str(hq_fast_message &msg,unsigned int fieldid,char *buf,int buflen);

bool hq_fast_msg_get_sequence(hq_fast_message &msg,const char *fieldid,hq_fast_sequence &sequence);
bool hq_fast_msg_get_sequence2(hq_fast_message &msg,unsigned int fieldid,hq_fast_sequence &sequence);

typedef bool (*HQFASTCB)(hq_fast_message &msg,unsigned int tid,void *pdata);

struct hq_fast_decoder;
hq_fast_decoder *hq_fast_create_decoder(const char *xmldeffile);
void hq_fast_decoder_set_cb(hq_fast_decoder &decoder,void *pdata,HQFASTCB cbfunc);
int hq_fast_decoder_parse(hq_fast_decoder &decoder,void *pdata,int datalen);
void hq_fast_reset_decoder(hq_fast_decoder *dc,bool resettempid=true);
void hq_fast_destroy_decoder(hq_fast_decoder *dc);

};


#include
inline std::string hq_fast_msg_get_str2(hq_fast_message &msg,unsigned int fieldid,const char *defaultvalue="")
{
char buf[64]={0};
if(hq_fast_msg_get_str(msg,fieldid,buf,63)<0)
return defaultvalue;
return std::string(buf);
}

#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#include
#include
#include

#include "XmlTemplateParser_Pugixml.h"


class FastFixConsumer : public QuickFAST::Codecs::MessageConsumer
{
public:
FastFixConsumer()
{
pdata=NULL;
cb=NULL;
}

~FastFixConsumer(){}

virtual bool consumeMessage(QuickFAST::Messages::Message & message)
{
if(!cb)
return true;
hq_fast_message msg;
msg.msg=&message;
return cb(msg,message.gettid(),pdata);
}
virtual bool wantLog(unsigned short level){return false;}
virtual bool logMessage(unsigned short level, const std::string & logMessage){return true;}
virtual bool reportDecodingError(const std::string & errorMessage){return true;}
virtual bool reportCommunicationError(const std::string & errorMessage){return true;}
virtual void decodingStarted(){}
virtual void decodingStopped(){}

HQFASTCB cb;
void *pdata;
};

struct hq_fast_decoder
{
public:
QuickFAST::Codecs::Decoder *decoder;
QuickFAST::Codecs::GenericMessageBuilder *builder;
QuickFAST::Codecs::TemplateRegistryPtr tmeplate_registry;
FastFixConsumer msg_consumer;
};

void hq_fast_reset_decoder(hq_fast_decoder *dc,bool resettempid)
{
dc->decoder->reset(resettempid);
}

hq_fast_decoder *hq_fast_create_decoder(const char *xmldeffile)
{
QuickFAST::Codecs::TemplateRegistryPtr tmeplate_registry=QuickFAST::Codecs::parse_template_file(xmldeffile);
if(tmeplate_registry==NULL)
return NULL;
hq_fast_decoder *result=new hq_fast_decoder();
result->tmeplate_registry=tmeplate_registry;
result->builder=new QuickFAST::Codecs::GenericMessageBuilder(result->msg_consumer);
result->decoder=new QuickFAST::Codecs::Decoder(tmeplate_registry);
return result;
}
void hq_fast_decoder_set_cb(hq_fast_decoder &decoder,void *pdata,HQFASTCB cbfunc)
{
decoder.msg_consumer.pdata=pdata;
decoder.msg_consumer.cb=cbfunc;
}
int hq_fast_decoder_parse(hq_fast_decoder &decoder,void *pdata,int datalen)
{
QuickFAST::Codecs::DataSourceBuffer dsb((unsigned char *)pdata,datalen);
int idecodeitems=0;
for(int i=0;i<40960;i++)
{
try
{
if(dsb.bytesAvailable()<=0)
break;
decoder.decoder->decodeMessage(dsb,*decoder.builder);
idecodeitems++;
}
catch(std::exception &excep)
{
//printf("ERROR:%s:%s\n",msgtype.c_str(),excep.what());
break;
}
catch(...)
{
//printf("unknown error:%s\n",msgtype.c_str());
break;
}
}
return idecodeitems;
}
void hq_fast_destroy_decoder(hq_fast_decoder *dc)
{
if(dc==NULL)
return;
delete dc->builder;
delete dc->decoder;
delete dc;
}

bool hq_fast_msg_get_uint(hq_fast_message &msg,unsigned int fieldid,unsigned __int64 &value)
{
return msg.msg->getUnsignedInteger(fieldid,value);
}
bool hq_fast_msg_get_sint(hq_fast_message &msg,unsigned int fieldid,__int64 &value)
{
return msg.msg->getSignedInteger(fieldid,value);
}
bool hq_fast_msg_get_double(hq_fast_message &msg,unsigned int fieldid,double &value)
{
QuickFAST::Decimal decimal;
if(!msg.msg->getDecimal(fieldid,decimal))
return false;
value=decimal;
return true;
}
unsigned __int64 hq_fast_msg_get_uint2(hq_fast_message &msg,unsigned int fieldid,unsigned __int64 defaultvalue)
{
return msg.msg->getSignedInteger2(fieldid,defaultvalue);
}
__int64 hq_fast_msg_get_sint2(hq_fast_message &msg,unsigned int fieldid,__int64 defaultvalue)
{
return msg.msg->getUnsignedInteger2(fieldid,defaultvalue);
}
double hq_fast_msg_get_double2(hq_fast_message &msg,unsigned int fieldid,double defaultvalue)
{
return msg.msg->getDecimal2(fieldid,defaultvalue);
}

int hq_fast_msg_get_str(hq_fast_message &msg,unsigned int fieldid,char *buf,int buflen)
{
const QuickFAST::StringBuffer *buffield=NULL;
if(!msg.msg->getString(fieldid,buffield))
return -1;
int copybytes=buffield->size();
if(copybytes>buflen)
copybytes=buflen;
memcpy(buf,buffield->c_str(),copybytes);
return copybytes;
}

bool hq_fast_msg_get_sequence(hq_fast_message &msg,const char *fieldid,hq_fast_sequence &sequence)
{
sequence.seq=NULL;
QuickFAST::Messages::SequenceCPtr result;
if(!msg.msg->getSequence(fieldid,result))
return false;
sequence.seq=result.get();
return true;
}
bool hq_fast_msg_get_sequence2(hq_fast_message &msg,unsigned int fieldid,hq_fast_sequence &sequence)
{
sequence.seq=NULL;
QuickFAST::Messages::SequenceCPtr result;
if(!msg.msg->getSequence(fieldid,result))
return false;
sequence.seq=result.get();
return true;
}

int hq_fast_seq_get_size(hq_fast_sequence &sequence)
{
return sequence.seq->size();
}
bool hq_fast_seq_get_msg(hq_fast_sequence &sequence,int index,hq_fast_message &msg)
{
msg.msg=NULL;
const QuickFAST::Messages::FieldSetCPtr fsc=sequence.seq->operator[](index);
msg.msg=fsc.get();
return true;
} ]]>