From 84dd33ade1deac07cecafcb79d176e27e436707b Mon Sep 17 00:00:00 2001 From: stan Date: Sat, 13 Mar 2004 14:06:53 +0000 Subject: [PATCH] Added regular expression and memory buffer files. git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@944 e3e1d417-86f3-4887-817a-d78f3d33393f --- src/Makefile.am | 6 +- src/Makefile.in | 22 +++++-- src/zm_buffer.cpp | 65 +++++++++++++++++++ src/zm_buffer.h | 161 ++++++++++++++++++++++++++++++++++++++++++++++ src/zm_regexp.cpp | 114 ++++++++++++++++++++++++++++++++ src/zm_regexp.h | 57 ++++++++++++++++ 6 files changed, 417 insertions(+), 8 deletions(-) create mode 100644 src/zm_buffer.cpp create mode 100644 src/zm_buffer.h create mode 100644 src/zm_regexp.cpp create mode 100644 src/zm_regexp.h diff --git a/src/Makefile.am b/src/Makefile.am index 9461791dd..e2a9f37a4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,6 +31,8 @@ zm_SOURCES = \ zm_remote_camera.cpp \ zm_monitor.cpp \ zm_mpeg.cpp \ + zm_regexp.cpp \ + zm_buffer.cpp \ zm_debug.c \ zm_jpeg.c @@ -62,7 +64,9 @@ noinst_HEADERS = \ jinclude.h \ zmf.h \ zm_jpeg.h \ - zm_mpeg.h + zm_mpeg.h \ + zm_regexp.h \ + zm_buffer.h EXTRA_DIST = zm_config.h.z diff --git a/src/Makefile.in b/src/Makefile.in index 9b5680fad..caa3b18e6 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -122,6 +122,8 @@ zm_SOURCES = \ zm_remote_camera.cpp \ zm_monitor.cpp \ zm_mpeg.cpp \ + zm_regexp.cpp \ + zm_buffer.cpp \ zm_debug.c \ zm_jpeg.c @@ -154,7 +156,9 @@ noinst_HEADERS = \ jinclude.h \ zmf.h \ zm_jpeg.h \ - zm_mpeg.h + zm_mpeg.h \ + zm_regexp.h \ + zm_buffer.h EXTRA_DIST = zm_config.h.z @@ -170,8 +174,8 @@ am__objects_1 = zm.$(OBJEXT) zm_db.$(OBJEXT) zm_config.$(OBJEXT) \ zm_coord.$(OBJEXT) zm_box.$(OBJEXT) zm_image.$(OBJEXT) \ zm_event.$(OBJEXT) zm_zone.$(OBJEXT) zm_camera.$(OBJEXT) \ zm_local_camera.$(OBJEXT) zm_remote_camera.$(OBJEXT) \ - zm_monitor.$(OBJEXT) zm_mpeg.$(OBJEXT) zm_debug.$(OBJEXT) \ - zm_jpeg.$(OBJEXT) + zm_monitor.$(OBJEXT) zm_mpeg.$(OBJEXT) zm_regexp.$(OBJEXT) \ + zm_buffer.$(OBJEXT) zm_debug.$(OBJEXT) zm_jpeg.$(OBJEXT) am_zma_OBJECTS = zma.$(OBJEXT) $(am__objects_1) zma_OBJECTS = $(am_zma_OBJECTS) zma_LDADD = $(LDADD) @@ -212,12 +216,14 @@ LIBS = @LIBS@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/zm.Po ./$(DEPDIR)/zm_box.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/zm_camera.Po ./$(DEPDIR)/zm_config.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/zm_coord.Po ./$(DEPDIR)/zm_db.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/zm_debug.Po ./$(DEPDIR)/zm_event.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/zm_image.Po ./$(DEPDIR)/zm_jpeg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/zm_buffer.Po ./$(DEPDIR)/zm_camera.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/zm_config.Po ./$(DEPDIR)/zm_coord.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/zm_db.Po ./$(DEPDIR)/zm_debug.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/zm_event.Po ./$(DEPDIR)/zm_image.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/zm_jpeg.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/zm_local_camera.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/zm_monitor.Po ./$(DEPDIR)/zm_mpeg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/zm_regexp.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/zm_remote_camera.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/zm_zone.Po ./$(DEPDIR)/zma.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/zmc.Po ./$(DEPDIR)/zmf.Po \ @@ -301,6 +307,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_box.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_camera.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_coord.Po@am__quote@ @@ -312,6 +319,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_local_camera.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_mpeg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_regexp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_remote_camera.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_zone.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zma.Po@am__quote@ diff --git a/src/zm_buffer.cpp b/src/zm_buffer.cpp new file mode 100644 index 000000000..add48cfb3 --- /dev/null +++ b/src/zm_buffer.cpp @@ -0,0 +1,65 @@ +/* + * ZoneMinder flexible memory class implementation, $Date$, $Revision$ + * Copyright (C) 2003 Philip Coombes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +#include "zm.h" +#include "zm_buffer.h" + +unsigned int Buffer::Assign( const unsigned char *p_storage, unsigned int p_size ) +{ + delete[] storage; + size = allocation = p_size; + head = storage = new unsigned char[size]; + memcpy( storage, p_storage, size ); + tail = head + size; + return( size ); +} + +unsigned int Buffer::Expand( unsigned int count ) +{ + int spare = allocation - size; + int head_space = head - storage; + int tail_space = spare - head_space; + int width = tail - head; + if ( spare > count ) + { + if ( tail_space < count ) + { + memmove( storage, head, size ); + head = storage; + tail = head + width; + } + } + else + { + allocation += count; + unsigned char *new_storage = new unsigned char[allocation]; + if ( storage ) + { + memcpy( new_storage, storage, size ); + delete[] storage; + } + storage = new_storage; + head = storage; + tail = head + width; + } + size += count; + return( size ); +} diff --git a/src/zm_buffer.h b/src/zm_buffer.h new file mode 100644 index 000000000..4e88451cd --- /dev/null +++ b/src/zm_buffer.h @@ -0,0 +1,161 @@ +/* + * ZoneMinder Flexible Memory Interface, $Date$, $Revision$ + * Copyright (C) 2003 Philip Coombes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "zm.h" + +#ifndef ZM_BUFFER_H +#define ZM_BUFFER_H + +class Buffer +{ +protected: + unsigned char *storage; + unsigned int allocation; + unsigned int size; + unsigned char *head; + unsigned char *tail; + +public: + Buffer() : storage( 0 ), allocation( 0 ), size( 0 ), head( 0 ), tail( 0 ) + { + } + Buffer( unsigned int p_size ) : allocation( p_size ), size( p_size ) + { + head = storage = new unsigned char[allocation]; + tail = head; + } + Buffer( const unsigned char *p_storage, unsigned int p_size ) : allocation( p_size ), size( p_size ) + { + head = storage = new unsigned char[size]; + memcpy( storage, p_storage, size ); + tail = head + size; + } + Buffer( const Buffer &buffer ) : allocation( buffer.size ), size( buffer.size ) + { + head = storage = new unsigned char[size]; + memcpy( storage, buffer.storage, size ); + tail = head + size; + } + ~Buffer() + { + delete[] storage; + } + void Dump( const char *s="" ) + { + Info(( "%s - Size:%d, Allocation:%d, Storage:%p, Head:%p, Tail:%p", s, size, allocation, storage, head, tail )); + } + void FullDump( const char *s="" ) + { + for ( int i = 0; i < size && i < 100; i++ ) + { + Info(( "%d: %p - %02x\n", i, head+i, *(head+i) )); + } + } + unsigned char *Head() const { return( head ); } + unsigned char *Tail() const { return( tail ); } + unsigned int Size() const { return( size ); } + unsigned int Size( unsigned int p_size ) + { + if ( size < p_size ) + { + Expand( p_size ); + } + return( size ); + } + //unsigned int Allocation() const { return( allocation ); } + + void Empty() + { + size = 0; + tail = head; + } + + unsigned int Assign( const unsigned char *p_storage, unsigned int p_size ); + unsigned int Assign( const Buffer &buffer ) + { + return( Assign( buffer.storage, buffer.size ) ); + } + + unsigned int Consume( unsigned int count ) + { + head += count; + size -= count; + return( size ); + } + unsigned int Shrink( unsigned int count ) + { + size -= count; + if ( tail > head + size ) + tail = head + size; + return( size ); + } + unsigned int Expand( unsigned int count ); + unsigned char *Extract( unsigned int p_size ) + { + unsigned char *old_head = head; + head += p_size; + size -= p_size; + return( old_head ); + } + unsigned int Append( const unsigned char *p_storage, unsigned int p_size ) + { + Expand( p_size ); + memcpy( tail, p_storage, p_size ); + tail += p_size; + return( size ); + } + unsigned int Append( const Buffer &buffer ) + { + return( Append( buffer.head, buffer.size ) ); + } + + Buffer &operator+=( const Buffer &buffer ) + { + Append( buffer ); + return( *this ); + } + Buffer &operator+=( unsigned int count ) + { + Expand( count ); + return( *this ); + } + Buffer &operator-=( unsigned int count ) + { + Consume( count ); + return( *this ); + } + operator unsigned char *() const + { + return( head ); + } + operator char *() const + { + return( (char *)head ); + } + operator unsigned int () const + { + return( size ); + } + operator int () const + { + return( (int)size ); + } +}; + +#endif // ZM_BUFFER_H diff --git a/src/zm_regexp.cpp b/src/zm_regexp.cpp new file mode 100644 index 000000000..5b6b70f92 --- /dev/null +++ b/src/zm_regexp.cpp @@ -0,0 +1,114 @@ +/* + * ZoneMinder regular expression class implementation, $Date$, $Revision$ + * Copyright (C) 2003 Philip Coombes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +#include "zm.h" +#include "zm_regexp.h" + +#if HAVE_LIBPCRE + +RegExpr::RegExpr( const char *pattern, int flags, int p_max_matches ) : max_matches( p_max_matches ), match_buffers( 0 ) +{ + const char *errstr; + int erroffset = 0; + if ( !(regex = pcre_compile( pattern, flags, &errstr, &erroffset, 0 )) ) + { + Fatal(( "pcre_compile(%s): %s at %d", pattern, errstr, erroffset )); + } + + regextra = pcre_study( regex, 0, &errstr ); + if ( errstr ) + { + Fatal(( "pcre_study(%s): %s", pattern, errstr )); + } + + if ( ok = (bool)regex ) + { + match_vectors = new int[3*max_matches]; + match_buffers = new char *[max_matches]; + memset( match_buffers, 0, sizeof(*match_buffers)*max_matches ); + } + n_matches = 0; +} + +RegExpr::~RegExpr() +{ + for ( int i = 0; i < max_matches; i++ ) + { + if ( match_buffers[i] ) + { + delete[] match_buffers[i]; + } + } + delete[] match_buffers; + delete[] match_vectors; +} + +int RegExpr::Match( const char *subject_string, int subject_length, int flags ) +{ + match_string = subject_string; + + n_matches = pcre_exec( regex, regextra, subject_string, subject_length, 0, flags, match_vectors, 2*max_matches ); + + if ( n_matches < 0 ) + { + if ( n_matches < PCRE_ERROR_NOMATCH ) + { + Error(( "Error %d executing regular expression", n_matches )); + } + return( n_matches = 0 ); + } + + for( int i = 0; i < max_matches; i++ ) + { + if ( match_vectors[2*i] < 0 ) + break; + delete[] match_buffers[i]; + match_buffers[i] = 0; + } + return( n_matches ); +} + +const char *RegExpr::MatchString( int match_index ) const +{ + if ( match_index > n_matches ) + { + return( 0 ); + } + if ( !match_buffers[match_index] ) + { + int match_len = match_vectors[(2*match_index)+1]-match_vectors[2*match_index]; + char *match_buffer = match_buffers[match_index] = new char[match_len+1]; + memcpy( match_buffer, match_string+match_vectors[2*match_index], match_len ); + match_buffer[match_len] = '\0'; + } + return( match_buffers[match_index] ); +} + +int RegExpr::MatchLength( int match_index ) const +{ + if ( match_index > n_matches ) + { + return( 0 ); + } + return( match_vectors[(2*match_index)+1]-match_vectors[2*match_index] ); +} + +#endif // HAVE_LIBPCRE diff --git a/src/zm_regexp.h b/src/zm_regexp.h new file mode 100644 index 000000000..dbcf631f9 --- /dev/null +++ b/src/zm_regexp.h @@ -0,0 +1,57 @@ +/* + * ZoneMinder Regular Expression Interface, $Date$, $Revision$ + * Copyright (C) 2003 Philip Coombes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "zm.h" + +#if HAVE_LIBPCRE + +#ifndef ZM_REGEXP_H +#define ZM_REGEXP_H + +#include + +class RegExpr +{ +protected: + pcre *regex; + pcre_extra *regextra; + int max_matches; + int *match_vectors; + mutable char **match_buffers; + +protected: + const char *match_string; + int n_matches; + +protected: + bool ok; + +public: + RegExpr( const char *pattern, int cflags=0, int p_max_matches=256 ); + ~RegExpr(); + bool Ok() const { return( ok ); } + int MatchCount() const { return( n_matches ); } + int Match( const char *subject_string, int subject_length, int flags=0 ); + const char *MatchString( int match_index ) const; + int MatchLength( int match_index ) const; +}; + +#endif // ZM_REGEXP_H + +#endif // HAVE_LIBPCRE