File Coverage

blib/lib/Net/AMQP/PP.pm
Criterion Covered Total %
statement 14 21 66.6
branch n/a
condition n/a
subroutine 5 6 83.3
pod n/a
total 19 27 70.3


line stmt bran cond sub pod time code
1             package Net::AMQP::PP;
2 1     1   1120 use strict;
  1         2  
  1         45  
3 1     1   8 use warnings;
  1         2  
  1         35  
4 1     1   5 use JSON ();
  1         13  
  1         777  
5              
6             our $VERSION = '0.01';
7              
8             my $data = JSON::from_json(
9             q[{"domain":{"delivery tag":{"type":"longlong"},"exchange name":{"type":"shortstr"},"reply code":{"type":"short"},"consumer tag":{"type":"shortstr"},"path":{"type":"shortstr"},"class id":{"type":"short"},"access ticket":{"type":"short"},"queue name":{"type":"shortstr"},"redelivered":{"type":"bit"},"method id":{"type":"short"},"reply text":{"type":"shortstr"},"no local":{"type":"bit"},"known hosts":{"type":"shortstr"},"no ack":{"type":"bit"},"peer properties":{"type":"table"}},"class":{"Exchange":{"handler":"channel","methods":[{"method_id":"10","fields":[{"domain":"access ticket","name":"ticket","doc":"\n\nWhen a client defines a new exchange, this belongs to the access realm of the ticket used. All further work done with that exchange must be done with an access ticket for the same realm. "},{"domain":"exchange name","name":"exchange","doc":""},{"name":"type","doc":"exchange type \n\nEach exchange belongs to one of a set of exchange types implemented by the server. The exchange types define the functionality of the exchange - i.e. how messages are routed through it. It is not valid or meaningful to attempt to change the type of an existing exchange. ","type":"shortstr"},{"name":"passive","doc":"do not create exchange \n\nIf set, the server will not create the exchange. The client can use this to check whether an exchange exists without modifying the server state. ","type":"bit"},{"name":"durable","doc":"request a durable exchange \n\nIf set when creating a new exchange, the exchange will be marked as durable. Durable exchanges remain active when a server restarts. Non-durable exchanges (transient exchanges) are purged if/when a server restarts. ","type":"bit"},{"name":"auto delete","doc":"auto-delete when unused \n\nIf set, the exchange is deleted when all queues have finished using it. ","type":"bit"},{"name":"internal","doc":"create internal exchange \n\nIf set, the exchange may not be used directly by publishers, but only when bound to other exchanges. Internal exchanges are used to construct wiring that is not visible to applications. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"},{"name":"arguments","doc":"arguments for declaration \n\nA set of arguments for the declaration. The syntax and semantics of these arguments depends on the server implementation. This field is ignored if passive is 1. ","type":"table"}],"synchronous":"1","content":null,"name":"Declare","responses":{"Net::AMQP::Protocol::Exchange::DeclareOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"DeclareOk","responses":{}},{"method_id":"20","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"exchange name","name":"exchange","doc":""},{"name":"if unused","doc":"delete only if unused \n\nIf set, the server will only delete the exchange if it has no queue bindings. If the exchange has queue bindings the server does not delete it but raises a channel exception instead. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Delete","responses":{"Net::AMQP::Protocol::Exchange::DeleteOk":1}},{"method_id":"21","fields":[],"synchronous":"1","content":null,"name":"DeleteOk","responses":{}}],"name":"Exchange","class_id":"40"},"Tunnel":{"handler":"tunnel","methods":[{"method_id":"10","fields":[{"name":"meta data","doc":"meta data for the tunnelled block \n\nThis field table holds arbitrary meta-data that the sender needs to pass to the recipient. ","type":"table"}],"synchronous":null,"content":"1","name":"Request","responses":{}},{"method_id":0,"fields":[{"name":"headers","type":"table"},{"name":"proxy name","type":"shortstr"},{"name":"data name","type":"shortstr"},{"name":"durable","type":"octet"},{"name":"broadcast","type":"octet"}],"synchronous":null,"name":"ContentHeader","responses":{}}],"name":"Tunnel","class_id":"110"},"Tx":{"handler":"channel","methods":[{"method_id":"10","fields":[],"synchronous":"1","content":null,"name":"Select","responses":{"Net::AMQP::Protocol::Tx::SelectOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"SelectOk","responses":{}},{"method_id":"20","fields":[],"synchronous":"1","content":null,"name":"Commit","responses":{"Net::AMQP::Protocol::Tx::CommitOk":1}},{"method_id":"21","fields":[],"synchronous":"1","content":null,"name":"CommitOk","responses":{}},{"method_id":"30","fields":[],"synchronous":"1","content":null,"name":"Rollback","responses":{"Net::AMQP::Protocol::Tx::RollbackOk":1}},{"method_id":"31","fields":[],"synchronous":"1","content":null,"name":"RollbackOk","responses":{}}],"name":"Tx","class_id":"90"},"Stream":{"handler":"channel","methods":[{"method_id":"10","fields":[{"name":"prefetch size","doc":"prefetch window in octets \n\nThe client can request that messages be sent in advance so that when the client finishes processing a message, the following message is already held locally, rather than needing to be sent down the channel. Prefetching gives a performance improvement. This field specifies the prefetch window size in octets. May be set to zero, meaning \"no specific limit\". Note that other prefetch limits may still apply. ","type":"long"},{"name":"prefetch count","doc":"prefetch window in messages \n\nSpecifies a prefetch window in terms of whole messages. This field may be used in combination with the prefetch-size field; a message will only be sent in advance if both prefetch windows (and those at the channel and connection level) allow it. ","type":"short"},{"name":"consume rate","doc":"transfer rate in octets/second \n\nSpecifies a desired transfer rate in octets per second. This is usually determined by the application that uses the streaming data. A value of zero means \"no limit\", i.e. as rapidly as possible. ","type":"long"},{"name":"global","doc":"apply to entire connection \n\nBy default the QoS settings apply to the current channel only. If this field is set, they are applied to the entire connection. ","type":"bit"}],"synchronous":"1","content":null,"name":"Qos","responses":{"Net::AMQP::Protocol::Stream::QosOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"QosOk","responses":{}},{"method_id":"20","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to consume from. If the queue name is null, refers to the current queue for the channel, which is the last declared queue. "},{"domain":"consumer tag","name":"consumer tag","doc":"\n\nSpecifies the identifier for the consumer. The consumer tag is local to a connection, so two clients can use the same consumer tags. If this field is empty the server will generate a unique tag. "},{"domain":"no local","name":"no local","doc":""},{"name":"exclusive","doc":"request exclusive access \n\nRequest exclusive consumer access, meaning only this consumer can access the queue. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Consume","responses":{"Net::AMQP::Protocol::Stream::ConsumeOk":1}},{"method_id":"21","fields":[{"domain":"consumer tag","name":"consumer tag","doc":"\n\nHolds the consumer tag specified by the client or provided by the server. "}],"synchronous":"1","content":null,"name":"ConsumeOk","responses":{}},{"method_id":"30","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Cancel","responses":{"Net::AMQP::Protocol::Stream::CancelOk":1}},{"method_id":"31","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""}],"synchronous":"1","content":null,"name":"CancelOk","responses":{}},{"method_id":"40","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange to publish to. The exchange name can be empty, meaning the default exchange. If the exchange name is specified, and that exchange does not exist, the server will raise a channel exception. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key for the message. The routing key is used for routing messages depending on the exchange configuration. ","type":"shortstr"},{"name":"mandatory","doc":"indicate mandatory routing \n\nThis flag tells the server how to react if the message cannot be routed to a queue. If this flag is set, the server will return an unroutable message with a Return method. If this flag is zero, the server silently drops the message. ","type":"bit"},{"name":"immediate","doc":"request immediate delivery \n\nThis flag tells the server how to react if the message cannot be routed to a queue consumer immediately. If this flag is set, the server will return an undeliverable message with a Return method. If this flag is zero, the server will queue the message, but with no guarantee that it will ever be consumed. ","type":"bit"}],"synchronous":null,"content":"1","name":"Publish","responses":{}},{"method_id":"50","fields":[{"domain":"reply code","name":"reply code","doc":""},{"domain":"reply text","name":"reply text","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key name specified when the message was published. ","type":"shortstr"}],"synchronous":null,"content":"1","name":"Return","responses":{}},{"method_id":"60","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""},{"domain":"delivery tag","name":"delivery tag","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. "},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue that the message came from. Note that a single channel can start many consumers on different queues. "}],"synchronous":null,"content":"1","name":"Deliver","responses":{}},{"method_id":0,"fields":[{"name":"content type","type":"shortstr"},{"name":"content encoding","type":"shortstr"},{"name":"headers","type":"table"},{"name":"priority","type":"octet"},{"name":"timestamp","type":"timestamp"}],"synchronous":null,"name":"ContentHeader","responses":{}}],"name":"Stream","class_id":"80"},"Dtx":{"handler":"channel","methods":[{"method_id":"10","fields":[],"synchronous":"1","content":null,"name":"Select","responses":{"Net::AMQP::Protocol::Dtx::SelectOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"SelectOk","responses":{}},{"method_id":"20","fields":[{"name":"dtx identifier","doc":"transaction identifier \n\nThe distributed transaction key. This identifies the transaction so that the AMQP server can coordinate with the distributed transaction coordinator. ","type":"shortstr"}],"synchronous":"1","content":null,"name":"Start","responses":{"Net::AMQP::Protocol::Dtx::StartOk":1}},{"method_id":"21","fields":[],"synchronous":"1","content":null,"name":"StartOk","responses":{}}],"name":"Dtx","class_id":"100"},"Queue":{"handler":"channel","methods":[{"method_id":"10","fields":[{"domain":"access ticket","name":"ticket","doc":"\n\nWhen a client defines a new queue, this belongs to the access realm of the ticket used. All further work done with that queue must be done with an access ticket for the same realm. \n\nThe client provides a valid access ticket giving \"active\" access to the realm in which the queue exists or will be created, or \"passive\" access if the if-exists flag is set. "},{"domain":"queue name","name":"queue","doc":""},{"name":"passive","doc":"do not create queue \n\nIf set, the server will not create the queue. The client can use this to check whether a queue exists without modifying the server state. ","type":"bit"},{"name":"durable","doc":"request a durable queue \n\nIf set when creating a new queue, the queue will be marked as durable. Durable queues remain active when a server restarts. Non-durable queues (transient queues) are purged if/when a server restarts. Note that durable queues do not necessarily hold persistent messages, although it does not make sense to send persistent messages to a transient queue. ","type":"bit"},{"name":"exclusive","doc":"request an exclusive queue \n\nExclusive queues may only be consumed from by the current connection. Setting the 'exclusive' flag always implies 'auto-delete'. ","type":"bit"},{"name":"auto delete","doc":"auto-delete queue when unused \n\nIf set, the queue is deleted when all consumers have finished using it. Last consumer can be cancelled either explicitly or because its channel is closed. If there was no consumer ever on the queue, it won't be deleted. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"},{"name":"arguments","doc":"arguments for declaration \n\nA set of arguments for the declaration. The syntax and semantics of these arguments depends on the server implementation. This field is ignored if passive is 1. ","type":"table"}],"synchronous":"1","content":null,"name":"Declare","responses":{"Net::AMQP::Protocol::Queue::DeclareOk":1}},{"method_id":"11","fields":[{"domain":"queue name","name":"queue","doc":"\n\nReports the name of the queue. If the server generated a queue name, this field contains that name. "},{"name":"message count","doc":"number of messages in queue \n\nReports the number of messages in the queue, which will be zero for newly-created queues. ","type":"long"},{"name":"consumer count","doc":"number of consumers \n\nReports the number of active consumers for the queue. Note that consumers can suspend activity (Channel.Flow) in which case they do not appear in this count. ","type":"long"}],"synchronous":"1","content":null,"name":"DeclareOk","responses":{}},{"method_id":"20","fields":[{"domain":"access ticket","name":"ticket","doc":"\n\nThe client provides a valid access ticket giving \"active\" access rights to the queue's access realm. "},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to bind. If the queue name is empty, refers to the current queue for the channel, which is the last declared queue. "},{"domain":"exchange name","name":"exchange","doc":"The name of the exchange to bind to. "},{"name":"routing key","doc":"message routing key \n\nSpecifies the routing key for the binding. The routing key is used for routing messages depending on the exchange configuration. Not all exchanges use a routing key - refer to the specific exchange documentation. If the routing key is empty and the queue name is empty, the routing key will be the current queue for the channel, which is the last declared queue. ","type":"shortstr"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"},{"name":"arguments","doc":"arguments for binding \n\nA set of arguments for the binding. The syntax and semantics of these arguments depends on the exchange class. ","type":"table"}],"synchronous":"1","content":null,"name":"Bind","responses":{"Net::AMQP::Protocol::Queue::BindOk":1}},{"method_id":"21","fields":[],"synchronous":"1","content":null,"name":"BindOk","responses":{}},{"method_id":"50","fields":[{"domain":"access ticket","name":"ticket","doc":"\n\nThe client provides a valid access ticket giving \"active\" access rights to the queue's access realm. "},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to unbind."},{"domain":"exchange name","name":"exchange","doc":"\n\nThe name of the exchange to unbind from."},{"name":"routing key","doc":"routing key of binding \n\nSpecifies the routing key of the binding to unbind.","type":"shortstr"},{"name":"arguments","doc":"arguments of binding \n\nSpecifies the arguments of the binding to unbind.","type":"table"}],"synchronous":"1","content":null,"name":"Unbind","responses":{"Net::AMQP::Protocol::Queue::UnbindOk":1}},{"method_id":"51","fields":[],"synchronous":"1","content":null,"name":"UnbindOk","responses":{}},{"method_id":"30","fields":[{"domain":"access ticket","name":"ticket","doc":"\n\nThe access ticket must be for the access realm that holds the queue. "},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to purge. If the queue name is empty, refers to the current queue for the channel, which is the last declared queue. "},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Purge","responses":{"Net::AMQP::Protocol::Queue::PurgeOk":1}},{"method_id":"31","fields":[{"name":"message count","doc":"number of messages purged \n\nReports the number of messages purged. ","type":"long"}],"synchronous":"1","content":null,"name":"PurgeOk","responses":{}},{"method_id":"40","fields":[{"domain":"access ticket","name":"ticket","doc":"\n\nThe client provides a valid access ticket giving \"active\" access rights to the queue's access realm. "},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to delete. If the queue name is empty, refers to the current queue for the channel, which is the last declared queue. "},{"name":"if unused","doc":"delete only if unused \n\nIf set, the server will only delete the queue if it has no consumers. If the queue has consumers the server does does not delete it but raises a channel exception instead. ","type":"bit"},{"name":"if empty","doc":"delete only if empty \n\nIf set, the server will only delete the queue if it has no messages. If the queue is not empty the server raises a channel exception. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Delete","responses":{"Net::AMQP::Protocol::Queue::DeleteOk":1}},{"method_id":"41","fields":[{"name":"message count","doc":"number of messages purged \n\nReports the number of messages purged. ","type":"long"}],"synchronous":"1","content":null,"name":"DeleteOk","responses":{}}],"name":"Queue","class_id":"50"},"Channel":{"handler":"channel","methods":[{"method_id":"10","fields":[{"name":"out of band","doc":"out-of-band settings \n\nConfigures out-of-band transfers on this channel. The syntax and meaning of this field will be formally defined at a later date. ","type":"shortstr"}],"synchronous":"1","content":null,"name":"Open","responses":{"Net::AMQP::Protocol::Channel::OpenOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"OpenOk","responses":{}},{"method_id":"20","fields":[{"name":"active","doc":"start/stop content frames \n\nIf 1, the peer starts sending content frames. If 0, the peer stops sending content frames. ","type":"bit"}],"synchronous":"1","content":null,"name":"Flow","responses":{"Net::AMQP::Protocol::Channel::FlowOk":1}},{"method_id":"21","fields":[{"name":"active","doc":"current flow setting \n\nConfirms the setting of the processed flow method: 1 means the peer will start sending or continue to send content frames; 0 means it will not. ","type":"bit"}],"synchronous":null,"content":null,"name":"FlowOk","responses":{}},{"method_id":"30","fields":[{"domain":"reply code","name":"reply code","doc":""},{"domain":"reply text","name":"reply text","doc":""},{"name":"details","doc":"detailed information for warning \n\nA set of fields that provide more information about the problem. The meaning of these fields are defined on a per-reply-code basis (TO BE DEFINED). ","type":"table"}],"synchronous":null,"content":null,"name":"Alert","responses":{}},{"method_id":"40","fields":[{"domain":"reply code","name":"reply code","doc":""},{"domain":"reply text","name":"reply text","doc":""},{"domain":"class id","name":"class id","doc":"failing method class \n\nWhen the close is provoked by a method exception, this is the class of the method. "},{"domain":"method id","name":"method id","doc":"failing method ID \n\nWhen the close is provoked by a method exception, this is the ID of the method. "}],"synchronous":"1","content":null,"name":"Close","responses":{"Net::AMQP::Protocol::Channel::CloseOk":1}},{"method_id":"41","fields":[],"synchronous":"1","content":null,"name":"CloseOk","responses":{}}],"name":"Channel","class_id":"20"},"Connection":{"handler":"connection","methods":[{"method_id":"10","fields":[{"name":"version major","doc":"protocol major version \n\nThe protocol major version that the server agrees to use, which cannot be higher than the client's major version. ","type":"octet"},{"name":"version minor","doc":"protocol major version \n\nThe protocol minor version that the server agrees to use, which cannot be higher than the client's minor version. ","type":"octet"},{"domain":"peer properties","name":"server properties","doc":"server properties "},{"name":"mechanisms","doc":"available security mechanisms \n\nA list of the security mechanisms that the server supports, delimited by spaces. Currently ASL supports these mechanisms: PLAIN. ","type":"longstr"},{"name":"locales","doc":"available message locales \n\nA list of the message locales that the server supports, delimited by spaces. The locale defines the language in which the server will send reply texts. ","type":"longstr"}],"synchronous":"1","content":null,"name":"Start","responses":{"Net::AMQP::Protocol::Connection::StartOk":1}},{"method_id":"11","fields":[{"domain":"peer properties","name":"client properties","doc":"client properties "},{"name":"mechanism","doc":"selected security mechanism \n\nA single security mechanisms selected by the client, which must be one of those specified by the server. ","type":"shortstr"},{"name":"response","doc":"security response data \n\nA block of opaque data passed to the security mechanism. The contents of this data are defined by the SASL security mechanism. For the PLAIN security mechanism this is defined as a field table holding two fields, LOGIN and PASSWORD. ","type":"longstr"},{"name":"locale","doc":"selected message locale \n\nA single message local selected by the client, which must be one of those specified by the server. ","type":"shortstr"}],"synchronous":"1","content":null,"name":"StartOk","responses":{}},{"method_id":"20","fields":[{"name":"challenge","doc":"security challenge data \n\nChallenge information, a block of opaque binary data passed to the security mechanism. ","type":"longstr"}],"synchronous":"1","content":null,"name":"Secure","responses":{"Net::AMQP::Protocol::Connection::SecureOk":1}},{"method_id":"21","fields":[{"name":"response","doc":"security response data \n\nA block of opaque data passed to the security mechanism. The contents of this data are defined by the SASL security mechanism. ","type":"longstr"}],"synchronous":"1","content":null,"name":"SecureOk","responses":{}},{"method_id":"30","fields":[{"name":"channel max","doc":"proposed maximum channels \n\nThe maximum total number of channels that the server allows per connection. Zero means that the server does not impose a fixed limit, but the number of allowed channels may be limited by available server resources. ","type":"short"},{"name":"frame max","doc":"proposed maximum frame size \n\nThe largest frame size that the server proposes for the connection. The client can negotiate a lower value. Zero means that the server does not impose any specific limit but may reject very large frames if it cannot allocate resources for them. ","type":"long"},{"name":"heartbeat","doc":"desired heartbeat delay \n\nThe delay, in seconds, of the connection heartbeat that the server wants. Zero means the server does not want a heartbeat. ","type":"short"}],"synchronous":"1","content":null,"name":"Tune","responses":{"Net::AMQP::Protocol::Connection::TuneOk":1}},{"method_id":"31","fields":[{"name":"channel max","doc":"negotiated maximum channels \n\nThe maximum total number of channels that the client will use per connection. May not be higher than the value specified by the server. ","type":"short"},{"name":"frame max","doc":"negotiated maximum frame size \n\nThe largest frame size that the client and server will use for the connection. Zero means that the client does not impose any specific limit but may reject very large frames if it cannot allocate resources for them. Note that the frame-max limit applies principally to content frames, where large contents can be broken into frames of arbitrary size. ","type":"long"},{"name":"heartbeat","doc":"desired heartbeat delay \n\nThe delay, in seconds, of the connection heartbeat that the client wants. Zero means the client does not want a heartbeat. ","type":"short"}],"synchronous":"1","content":null,"name":"TuneOk","responses":{}},{"method_id":"40","fields":[{"domain":"path","name":"virtual host","doc":"virtual host name \n\nThe name of the virtual host to work with. "},{"name":"capabilities","doc":"required capabilities \n\nThe client may specify a number of capability names, delimited by spaces. The server can use this string to how to process the client's connection request. ","type":"shortstr"},{"name":"insist","doc":"insist on connecting to server \n\nIn a configuration with multiple load-sharing servers, the server may respond to a Connection.Open method with a Connection.Redirect. The insist option tells the server that the client is insisting on a connection to the specified server. ","type":"bit"}],"synchronous":"1","content":null,"name":"Open","responses":{"Net::AMQP::Protocol::Connection::Redirect":1,"Net::AMQP::Protocol::Connection::OpenOk":1}},{"method_id":"41","fields":[{"domain":"known hosts","name":"known hosts","doc":""}],"synchronous":"1","content":null,"name":"OpenOk","responses":{}},{"method_id":"50","fields":[{"name":"host","doc":"server to connect to \n\nSpecifies the server to connect to. This is an IP address or a DNS name, optionally followed by a colon and a port number. If no port number is specified, the client should use the default port number for the protocol. ","type":"shortstr"},{"domain":"known hosts","name":"known hosts","doc":""}],"synchronous":"1","content":null,"name":"Redirect","responses":{}},{"method_id":"60","fields":[{"domain":"reply code","name":"reply code","doc":""},{"domain":"reply text","name":"reply text","doc":""},{"domain":"class id","name":"class id","doc":"failing method class \n\nWhen the close is provoked by a method exception, this is the class of the method. "},{"domain":"class id","name":"method id","doc":"failing method ID \n\nWhen the close is provoked by a method exception, this is the ID of the method. "}],"synchronous":"1","content":null,"name":"Close","responses":{"Net::AMQP::Protocol::Connection::CloseOk":1}},{"method_id":"61","fields":[],"synchronous":"1","content":null,"name":"CloseOk","responses":{}}],"name":"Connection","class_id":"10"},"Test":{"handler":"channel","methods":[{"method_id":"10","fields":[{"name":"integer 1","doc":"octet test value \n\nAn octet integer test value. ","type":"octet"},{"name":"integer 2","doc":"short test value \n\nA short integer test value. ","type":"short"},{"name":"integer 3","doc":"long test value \n\nA long integer test value. ","type":"long"},{"name":"integer 4","doc":"long-long test value \n\nA long long integer test value. ","type":"longlong"},{"name":"operation","doc":"operation to test \n\nThe client must execute this operation on the provided integer test fields and return the result. ","type":"octet"}],"synchronous":"1","content":null,"name":"Integer","responses":{"Net::AMQP::Protocol::Test::IntegerOk":1}},{"method_id":"11","fields":[{"name":"result","doc":"result value \n\nThe result of the tested operation. ","type":"longlong"}],"synchronous":"1","content":null,"name":"IntegerOk","responses":{}},{"method_id":"20","fields":[{"name":"string 1","doc":"short string test value \n\nAn short string test value. ","type":"shortstr"},{"name":"string 2","doc":"long string test value \n\nA long string test value. ","type":"longstr"},{"name":"operation","doc":"operation to test \n\nThe client must execute this operation on the provided string test fields and return the result. ","type":"octet"}],"synchronous":"1","content":null,"name":"String","responses":{"Net::AMQP::Protocol::Test::StringOk":1}},{"method_id":"21","fields":[{"name":"result","doc":"result value \n\nThe result of the tested operation. ","type":"longstr"}],"synchronous":"1","content":null,"name":"StringOk","responses":{}},{"method_id":"30","fields":[{"name":"table","doc":"field table of test values \n\nA field table of test values. ","type":"table"},{"name":"integer op","doc":"operation to test on integers \n\nThe client must execute this operation on the provided field table integer values and return the result. ","type":"octet"},{"name":"string op","doc":"operation to test on strings \n\nThe client must execute this operation on the provided field table string values and return the result. ","type":"octet"}],"synchronous":"1","content":null,"name":"Table","responses":{"Net::AMQP::Protocol::Test::TableOk":1}},{"method_id":"31","fields":[{"name":"integer result","doc":"integer result value \n\nThe result of the tested integer operation. ","type":"longlong"},{"name":"string result","doc":"string result value \n\nThe result of the tested string operation. ","type":"longstr"}],"synchronous":"1","content":null,"name":"TableOk","responses":{}},{"method_id":"40","fields":[],"synchronous":"1","content":"1","name":"Content","responses":{"Net::AMQP::Protocol::Test::ContentOk":1}},{"method_id":"41","fields":[{"name":"content checksum","doc":"content hash \n\nThe 32-bit checksum of the content, calculated by adding the content into a 32-bit accumulator. ","type":"long"}],"synchronous":"1","content":"1","name":"ContentOk","responses":{}}],"name":"Test","class_id":"120"},"Basic":{"handler":"channel","methods":[{"method_id":"10","fields":[{"name":"prefetch size","doc":"prefetch window in octets \n\nThe client can request that messages be sent in advance so that when the client finishes processing a message, the following message is already held locally, rather than needing to be sent down the channel. Prefetching gives a performance improvement. This field specifies the prefetch window size in octets. The server will send a message in advance if it is equal to or smaller in size than the available prefetch size (and also falls into other prefetch limits). May be set to zero, meaning \"no specific limit\", although other prefetch limits may still apply. The prefetch-size is ignored if the no-ack option is set. ","type":"long"},{"name":"prefetch count","doc":"prefetch window in messages \n\nSpecifies a prefetch window in terms of whole messages. This field may be used in combination with the prefetch-size field; a message will only be sent in advance if both prefetch windows (and those at the channel and connection level) allow it. The prefetch-count is ignored if the no-ack option is set. ","type":"short"},{"name":"global","doc":"apply to entire connection \n\nBy default the QoS settings apply to the current channel only. If this field is set, they are applied to the entire connection. ","type":"bit"}],"synchronous":"1","content":null,"name":"Qos","responses":{"Net::AMQP::Protocol::Basic::QosOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"QosOk","responses":{}},{"method_id":"20","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to consume from. If the queue name is null, refers to the current queue for the channel, which is the last declared queue. "},{"domain":"consumer tag","name":"consumer tag","doc":"\n\nSpecifies the identifier for the consumer. The consumer tag is local to a connection, so two clients can use the same consumer tags. If this field is empty the server will generate a unique tag. "},{"domain":"no local","name":"no local","doc":""},{"domain":"no ack","name":"no ack","doc":""},{"name":"exclusive","doc":"request exclusive access \n\nRequest exclusive consumer access, meaning only this consumer can access the queue. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Consume","responses":{"Net::AMQP::Protocol::Basic::ConsumeOk":1}},{"method_id":"21","fields":[{"domain":"consumer tag","name":"consumer tag","doc":"\n\nHolds the consumer tag specified by the client or provided by the server. "}],"synchronous":"1","content":null,"name":"ConsumeOk","responses":{}},{"method_id":"30","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Cancel","responses":{"Net::AMQP::Protocol::Basic::CancelOk":1}},{"method_id":"31","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""}],"synchronous":"1","content":null,"name":"CancelOk","responses":{}},{"method_id":"40","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange to publish to. The exchange name can be empty, meaning the default exchange. If the exchange name is specified, and that exchange does not exist, the server will raise a channel exception. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key for the message. The routing key is used for routing messages depending on the exchange configuration. ","type":"shortstr"},{"name":"mandatory","doc":"indicate mandatory routing \n\nThis flag tells the server how to react if the message cannot be routed to a queue. If this flag is set, the server will return an unroutable message with a Return method. If this flag is zero, the server silently drops the message. ","type":"bit"},{"name":"immediate","doc":"request immediate delivery \n\nThis flag tells the server how to react if the message cannot be routed to a queue consumer immediately. If this flag is set, the server will return an undeliverable message with a Return method. If this flag is zero, the server will queue the message, but with no guarantee that it will ever be consumed. ","type":"bit"}],"synchronous":null,"content":"1","name":"Publish","responses":{}},{"method_id":"50","fields":[{"domain":"reply code","name":"reply code","doc":""},{"domain":"reply text","name":"reply text","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key name specified when the message was published. ","type":"shortstr"}],"synchronous":null,"content":"1","name":"Return","responses":{}},{"method_id":"60","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""},{"domain":"delivery tag","name":"delivery tag","doc":""},{"domain":"redelivered","name":"redelivered","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key name specified when the message was published. ","type":"shortstr"}],"synchronous":null,"content":"1","name":"Deliver","responses":{}},{"method_id":"70","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to consume from. If the queue name is null, refers to the current queue for the channel, which is the last declared queue. "},{"domain":"no ack","name":"no ack","doc":""}],"synchronous":"1","content":null,"name":"Get","responses":{"Net::AMQP::Protocol::Basic::GetOk":1,"Net::AMQP::Protocol::Basic::GetEmpty":1}},{"method_id":"71","fields":[{"domain":"delivery tag","name":"delivery tag","doc":""},{"domain":"redelivered","name":"redelivered","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. If empty, the message was published to the default exchange. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key name specified when the message was published. ","type":"shortstr"},{"name":"message count","doc":"number of messages pending \n\nThis field reports the number of messages pending on the queue, excluding the message being delivered. Note that this figure is indicative, not reliable, and can change arbitrarily as messages are added to the queue and removed by other clients. ","type":"long"}],"synchronous":"1","content":"1","name":"GetOk","responses":{}},{"method_id":"72","fields":[{"name":"cluster id","doc":"Cluster id \n\nFor use by cluster applications, should not be used by client applications. ","type":"shortstr"}],"synchronous":"1","content":null,"name":"GetEmpty","responses":{}},{"method_id":"80","fields":[{"domain":"delivery tag","name":"delivery tag","doc":""},{"name":"multiple","doc":"acknowledge multiple messages \n\nIf set to 1, the delivery tag is treated as \"up to and including\", so that the client can acknowledge multiple messages with a single method. If set to zero, the delivery tag refers to a single message. If the multiple field is 1, and the delivery tag is zero, tells the server to acknowledge all outstanding mesages. ","type":"bit"}],"synchronous":null,"content":null,"name":"Ack","responses":{}},{"method_id":"90","fields":[{"domain":"delivery tag","name":"delivery tag","doc":""},{"name":"requeue","doc":"requeue the message \n\nIf this field is zero, the message will be discarded. If this bit is 1, the server will attempt to requeue the message. ","type":"bit"}],"synchronous":null,"content":null,"name":"Reject","responses":{}},{"method_id":"100","fields":[{"name":"requeue","doc":"requeue the message \n\nIf this field is zero, the message will be redelivered to the original recipient. If this bit is 1, the server will attempt to requeue the message, potentially then delivering it to an alternative subscriber. ","type":"bit"}],"synchronous":null,"content":null,"name":"Recover","responses":{}},{"method_id":0,"fields":[{"name":"content type","type":"shortstr"},{"name":"content encoding","type":"shortstr"},{"name":"headers","type":"table"},{"name":"delivery mode","type":"octet"},{"name":"priority","type":"octet"},{"name":"correlation id","type":"shortstr"},{"name":"reply to","type":"shortstr"},{"name":"expiration","type":"shortstr"},{"name":"message id","type":"shortstr"},{"name":"timestamp","type":"timestamp"},{"name":"type","type":"shortstr"},{"name":"user id","type":"shortstr"},{"name":"app id","type":"shortstr"},{"name":"cluster id","type":"shortstr"}],"synchronous":null,"name":"ContentHeader","responses":{}}],"name":"Basic","class_id":"60"},"File":{"handler":"channel","methods":[{"method_id":"10","fields":[{"name":"prefetch size","doc":"prefetch window in octets \n\nThe client can request that messages be sent in advance so that when the client finishes processing a message, the following message is already held locally, rather than needing to be sent down the channel. Prefetching gives a performance improvement. This field specifies the prefetch window size in octets. May be set to zero, meaning \"no specific limit\". Note that other prefetch limits may still apply. The prefetch-size is ignored if the no-ack option is set. ","type":"long"},{"name":"prefetch count","doc":"prefetch window in messages \n\nSpecifies a prefetch window in terms of whole messages. This is compatible with some file API implementations. This field may be used in combination with the prefetch-size field; a message will only be sent in advance if both prefetch windows (and those at the channel and connection level) allow it. The prefetch-count is ignored if the no-ack option is set. ","type":"short"},{"name":"global","doc":"apply to entire connection \n\nBy default the QoS settings apply to the current channel only. If this field is set, they are applied to the entire connection. ","type":"bit"}],"synchronous":"1","content":null,"name":"Qos","responses":{"Net::AMQP::Protocol::File::QosOk":1}},{"method_id":"11","fields":[],"synchronous":"1","content":null,"name":"QosOk","responses":{}},{"method_id":"20","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"queue name","name":"queue","doc":"\n\nSpecifies the name of the queue to consume from. If the queue name is null, refers to the current queue for the channel, which is the last declared queue. "},{"domain":"consumer tag","name":"consumer tag","doc":"\n\nSpecifies the identifier for the consumer. The consumer tag is local to a connection, so two clients can use the same consumer tags. If this field is empty the server will generate a unique tag. "},{"domain":"no local","name":"no local","doc":""},{"domain":"no ack","name":"no ack","doc":""},{"name":"exclusive","doc":"request exclusive access \n\nRequest exclusive consumer access, meaning only this consumer can access the queue. ","type":"bit"},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Consume","responses":{"Net::AMQP::Protocol::File::ConsumeOk":1}},{"method_id":"21","fields":[{"domain":"consumer tag","name":"consumer tag","doc":"\n\nHolds the consumer tag specified by the client or provided by the server. "}],"synchronous":"1","content":null,"name":"ConsumeOk","responses":{}},{"method_id":"30","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""},{"name":"nowait","doc":"do not send a reply method \n\nIf set, the server will not respond to the method. The client should not wait for a reply method. If the server could not complete the method it will raise a channel or connection exception. ","type":"bit"}],"synchronous":"1","content":null,"name":"Cancel","responses":{"Net::AMQP::Protocol::File::CancelOk":1}},{"method_id":"31","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""}],"synchronous":"1","content":null,"name":"CancelOk","responses":{}},{"method_id":"40","fields":[{"name":"identifier","doc":"staging identifier \n\nThis is the staging identifier. This is an arbitrary string chosen by the sender. For staging to work correctly the sender must use the same staging identifier when staging the same message a second time after recovery from a failure. A good choice for the staging identifier would be the SHA1 hash of the message properties data (including the original filename, revised time, etc.). ","type":"shortstr"},{"name":"content size","doc":"message content size \n\nThe size of the content in octets. The recipient may use this information to allocate or check available space in advance, to avoid \"disk full\" errors during staging of very large messages. ","type":"longlong"}],"synchronous":"1","content":null,"name":"Open","responses":{"Net::AMQP::Protocol::File::OpenOk":1}},{"method_id":"41","fields":[{"name":"staged size","doc":"already staged amount \n\nThe amount of previously-staged content in octets. For a new message this will be zero. ","type":"longlong"}],"synchronous":"1","content":null,"name":"OpenOk","responses":{"Net::AMQP::Protocol::File::Stage":1}},{"method_id":"50","fields":[],"synchronous":null,"content":"1","name":"Stage","responses":{}},{"method_id":"60","fields":[{"domain":"access ticket","name":"ticket","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange to publish to. The exchange name can be empty, meaning the default exchange. If the exchange name is specified, and that exchange does not exist, the server will raise a channel exception. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key for the message. The routing key is used for routing messages depending on the exchange configuration. ","type":"shortstr"},{"name":"mandatory","doc":"indicate mandatory routing \n\nThis flag tells the server how to react if the message cannot be routed to a queue. If this flag is set, the server will return an unroutable message with a Return method. If this flag is zero, the server silently drops the message. ","type":"bit"},{"name":"immediate","doc":"request immediate delivery \n\nThis flag tells the server how to react if the message cannot be routed to a queue consumer immediately. If this flag is set, the server will return an undeliverable message with a Return method. If this flag is zero, the server will queue the message, but with no guarantee that it will ever be consumed. ","type":"bit"},{"name":"identifier","doc":"staging identifier \n\nThis is the staging identifier of the message to publish. The message must have been staged. Note that a client can send the Publish method asynchronously without waiting for staging to finish. ","type":"shortstr"}],"synchronous":null,"content":null,"name":"Publish","responses":{}},{"method_id":"70","fields":[{"domain":"reply code","name":"reply code","doc":""},{"domain":"reply text","name":"reply text","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key name specified when the message was published. ","type":"shortstr"}],"synchronous":null,"content":"1","name":"Return","responses":{}},{"method_id":"80","fields":[{"domain":"consumer tag","name":"consumer tag","doc":""},{"domain":"delivery tag","name":"delivery tag","doc":""},{"domain":"redelivered","name":"redelivered","doc":""},{"domain":"exchange name","name":"exchange","doc":"\n\nSpecifies the name of the exchange that the message was originally published to. "},{"name":"routing key","doc":"Message routing key \n\nSpecifies the routing key name specified when the message was published. ","type":"shortstr"},{"name":"identifier","doc":"staging identifier \n\nThis is the staging identifier of the message to deliver. The message must have been staged. Note that a server can send the Deliver method asynchronously without waiting for staging to finish. ","type":"shortstr"}],"synchronous":null,"content":null,"name":"Deliver","responses":{}},{"method_id":"90","fields":[{"domain":"delivery tag","name":"delivery tag","doc":""},{"name":"multiple","doc":"acknowledge multiple messages \n\nIf set to 1, the delivery tag is treated as \"up to and including\", so that the client can acknowledge multiple messages with a single method. If set to zero, the delivery tag refers to a single message. If the multiple field is 1, and the delivery tag is zero, tells the server to acknowledge all outstanding mesages. ","type":"bit"}],"synchronous":null,"content":null,"name":"Ack","responses":{}},{"method_id":"100","fields":[{"domain":"delivery tag","name":"delivery tag","doc":""},{"name":"requeue","doc":"requeue the message \n\nIf this field is zero, the message will be discarded. If this bit is 1, the server will attempt to requeue the message. ","type":"bit"}],"synchronous":null,"content":null,"name":"Reject","responses":{}},{"method_id":0,"fields":[{"name":"content type","type":"shortstr"},{"name":"content encoding","type":"shortstr"},{"name":"headers","type":"table"},{"name":"priority","type":"octet"},{"name":"reply to","type":"shortstr"},{"name":"message id","type":"shortstr"},{"name":"filename","type":"shortstr"},{"name":"timestamp","type":"timestamp"},{"name":"cluster id","type":"shortstr"}],"synchronous":null,"name":"ContentHeader","responses":{}}],"name":"File","class_id":"70"},"Access":{"handler":"connection","methods":[{"method_id":"10","fields":[{"domain":"path","name":"realm","doc":"name of requested realm "},{"name":"exclusive","doc":"request exclusive access \n\nRequest exclusive access to the realm. If the server cannot grant this - because there are other active tickets for the realm - it raises a channel exception. ","type":"bit"},{"name":"passive","doc":"request passive access \n\nRequest message passive access to the specified access realm. Passive access lets a client get information about resources in the realm but not to make any changes to them. ","type":"bit"},{"name":"active","doc":"request active access \n\nRequest message active access to the specified access realm. Acvtive access lets a client get create and delete resources in the realm. ","type":"bit"},{"name":"write","doc":"request write access \n\nRequest write access to the specified access realm. Write access lets a client publish messages to all exchanges in the realm. ","type":"bit"},{"name":"read","doc":"request read access \n\nRequest read access to the specified access realm. Read access lets a client consume messages from queues in the realm. ","type":"bit"}],"synchronous":"1","content":null,"name":"Request","responses":{"Net::AMQP::Protocol::Access::RequestOk":1}},{"method_id":"11","fields":[{"domain":"access ticket","name":"ticket","doc":""}],"synchronous":"1","content":null,"name":"RequestOk","responses":{}}],"name":"Access","class_id":"30"}},"constant":{"frame body":{"value":"3"},"internal error":{"value":"541","class":"hard error"},"frame min size":{"value":"4096"},"frame oob body":{"value":"6"},"frame header":{"value":"2"},"not implemented":{"value":"540","class":"hard error"},"command invalid":{"value":"503","class":"hard error"},"frame method":{"value":"1"},"frame error":{"value":"501","class":"hard error"},"syntax error":{"value":"502","class":"hard error"},"connection forced":{"value":"320","class":"hard error"},"not found":{"value":"404","class":"soft error"},"frame heartbeat":{"value":"8"},"channel error":{"value":"504","class":"hard error"},"resource error":{"value":"506","class":"hard error"},"frame oob method":{"value":"4"},"access refused":{"value":"403","class":"soft error"},"not delivered":{"value":"310","class":"soft error"},"frame oob header":{"value":"5"},"frame trace":{"value":"7"},"not allowed":{"value":"530","class":"hard error"},"resource locked":{"value":"405","class":"soft error"},"invalid path":{"value":"402","class":"hard error"},"frame end":{"value":"206"},"reply success":{"value":"200"},"content too large":{"value":"311","class":"soft error"}}}]);
10              
11             sub import {
12 1     1   11 local $INC{"XML/LibXML.pm"} = 1;
13 1         14 require Net::AMQP;
14 0           require Net::AMQP::Protocol;
15 1     1   7 no warnings 'redefine';
  1         2  
  1         169  
16             *Net::AMQP::Protocol::load_xml_spec = sub {
17 0     0     %Net::AMQP::Protocol::spec = %$data;
18 0           foreach my $key (keys %{$data->{class}}) {
  0            
19 0           Net::AMQP::Protocol::_build_class($data->{class}{$key});
20             }
21 0           $data;
22 0           };
23             }
24              
25             1;
26              
27             =head1 NAME
28              
29             Net::AMQP::PP - Nasty hack for when you want pure perl AnyEvent::RabbitMQ
30              
31             =head1 SYNOPSIS
32              
33             use Net::AMQP::PP;
34             use AnyEvent::RabbitMQ; # Note - order is important!
35              
36             =head1 DESCRIPTION
37              
38             This module horribly monkeypatches NET::AMQP to avoid it's need
39             to load L.
40              
41             This code does disgusting things, and should be considered alpha quality.
42              
43             It uses the flavour of the AMQP spec inlined into L
44             to be compatible with that module.
45              
46             Note that this module depends on L, which cannot be installed
47             without L, and therefore is only useful when you're
48             trying to make something with L.
49              
50             =head1 AUTHOR
51              
52             Tomas Doran (t0m) C<< >>.
53              
54             =head1 COPYRIGHT
55              
56             The above author
57              
58             =head1 LICENSE
59              
60             Perl licensed.
61              
62             =cut
63              
64