CSE 532S Interceptor Studio
Please complete the required studio exercises listed below, along
with the (optional) enrichment exercises if they interest you.
you work through the exercises, please record your answers in a file,
and upon completion please send an e-mail containing your answers to the firstname.lastname@example.org account, with
subject line Interceptor Studio.
Please make sure that the name of each person
who worked on these exercises is listed at the top of your reply message,
and that you number your answers so they are easy for us to match up with the
Visual Studio 2013 is not successfully compiling ACE on the Windows machines in Urbauer 218, so you should please use Visual Studio 2012 for this studio
(and for subsequent studios and for the lab 3 assignment).
- Please modify your client and server code from the
Acceptor and Connector studio exercises so that a functor
is applied (e.g., using the STL
transform algorithm) to read and possibly modify the
contents of each byte of data passing through the client or server. Initially, this functor should leave
the bytes unmodified and should simply pass them through so the program's behavior remains the same
even with the interceptor in place (you can think if the interceptor being in an inactive status at that
point). Build and test your client and server programs to confirm that the original behavior is preserved.
As the answer to this exercise, please describe how you integrated those interceptors into your client and
- Extend your interceptors from the previous exercise so that either the client, the server, or both, can be
configured with an (admittedly weak) "encryption" functor that performs a reversible operation
on each byte. For example, one functor might use modulus arithmetic to add or subtract a value to or from each
byte, but have the value wrap back around 0 appropriately if the operation exceeds the upper or lower bound of
the value range that the variable can represent. Alternatively, another functor might rotate all the bits of
the value by a given number of positions to the right or to the left.
Configure your client side interceptor to perform one such operation, leaving your server interceptor initially
in its original "pass through" configuration. Build and run your code and verify that the data received by the
server have been modified by the client interceptor. Then, configure your server interceptor to apply the inverse
of the operation that is performed by the client side interceptor. Build and run your code and verify that the
data output by the server are the same as the user input. As the answer to this exercise, please show the
program input and output for both of these trials, which demonstrate those two different behaviors.
- Extend your implementation from the previous exercise so that instead of applying just one functor to each byte,
multiple functors can be applied successively to each byte (e.g., according to the GoF
Chain of Responsibility design pattern,
or via STL functor composition). For example, the client interceptor might modulo-add 17 to each byte and then rotate
the bits in it by two positions to the left. The server interceptor might then rotate the bits in each byte by
two positions to the right, and then modulo-subtract 17 from that value.
As in the previous exercise, configure your client to perform such a chain of operations, and run trials with
the server in pass-through mode (to demonstrate the client interceptor's modifications) and then applying an
inverse-chain to resore the original content that the user typed in. As the answer to this exercise please
describe the client and server functors your trials applied, and how you implemented them.
- Demonstrate the ability to configure different compatible and incompatible combinations of operations in
your client and server interceptors, where compatible means that the server interceptor is able to reverse
the modifications made by the client interceptor. Think about various combinations of each kind, such as
modulus adding one and then modulus subtracting seven in the client interceptor which would be compatible
with simply modulus adding six in the server interceptor. Similarly, some relative permutations of the
order in which chains of operations would be applied will be compatible while others will not. Perform
several different trials to show these capabilities, and as the answer to this exercise, please describe
the trials you ran, what the results were in each case, and show program input and output that demonstrates
Enrichment Exercises (Optional, based on the Extension Interface pattern)
- Modify the interceptor code in your client and server so that
a single functor is used for each basic function (e.g., one for
rotation, another one for addition/subtraction) but is parameterized
with one or more variables that modify the functor's behavior. Each
such functor should have appropriate and well defined semantics for
how it behaves with each possible value of it's parameter(s). For
example, the rotation functor might take an integer that if positive rotates
that many positions to the right, if zero does nothing, and if negative rotates
a number of positions to the left that is given by the absolute value.
Using inheritance, delegation, or any other suitable mechanism you would like,
provide a common "root" interface from which an interface to each functor can be reached,
and which itself can be obtained from the interceptor. As the answer to this exercise,
please describe how you implemented your parameterized functors and their interfaces.
- Implement a basic user interface (similar to the kind of interface we'll look at in the
Component Configurator studio exercises) that lets
the user add, remove, and modify parameters of the different functors in each interceptor.
Repeat the last of the required exercises using the user interface to configure the interceptors
in different ways, and as the answer to this exercise describe how you implemented the user interface
and show program input and output documenting its use in different scenarios.