er ID int32_t hdr_offset; // offset into the packet_t->data buffer int32_t hdr_length; // length of the header in packet_t->data buffer } header_t; typedef struct packet_t { uint64_t pkt_header_map; // bit map of presence of headers // Keep track of how many instances of each header we have uint8_t pkt_instance_counts[MAX_ID_COUNT]; char *pkt_data; // packet data buffer int32_t pkt_header_count; // total number of headers found header_t pkt_headers[]; // One per header + 1 more for payload } packet_t; typedef struct binding_t { int32_t bnd_id; // ID of the header that this binding is for // Map of required headers that must already processed in this packet uint64_t bnd_dependency_map; jobject bnd_jbinding; // JBinding object } java_binding_t; typedef struct scanner_t { int32_t sc_len; // bytes allocated for sc_packets buffer int32_t sc_offset; // offset into sc_packets for next packet // Cumulative map of dependencies that must already exist in the packet uint64_t sc_dependency_map[MAX_ID_COUNT]; // Array of binding structures; The second array is NULL terminated binding_t sc_bindings[MAX_ID_COUNT][MAX_BINDING_COUNT]; uint64_t sc_binding_map; // bit mapping of java bindings // Overrides CORE protocol bindings uint64_t sc_override_map[MAX_ID_COUNT]; packet_t *sc_packet; // ptr into scanner_t where the first packet begins } scanner_t;
Note that a packet scanner (JScanner) is not a lightweight object but actually fairely heavy to initialize and run. The scanner typically allocates on the order of 100Kb of internal native memory for its state structures and buffer. It is advisable to use its thread local getter methods which maintain a pool of scanners on a per thread basis. Of course a new instance of a scanner can be instantiated and configured differently from the default case which uses the information in the global registry.
@author Mark Bednarczyk
@author Sly Technologies, Inc.