mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Changing the HTTP's analyzers internals to use 64-bit integers.
(Gregor Maier). This is the patch from #326, plus some cleanup.
This commit is contained in:
parent
80376653c2
commit
714289bd13
13 changed files with 56 additions and 62 deletions
|
@ -140,7 +140,7 @@ bool ChunkedIOFd::Write(Chunk* chunk)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DBG_LOG(DBG_CHUNKEDIO, "write of size %d [%s]",
|
DBG_LOG(DBG_CHUNKEDIO, "write of size %d [%s]",
|
||||||
chunk->len, fmt_bytes(chunk->data, min(20, chunk->len)));
|
chunk->len, fmt_bytes(chunk->data, min((uint32)20, chunk->len)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Reject if our queue of pending chunks is way too large. Otherwise,
|
// Reject if our queue of pending chunks is way too large. Otherwise,
|
||||||
|
@ -427,7 +427,7 @@ bool ChunkedIOFd::Read(Chunk** chunk, bool may_block)
|
||||||
(*chunk)->len & ~FLAG_PARTIAL,
|
(*chunk)->len & ~FLAG_PARTIAL,
|
||||||
(*chunk)->len & FLAG_PARTIAL ? "(P) " : "",
|
(*chunk)->len & FLAG_PARTIAL ? "(P) " : "",
|
||||||
fmt_bytes((*chunk)->data,
|
fmt_bytes((*chunk)->data,
|
||||||
min(20, (*chunk)->len)));
|
min((uint32)20, (*chunk)->len)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( ! ((*chunk)->len & FLAG_PARTIAL) )
|
if ( ! ((*chunk)->len & FLAG_PARTIAL) )
|
||||||
|
|
|
@ -120,7 +120,7 @@ void ContentLine_Analyzer::EndpointEOF(bool is_orig)
|
||||||
DeliverStream(1, (const u_char*) "\n", is_orig);
|
DeliverStream(1, (const u_char*) "\n", is_orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLine_Analyzer::SetPlainDelivery(int length)
|
void ContentLine_Analyzer::SetPlainDelivery(int64_t length)
|
||||||
{
|
{
|
||||||
if ( length < 0 )
|
if ( length < 0 )
|
||||||
internal_error("negative length for plain delivery");
|
internal_error("negative length for plain delivery");
|
||||||
|
@ -154,7 +154,7 @@ void ContentLine_Analyzer::DoDeliver(int len, const u_char* data)
|
||||||
|
|
||||||
if ( plain_delivery_length > 0 )
|
if ( plain_delivery_length > 0 )
|
||||||
{
|
{
|
||||||
int deliver_plain = min(plain_delivery_length, len);
|
int deliver_plain = min(plain_delivery_length, (int64_t)len);
|
||||||
|
|
||||||
last_char = 0; // clear last_char
|
last_char = 0; // clear last_char
|
||||||
plain_delivery_length -= deliver_plain;
|
plain_delivery_length -= deliver_plain;
|
||||||
|
@ -179,7 +179,7 @@ void ContentLine_Analyzer::DoDeliver(int len, const u_char* data)
|
||||||
if ( seq < seq_to_skip )
|
if ( seq < seq_to_skip )
|
||||||
{
|
{
|
||||||
// Skip rest of the data and return
|
// Skip rest of the data and return
|
||||||
int skip_len = seq_to_skip - seq;
|
int64_t skip_len = seq_to_skip - seq;
|
||||||
if ( skip_len > len )
|
if ( skip_len > len )
|
||||||
skip_len = len;
|
skip_len = len;
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ void ContentLine_Analyzer::CheckNUL()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLine_Analyzer::SkipBytesAfterThisLine(int length)
|
void ContentLine_Analyzer::SkipBytesAfterThisLine(int64_t length)
|
||||||
{
|
{
|
||||||
// This is a little complicated because Bro has to handle
|
// This is a little complicated because Bro has to handle
|
||||||
// both CR and CRLF as a line break. When a line is delivered,
|
// both CR and CRLF as a line break. When a line is delivered,
|
||||||
|
@ -326,7 +326,7 @@ void ContentLine_Analyzer::SkipBytesAfterThisLine(int length)
|
||||||
SkipBytes(length);
|
SkipBytes(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLine_Analyzer::SkipBytes(int length)
|
void ContentLine_Analyzer::SkipBytes(int64_t length)
|
||||||
{
|
{
|
||||||
skip_pending = 0;
|
skip_pending = 0;
|
||||||
seq_to_skip = SeqDelivered() + length;
|
seq_to_skip = SeqDelivered() + length;
|
||||||
|
|
|
@ -44,16 +44,16 @@ public:
|
||||||
// mode for next <length> bytes. Plain-delivery data is also passed
|
// mode for next <length> bytes. Plain-delivery data is also passed
|
||||||
// via DeliverStream() and can differentiated by calling
|
// via DeliverStream() and can differentiated by calling
|
||||||
// IsPlainDelivery().
|
// IsPlainDelivery().
|
||||||
void SetPlainDelivery(int length);
|
void SetPlainDelivery(int64_t length);
|
||||||
int GetPlainDeliveryLength() const { return plain_delivery_length; }
|
int64_t GetPlainDeliveryLength() const { return plain_delivery_length; }
|
||||||
bool IsPlainDelivery() { return is_plain; }
|
bool IsPlainDelivery() { return is_plain; }
|
||||||
|
|
||||||
// Skip <length> bytes after this line.
|
// Skip <length> bytes after this line.
|
||||||
// Can be used to skip HTTP data for performance considerations.
|
// Can be used to skip HTTP data for performance considerations.
|
||||||
void SkipBytesAfterThisLine(int length);
|
void SkipBytesAfterThisLine(int64_t length);
|
||||||
void SkipBytes(int length);
|
void SkipBytes(int64_t length);
|
||||||
|
|
||||||
bool IsSkippedContents(int seq, int length)
|
bool IsSkippedContents(int64_t seq, int64_t length)
|
||||||
{ return seq + length <= seq_to_skip; }
|
{ return seq + length <= seq_to_skip; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -71,26 +71,26 @@ protected:
|
||||||
void CheckNUL();
|
void CheckNUL();
|
||||||
|
|
||||||
// Returns the sequence number delivered so far.
|
// Returns the sequence number delivered so far.
|
||||||
int SeqDelivered() const { return seq_delivered_in_lines; }
|
int64_t SeqDelivered() const { return seq_delivered_in_lines; }
|
||||||
|
|
||||||
u_char* buf; // where we build up the body of the request
|
u_char* buf; // where we build up the body of the request
|
||||||
int offset; // where we are in buf
|
int offset; // where we are in buf
|
||||||
int buf_len; // how big buf is, total
|
int buf_len; // how big buf is, total
|
||||||
unsigned int last_char; // last (non-option) character scanned
|
unsigned int last_char; // last (non-option) character scanned
|
||||||
|
|
||||||
int seq; // last seq number
|
int64_t seq; // last seq number
|
||||||
int seq_to_skip;
|
int64_t seq_to_skip;
|
||||||
|
|
||||||
// Seq delivered up to through NewLine() -- it is adjusted
|
// Seq delivered up to through NewLine() -- it is adjusted
|
||||||
// *before* NewLine() is called.
|
// *before* NewLine() is called.
|
||||||
int seq_delivered_in_lines;
|
int64_t seq_delivered_in_lines;
|
||||||
|
|
||||||
// Number of bytes to be skipped after this line. See
|
// Number of bytes to be skipped after this line. See
|
||||||
// comments in SkipBytesAfterThisLine().
|
// comments in SkipBytesAfterThisLine().
|
||||||
int skip_pending;
|
int64_t skip_pending;
|
||||||
|
|
||||||
// Remaining bytes to deliver plain.
|
// Remaining bytes to deliver plain.
|
||||||
int plain_delivery_length;
|
int64_t plain_delivery_length;
|
||||||
int is_plain;
|
int is_plain;
|
||||||
|
|
||||||
// Don't deliver further data.
|
// Don't deliver further data.
|
||||||
|
|
|
@ -735,7 +735,7 @@ int BroFile::Write(const char* data, int len)
|
||||||
while ( len )
|
while ( len )
|
||||||
{
|
{
|
||||||
int outl;
|
int outl;
|
||||||
int inl = min(MIN_BUFFER_SIZE, len);
|
int inl = min(+MIN_BUFFER_SIZE, len);
|
||||||
|
|
||||||
if ( ! EVP_SealUpdate(cipher_ctx, cipher_buffer, &outl,
|
if ( ! EVP_SealUpdate(cipher_ctx, cipher_buffer, &outl,
|
||||||
(unsigned char*)data, inl) )
|
(unsigned char*)data, inl) )
|
||||||
|
|
|
@ -238,7 +238,7 @@ void Gnutella_Analyzer::SendEvents(GnutellaMsgState* p, bool is_orig)
|
||||||
vl->append(new StringVal(p->payload));
|
vl->append(new StringVal(p->payload));
|
||||||
vl->append(new Val(p->payload_len, TYPE_COUNT));
|
vl->append(new Val(p->payload_len, TYPE_COUNT));
|
||||||
vl->append(new Val((p->payload_len <
|
vl->append(new Val((p->payload_len <
|
||||||
min(p->msg_len, GNUTELLA_MAX_PAYLOAD)),
|
min(p->msg_len, (unsigned int)GNUTELLA_MAX_PAYLOAD)),
|
||||||
TYPE_BOOL));
|
TYPE_BOOL));
|
||||||
vl->append(new Val((p->payload_left == 0), TYPE_BOOL));
|
vl->append(new Val((p->payload_left == 0), TYPE_BOOL));
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
u_char msg_type;
|
u_char msg_type;
|
||||||
u_char msg_ttl;
|
u_char msg_ttl;
|
||||||
char payload[GNUTELLA_MAX_PAYLOAD];
|
char payload[GNUTELLA_MAX_PAYLOAD];
|
||||||
int payload_len;
|
unsigned int payload_len;
|
||||||
unsigned int payload_left;
|
unsigned int payload_left;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
16
src/HTTP.cc
16
src/HTTP.cc
|
@ -226,7 +226,7 @@ void HTTP_Entity::DeliverBodyClear(int len, const char* data, int trailing_CRLF)
|
||||||
|
|
||||||
// Returns 1 if the undelivered bytes are completely within the body,
|
// Returns 1 if the undelivered bytes are completely within the body,
|
||||||
// otherwise returns 0.
|
// otherwise returns 0.
|
||||||
int HTTP_Entity::Undelivered(int len)
|
int HTTP_Entity::Undelivered(int64_t len)
|
||||||
{
|
{
|
||||||
if ( DEBUG_http )
|
if ( DEBUG_http )
|
||||||
{
|
{
|
||||||
|
@ -283,7 +283,7 @@ void HTTP_Entity::SubmitData(int len, const char* buf)
|
||||||
MIME_Entity::SubmitData(len, buf);
|
MIME_Entity::SubmitData(len, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTP_Entity::SetPlainDelivery(int length)
|
void HTTP_Entity::SetPlainDelivery(int64_t length)
|
||||||
{
|
{
|
||||||
ASSERT(length >= 0);
|
ASSERT(length >= 0);
|
||||||
ASSERT(length == 0 || ! in_header);
|
ASSERT(length == 0 || ! in_header);
|
||||||
|
@ -302,7 +302,7 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h)
|
||||||
data_chunk_t vt = h->get_value_token();
|
data_chunk_t vt = h->get_value_token();
|
||||||
if ( ! is_null_data_chunk(vt) )
|
if ( ! is_null_data_chunk(vt) )
|
||||||
{
|
{
|
||||||
int n;
|
int64_t n;
|
||||||
if ( atoi_n(vt.length, vt.data, 0, 10, n) )
|
if ( atoi_n(vt.length, vt.data, 0, 10, n) )
|
||||||
content_length = n;
|
content_length = n;
|
||||||
else
|
else
|
||||||
|
@ -409,7 +409,7 @@ void HTTP_Entity::SubmitAllHeaders()
|
||||||
|
|
||||||
HTTP_Message::HTTP_Message(HTTP_Analyzer* arg_analyzer,
|
HTTP_Message::HTTP_Message(HTTP_Analyzer* arg_analyzer,
|
||||||
ContentLine_Analyzer* arg_cl, bool arg_is_orig,
|
ContentLine_Analyzer* arg_cl, bool arg_is_orig,
|
||||||
int expect_body, int init_header_length)
|
int expect_body, int64_t init_header_length)
|
||||||
: MIME_Message (arg_analyzer)
|
: MIME_Message (arg_analyzer)
|
||||||
{
|
{
|
||||||
analyzer = arg_analyzer;
|
analyzer = arg_analyzer;
|
||||||
|
@ -477,7 +477,7 @@ void HTTP_Message::Done(const int interrupted, const char* detail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int HTTP_Message::Undelivered(int len)
|
int HTTP_Message::Undelivered(int64_t len)
|
||||||
{
|
{
|
||||||
if ( ! top_level )
|
if ( ! top_level )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -628,7 +628,7 @@ void HTTP_Message::SubmitEvent(int event_type, const char* detail)
|
||||||
MyHTTP_Analyzer()->HTTP_Event(category, detail);
|
MyHTTP_Analyzer()->HTTP_Event(category, detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTP_Message::SetPlainDelivery(int length)
|
void HTTP_Message::SetPlainDelivery(int64_t length)
|
||||||
{
|
{
|
||||||
content_line->SetPlainDelivery(length);
|
content_line->SetPlainDelivery(length);
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ void HTTP_Message::DeliverEntityData()
|
||||||
total_buffer_size = 0;
|
total_buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HTTP_Message::InitBuffer(int length)
|
int HTTP_Message::InitBuffer(int64_t length)
|
||||||
{
|
{
|
||||||
if ( length <= 0 )
|
if ( length <= 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1633,7 +1633,7 @@ void HTTP_Analyzer::HTTP_MessageDone(int is_orig, HTTP_Message* /* message */)
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTP_Analyzer::InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message,
|
void HTTP_Analyzer::InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message,
|
||||||
bool is_orig, int expect_body, int init_header_length)
|
bool is_orig, int expect_body, int64_t init_header_length)
|
||||||
{
|
{
|
||||||
if ( message )
|
if ( message )
|
||||||
{
|
{
|
||||||
|
|
32
src/HTTP.h
32
src/HTTP.h
|
@ -39,9 +39,9 @@ public:
|
||||||
|
|
||||||
void EndOfData();
|
void EndOfData();
|
||||||
void Deliver(int len, const char* data, int trailing_CRLF);
|
void Deliver(int len, const char* data, int trailing_CRLF);
|
||||||
int Undelivered(int len);
|
int Undelivered(int64_t len);
|
||||||
int BodyLength() const { return body_length; }
|
int64_t BodyLength() const { return body_length; }
|
||||||
int HeaderLength() const { return header_length; }
|
int64_t HeaderLength() const { return header_length; }
|
||||||
void SkipBody() { deliver_body = 0; }
|
void SkipBody() { deliver_body = 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -50,11 +50,11 @@ protected:
|
||||||
|
|
||||||
HTTP_Message* http_message;
|
HTTP_Message* http_message;
|
||||||
int chunked_transfer_state;
|
int chunked_transfer_state;
|
||||||
int content_length;
|
int64_t content_length;
|
||||||
int expect_data_length;
|
int64_t expect_data_length;
|
||||||
int expect_body;
|
int expect_body;
|
||||||
int body_length;
|
int64_t body_length;
|
||||||
int header_length;
|
int64_t header_length;
|
||||||
int deliver_body;
|
int deliver_body;
|
||||||
enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding;
|
enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding;
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
|
@ -68,7 +68,7 @@ protected:
|
||||||
|
|
||||||
void SubmitData(int len, const char* buf);
|
void SubmitData(int len, const char* buf);
|
||||||
|
|
||||||
void SetPlainDelivery(int length);
|
void SetPlainDelivery(int64_t length);
|
||||||
|
|
||||||
void SubmitHeader(MIME_Header* h);
|
void SubmitHeader(MIME_Header* h);
|
||||||
void SubmitAllHeaders();
|
void SubmitAllHeaders();
|
||||||
|
@ -94,12 +94,12 @@ enum {
|
||||||
class HTTP_Message : public MIME_Message {
|
class HTTP_Message : public MIME_Message {
|
||||||
public:
|
public:
|
||||||
HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl,
|
HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl,
|
||||||
bool is_orig, int expect_body, int init_header_length);
|
bool is_orig, int expect_body, int64_t init_header_length);
|
||||||
~HTTP_Message();
|
~HTTP_Message();
|
||||||
void Done(const int interrupted, const char* msg);
|
void Done(const int interrupted, const char* msg);
|
||||||
void Done() { Done(0, "message ends normally"); }
|
void Done() { Done(0, "message ends normally"); }
|
||||||
|
|
||||||
int Undelivered(int len);
|
int Undelivered(int64_t len);
|
||||||
|
|
||||||
void BeginEntity(MIME_Entity* /* entity */);
|
void BeginEntity(MIME_Entity* /* entity */);
|
||||||
void EndEntity(MIME_Entity* entity);
|
void EndEntity(MIME_Entity* entity);
|
||||||
|
@ -111,7 +111,7 @@ public:
|
||||||
void SubmitEvent(int event_type, const char* detail);
|
void SubmitEvent(int event_type, const char* detail);
|
||||||
|
|
||||||
void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */);
|
void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */);
|
||||||
void SetPlainDelivery(int length);
|
void SetPlainDelivery(int64_t length);
|
||||||
void SkipEntityData();
|
void SkipEntityData();
|
||||||
|
|
||||||
HTTP_Analyzer* MyHTTP_Analyzer() const
|
HTTP_Analyzer* MyHTTP_Analyzer() const
|
||||||
|
@ -135,16 +135,16 @@ protected:
|
||||||
|
|
||||||
double start_time;
|
double start_time;
|
||||||
|
|
||||||
int body_length; // total length of entity bodies
|
int64_t body_length; // total length of entity bodies
|
||||||
int header_length; // total length of headers, including the request/reply line
|
int64_t header_length; // total length of headers, including the request/reply line
|
||||||
|
|
||||||
// Total length of content gaps that are "successfully" skipped.
|
// Total length of content gaps that are "successfully" skipped.
|
||||||
// Note: this might NOT include all content gaps!
|
// Note: this might NOT include all content gaps!
|
||||||
int content_gap_length;
|
int64_t content_gap_length;
|
||||||
|
|
||||||
HTTP_Entity* current_entity;
|
HTTP_Entity* current_entity;
|
||||||
|
|
||||||
int InitBuffer(int length);
|
int InitBuffer(int64_t length);
|
||||||
void DeliverEntityData();
|
void DeliverEntityData();
|
||||||
|
|
||||||
Val* BuildMessageStat(const int interrupted, const char* msg);
|
Val* BuildMessageStat(const int interrupted, const char* msg);
|
||||||
|
@ -191,7 +191,7 @@ protected:
|
||||||
int HTTP_ReplyLine(const char* line, const char* end_of_line);
|
int HTTP_ReplyLine(const char* line, const char* end_of_line);
|
||||||
|
|
||||||
void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig,
|
void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig,
|
||||||
int expect_body, int init_header_length);
|
int expect_body, int64_t init_header_length);
|
||||||
|
|
||||||
const char* PrefixMatch(const char* line, const char* end_of_line,
|
const char* PrefixMatch(const char* line, const char* end_of_line,
|
||||||
const char* prefix);
|
const char* prefix);
|
||||||
|
|
|
@ -2394,7 +2394,7 @@ bool RemoteSerializer::SendPrintHookEvent(BroFile* f, const char* txt)
|
||||||
if ( ! fname )
|
if ( ! fname )
|
||||||
continue; // not a managed file.
|
continue; // not a managed file.
|
||||||
|
|
||||||
int len = strlen(txt);
|
long unsigned int len = strlen(txt);
|
||||||
|
|
||||||
// We cut off everything after the max buffer size. That
|
// We cut off everything after the max buffer size. That
|
||||||
// makes the code a bit easier, and we shouldn't have such
|
// makes the code a bit easier, and we shouldn't have such
|
||||||
|
|
|
@ -397,7 +397,7 @@ bool XMLSerializationFormat::Write(char v, const char* tag)
|
||||||
|
|
||||||
bool XMLSerializationFormat::Write(uint16 v, const char* tag)
|
bool XMLSerializationFormat::Write(uint16 v, const char* tag)
|
||||||
{
|
{
|
||||||
const char* tmp = fmt("%"PRIu16, v);
|
const char* tmp = fmt("%" PRIu16, v);
|
||||||
return WriteElem(tag, "uint16", tmp, strlen(tmp));
|
return WriteElem(tag, "uint16", tmp, strlen(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -630,7 +630,7 @@ function strip%(str: string%): string
|
||||||
function string_fill%(len: int, source: string%): string
|
function string_fill%(len: int, source: string%): string
|
||||||
%{
|
%{
|
||||||
const u_char* src = source->Bytes();
|
const u_char* src = source->Bytes();
|
||||||
int n = source->Len();
|
int64_t n = source->Len();
|
||||||
char* dst = new char[len];
|
char* dst = new char[len];
|
||||||
|
|
||||||
for ( int i = 0; i < len; i += n )
|
for ( int i = 0; i < len; i += n )
|
||||||
|
|
|
@ -295,9 +295,9 @@ char* strcasestr(const char* s, const char* find)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int atoi_n(int len, const char* s, const char** end, int base, int& result)
|
template<class T> int atoi_n(int len, const char* s, const char** end, int base, T& result)
|
||||||
{
|
{
|
||||||
int n = 0;
|
T n = 0;
|
||||||
int neg = 0;
|
int neg = 0;
|
||||||
|
|
||||||
if ( len > 0 && *s == '-' )
|
if ( len > 0 && *s == '-' )
|
||||||
|
@ -340,6 +340,10 @@ int atoi_n(int len, const char* s, const char** end, int base, int& result)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instantiate the ones we need.
|
||||||
|
template int atoi_n<int>(int len, const char* s, const char** end, int base, int& result);
|
||||||
|
template int atoi_n<int64_t>(int len, const char* s, const char** end, int base, int64_t& result);
|
||||||
|
|
||||||
char* uitoa_n(uint64 value, char* str, int n, int base)
|
char* uitoa_n(uint64 value, char* str, int n, int base)
|
||||||
{
|
{
|
||||||
static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
@ -361,6 +365,7 @@ char* uitoa_n(uint64 value, char* str, int n, int base)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int strstr_n(const int big_len, const u_char* big,
|
int strstr_n(const int big_len, const u_char* big,
|
||||||
const int little_len, const u_char* little)
|
const int little_len, const u_char* little)
|
||||||
{
|
{
|
||||||
|
|
13
src/util.h
13
src/util.h
|
@ -110,8 +110,7 @@ extern int strcasecmp_n(int s_len, const char* s, const char* t);
|
||||||
extern char* strcasestr(const char* s, const char* find);
|
extern char* strcasestr(const char* s, const char* find);
|
||||||
#endif
|
#endif
|
||||||
extern const char* strpbrk_n(size_t len, const char* s, const char* charset);
|
extern const char* strpbrk_n(size_t len, const char* s, const char* charset);
|
||||||
extern int atoi_n(int len, const char* s, const char** end,
|
template<class T> int atoi_n(int len, const char* s, const char** end, int base, T& result);
|
||||||
int base, int& result);
|
|
||||||
extern char* uitoa_n(uint64 value, char* str, int n, int base);
|
extern char* uitoa_n(uint64 value, char* str, int n, int base);
|
||||||
int strstr_n(const int big_len, const unsigned char* big,
|
int strstr_n(const int big_len, const unsigned char* big,
|
||||||
const int little_len, const unsigned char* little);
|
const int little_len, const unsigned char* little);
|
||||||
|
@ -234,16 +233,6 @@ extern struct timeval double_to_timeval(double t);
|
||||||
// Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b.
|
// Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b.
|
||||||
extern int time_compare(struct timeval* tv_a, struct timeval* tv_b);
|
extern int time_compare(struct timeval* tv_a, struct timeval* tv_b);
|
||||||
|
|
||||||
inline int min(int a, int b)
|
|
||||||
{
|
|
||||||
return a < b ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int max(int a, int b)
|
|
||||||
{
|
|
||||||
return a > b ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For now, don't use hash_maps - they're not fully portable.
|
// For now, don't use hash_maps - they're not fully portable.
|
||||||
#if 0
|
#if 0
|
||||||
// Use for hash_map's string keys.
|
// Use for hash_map's string keys.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue