From: Amos Jeffries Date: Tue, 3 Mar 2015 09:45:37 +0000 (-0800) Subject: Create Packable interface class X-Git-Tag: merge-candidate-3-v1~101^2~13^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d570dc5327a14de7349facb96f0b3217ee98b4ac;p=thirdparty%2Fsquid.git Create Packable interface class Packer class model used C-style function pointers and a standalone object to perform C-style trampoline for function/method calls. C++ virtual methods offer to inline all that directly in the data store objects and enforces type safety on the child object methods instead of forcing manual type casting on developers. Re-implement Packer as a wrapper class providing the Packable interface for backward compatibility with Packer* code. Future code should inherit objects directly from Packable and implement the interface. --- diff --git a/src/Packer.cc b/src/Packer.cc index fcc674cc75..4f51f8d1eb 100644 --- a/src/Packer.cc +++ b/src/Packer.cc @@ -6,38 +6,7 @@ * Please see the COPYING and CONTRIBUTORS files for details. */ -/* DEBUG: section 60 Packer: A uniform interface to store-like modules */ - -/* - * Rationale: - * ---------- - * - * OK, we have two major interfaces comm.c and store.c. - * - * Store.c has a nice storeAppend[Printf] capability which makes "storing" - * things easy and painless. - * - * Comm.c lacks commAppend[Printf] because comm does not handle its own - * buffers (no mem_obj equivalent for comm.c). - * - * Thus, if one wants to be able to store _and_ Comm::Write an object, s/he - * has to implement two almost identical functions. - * - * Packer - * ------ - * - * Packer provides for a more uniform interface to store and comm modules. - * Packer has its own append and printf routines that "know" where to send - * incoming data. In case of store interface, Packer sends data to - * storeAppend. Otherwise, Packer uses a MemBuf that can be flushed later to - * Comm::Write. - * - * Thus, one can write just one function that will either "pack" things for - * Comm::Write or "append" things to store, depending on actual packer - * supplied. - * - * It is amazing how much work a tiny object can save. :) - */ +/* DEBUG: section 60 Generic Data Packer */ #include "squid.h" #include "MemBuf.h" diff --git a/src/Packer.h b/src/Packer.h index 86a37bd6d5..1e630838da 100644 --- a/src/Packer.h +++ b/src/Packer.h @@ -9,6 +9,8 @@ #ifndef SQUID_PACKER_H #define SQUID_PACKER_H +#include "base/Packable.h" + /* see Packer.cc for description */ class Packer; @@ -19,18 +21,14 @@ typedef void (*ObjPackMethod) (void *obj, Packer * p); typedef void (*append_f) (void *, const char *buf, int size); typedef void (*vprintf_f) (void *, const char *fmt, va_list args); -class Packer +class Packer : public Packable { public: virtual ~Packer(); + /* Packable API */ virtual void append(const char *buf, int size); - - /* - * \note we use Printf instead of printf so the compiler won't - * think we're calling the libc printf() - */ virtual void Printf(const char *fmt,...) PRINTF_FORMAT_ARG2; /* protected, use interface functions instead */ diff --git a/src/base/Makefile.am b/src/base/Makefile.am index 8904db7f20..8643df4da2 100644 --- a/src/base/Makefile.am +++ b/src/base/Makefile.am @@ -26,6 +26,7 @@ libbase_la_SOURCES = \ InstanceId.h \ Lock.h \ LruMap.h \ + Packable.h \ RunnersRegistry.cc \ RunnersRegistry.h \ Subscription.h \ diff --git a/src/base/Packable.h b/src/base/Packable.h new file mode 100644 index 0000000000..770bd2cc03 --- /dev/null +++ b/src/base/Packable.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 1996-2015 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_SRC_BASE_PACKABLE_H +#define SQUID_SRC_BASE_PACKABLE_H + +/** + * A uniform interface to store-like modules + * + * Rationale: + * ---------- + * + * We have two major interfaces Comm and Store, which take a variety of + * different data buffering objects and have different output actions + * to be performed on data. + * + * Store has a nice storeAppend[Printf] capability which makes "storing" + * things easy and painless. + * + * Comm lacks commAppend[Printf] because Comm does not handle its own + * buffers (no mem_obj equivalent for Comm). + * + * Thus, if one wants to be able to Store _and_ Comm::Write an object, 'e + * has to implement almost identical functions for using all the data + * storage objects and their associated actions. Doing this for all the + * available data storage types is a tedious nightmare of almost-duplicated + * code. + * + * Packer + * ------ + * + * Objects inheriting from Packable provide a uniform interface for code to + * assemble data before passing to Store and Comm modules. + * + * Packable objects have their own append and printf routines that "know" + * where to send incoming data. In case of Store interface, sending data to + * storeAppend. Packable buffer objects retain the data such that it can be + * flushed later to Comm::Write. + * + * Thus, one can write just one function that will take a Packer* pointer + * and either "pack" things for Comm::Write or "append" things to Store, + * depending on actual Packable object supplied. + */ +class Packable +{ +public: + /// Appends a c-string to existing packed data. + virtual void append(const char *buf, int size) = 0; + + /** + * Append operation with printf-style arguments. + * + * \note we use Printf instead of printf so the compiler won't + * think we're calling the libc printf() + */ + virtual void Printf(const char *fmt,...) PRINTF_FORMAT_ARG2 = 0; +}; + +#endif /* SQUID_SRC_BASE_PACKABLE_H */ +