def generate(specPath): spec = amqp_codegen.AmqpSpec(specPath) def genSingleDecode(prefix, cLvalue, unresolved_domain): type = spec.resolveDomain(unresolved_domain) if type == 'shortstr': print(prefix + "%s, offset = data.decode_short_string(encoded, offset)" % cLvalue) elif type == 'longstr': print(prefix + "length = struct.unpack_from('>I', encoded, offset)[0]") print(prefix + "offset += 4") print(prefix + "%s = encoded[offset:offset + length]" % cLvalue) print(prefix + "try:") print(prefix + " %s = str(%s)" % (cLvalue, cLvalue)) print(prefix + "except UnicodeEncodeError:") print(prefix + " pass") print(prefix + "offset += length") elif type == 'octet': print(prefix + "%s = struct.unpack_from('B', encoded, offset)[0]" % cLvalue) print(prefix + "offset += 1") elif type == 'short': print(prefix + "%s = struct.unpack_from('>H', encoded, offset)[0]" % cLvalue) print(prefix + "offset += 2") elif type == 'long': print(prefix + "%s = struct.unpack_from('>I', encoded, offset)[0]" % cLvalue) print(prefix + "offset += 4") elif type == 'longlong': print(prefix + "%s = struct.unpack_from('>Q', encoded, offset)[0]" % cLvalue) print(prefix + "offset += 8") elif type == 'timestamp': print(prefix + "%s = struct.unpack_from('>Q', encoded, offset)[0]" % cLvalue) print(prefix + "offset += 8") elif type == 'bit': raise Exception("Can't decode bit in genSingleDecode") elif type == 'table': print(Exception(prefix + "(%s, offset) = data.decode_table(encoded, offset)" % \ cLvalue)) else: raise Exception("Illegal domain in genSingleDecode", type) def genSingleEncode(prefix, cValue, unresolved_domain): type = spec.resolveDomain(unresolved_domain) if type == 'shortstr': print(prefix + \ "assert isinstance(%s, str_or_bytes),\\\n%s 'A non-string value was supplied for %s'" \ % (cValue, prefix, cValue)) print(prefix + "data.encode_short_string(pieces, %s)" % cValue) elif type == 'longstr': print(prefix + \ "assert isinstance(%s, str_or_bytes),\\\n%s 'A non-string value was supplied for %s'" \ % (cValue, prefix, cValue)) print( prefix + "value = %s.encode('utf-8') if isinstance(%s, unicode_type) else %s" % (cValue, cValue, cValue)) print(prefix + "pieces.append(struct.pack('>I', len(value)))") print(prefix + "pieces.append(value)") elif type == 'octet': print(prefix + "pieces.append(struct.pack('B', %s))" % cValue) elif type == 'short': print(prefix + "pieces.append(struct.pack('>H', %s))" % cValue) elif type == 'long': print(prefix + "pieces.append(struct.pack('>I', %s))" % cValue) elif type == 'longlong': print(prefix + "pieces.append(struct.pack('>Q', %s))" % cValue) elif type == 'timestamp': print(prefix + "pieces.append(struct.pack('>Q', %s))" % cValue) elif type == 'bit': raise Exception("Can't encode bit in genSingleEncode") elif type == 'table': print(Exception(prefix + "data.encode_table(pieces, %s)" % cValue)) else: raise Exception("Illegal domain in genSingleEncode", type) def genDecodeMethodFields(m): print(" def decode(self, encoded, offset=0):") bitindex = None for f in m.arguments: if spec.resolveDomain(f.domain) == 'bit': if bitindex is None: bitindex = 0 if bitindex >= 8: bitindex = 0 if not bitindex: print( " bit_buffer = struct.unpack_from('B', encoded, offset)[0]") print(" offset += 1") print(" self.%s = (bit_buffer & (1 << %d)) != 0" % \ (pyize(f.name), bitindex)) bitindex += 1 else: bitindex = None genSingleDecode(" ", "self.%s" % (pyize(f.name),), f.domain) print(" return self") print('') def genDecodeProperties(c): print(" def decode(self, encoded, offset=0):") print(" flags = 0") print(" flagword_index = 0") print(" while True:") print( " partial_flags = struct.unpack_from('>H', encoded, offset)[0]") print(" offset += 2") print( " flags = flags | (partial_flags << (flagword_index * 16))") print(" if not (partial_flags & 1):") print(" break") print(" flagword_index += 1") for f in c.fields: if spec.resolveDomain(f.domain) == 'bit': print(" self.%s = (flags & %s) != 0" % (pyize(f.name), flagName(c, f))) else: print(" if flags & %s:" % (flagName(c, f),)) genSingleDecode(" ", "self.%s" % (pyize(f.name),), f.domain) print(" else:") print(" self.%s = None" % (pyize(f.name),)) print(" return self") print('') def genEncodeMethodFields(m): print(" def encode(self):") print(" pieces = list()") bitindex = None def finishBits(): if bitindex is not None: print(" pieces.append(struct.pack('B', bit_buffer))") for f in m.arguments: if spec.resolveDomain(f.domain) == 'bit': if bitindex is None: bitindex = 0 print(" bit_buffer = 0") if bitindex >= 8: finishBits() print(" bit_buffer = 0") bitindex = 0 print(" if self.%s:" % pyize(f.name)) print(" bit_buffer = bit_buffer | (1 << %d)" % \ bitindex) bitindex += 1 else: finishBits() bitindex = None genSingleEncode(" ", "self.%s" % (pyize(f.name),), f.domain) finishBits() print(" return pieces") print('') def genEncodeProperties(c): print(" def encode(self):") print(" pieces = list()") print(" flags = 0") for f in c.fields: if spec.resolveDomain(f.domain) == 'bit': print(" if self.%s: flags = flags | %s" % (pyize(f.name), flagName(c, f))) else: print(" if self.%s is not None:" % (pyize(f.name),)) print(" flags = flags | %s" % (flagName(c, f),)) genSingleEncode(" ", "self.%s" % (pyize(f.name),), f.domain) print(" flag_pieces = list()") print(" while True:") print(" remainder = flags >> 16") print(" partial_flags = flags & 0xFFFE") print(" if remainder != 0:") print(" partial_flags |= 1") print( " flag_pieces.append(struct.pack('>H', partial_flags))") print(" flags = remainder") print(" if not flags:") print(" break") print(" return flag_pieces + pieces") print('') def fieldDeclList(fields): return ''.join([", %s=%s" % (pyize(f.name), fieldvalue(f.defaultvalue)) for f in fields]) def fieldInitList(prefix, fields): if fields: return ''.join(["%sself.%s = %s\n" % (prefix, pyize(f.name), pyize(f.name)) \ for f in fields]) else: return '%spass\n' % (prefix,) print("""\"\"\" AMQP Specification ================== This module implements the constants and classes that comprise AMQP protocol level constructs. It should rarely be directly referenced outside of Pika's own internal use. .. note:: Auto-generated code by codegen.py, do not edit directly. Pull requests to this file without accompanying ``utils/codegen.py`` changes will be rejected. \"\"\" import struct from pika import amqp_object from pika import data from pika.compat import str_or_bytes, unicode_type # Python 3 support for str object str = bytes """) print("PROTOCOL_VERSION = (%d, %d, %d)" % (spec.major, spec.minor, spec.revision)) print("PORT = %d" % spec.port) print('') # Append some constants that arent in the spec json file spec.constants.append(('FRAME_MAX_SIZE', 131072, '')) spec.constants.append(('FRAME_HEADER_SIZE', 7, '')) spec.constants.append(('FRAME_END_SIZE', 1, '')) spec.constants.append(('TRANSIENT_DELIVERY_MODE', 1, '')) spec.constants.append(('PERSISTENT_DELIVERY_MODE', 2, '')) constants = {} for c, v, cls in spec.constants: constants[constantName(c)] = v for key in sorted(constants.keys()): print("%s = %s" % (key, constants[key])) print('') for c in spec.allClasses(): print('') print('class %s(amqp_object.Class):' % (camel(c.name),)) print('') print(" INDEX = 0x%.04X # %d" % (c.index, c.index)) print(" NAME = %s" % (fieldvalue(camel(c.name)),)) print('') for m in c.allMethods(): print(' class %s(amqp_object.Method):' % (camel(m.name),)) print('') methodid = m.klass.index << 16 | m.index print(" INDEX = 0x%.08X # %d, %d; %d" % \ (methodid, m.klass.index, m.index, methodid)) print(" NAME = %s" % (fieldvalue(m.structName(),))) print('') print(" def __init__(self%s):" % (fieldDeclList(m.arguments),)) print(fieldInitList(' ', m.arguments)) print(" @property") print(" def synchronous(self):") print(" return %s" % m.isSynchronous) print('') genDecodeMethodFields(m) genEncodeMethodFields(m) for c in spec.allClasses(): if c.fields: print('') print('class %s(amqp_object.Properties):' % (c.structName(),)) print('') print(" CLASS = %s" % (camel(c.name),)) print(" INDEX = 0x%.04X # %d" % (c.index, c.index)) print(" NAME = %s" % (fieldvalue(c.structName(),))) print('') index = 0 if c.fields: for f in c.fields: if index % 16 == 15: index += 1 shortnum = index / 16 partialindex = 15 - (index % 16) bitindex = shortnum * 16 + partialindex print(' %s = (1 << %d)' % (flagName(None, f), bitindex)) index += 1 print('') print(" def __init__(self%s):" % (fieldDeclList(c.fields),)) print(fieldInitList(' ', c.fields)) genDecodeProperties(c) genEncodeProperties(c) print("methods = {") print(',\n'.join([" 0x%08X: %s" % (m.klass.index << 16 | m.index, m.structName()) \ for m in spec.allMethods()])) print("}") print('') print("props = {") print(',\n'.join([" 0x%04X: %s" % (c.index, c.structName()) \ for c in spec.allClasses() \ if c.fields])) print("}") print('') print('') print("def has_content(methodNumber):") print(' return methodNumber in (') for m in spec.allMethods(): if m.hasContent: print(' %s.INDEX,' % m.structName()) print(' )')
def generate(specPath): spec = amqp_codegen.AmqpSpec(specPath) def genSingleDecode(prefix, cLvalue, unresolved_domain): type = spec.resolveDomain(unresolved_domain) if type == 'shortstr': print prefix + "length = struct.unpack_from('B', encoded, offset)[0]" print prefix + "offset += 1" print prefix + "%s = encoded[offset:offset + length].decode('utf8')" % cLvalue print prefix + "try:" print prefix + " %s = str(%s)" % (cLvalue, cLvalue) print prefix + "except UnicodeEncodeError:" print prefix + " pass" print prefix + "offset += length" elif type == 'longstr': print prefix + "length = struct.unpack_from('>I', encoded, offset)[0]" print prefix + "offset += 4" print prefix + "%s = encoded[offset:offset + length].decode('utf8')" % cLvalue print prefix + "try:" print prefix + " %s = str(%s)" % (cLvalue, cLvalue) print prefix + "except UnicodeEncodeError:" print prefix + " pass" print prefix + "offset += length" elif type == 'octet': print prefix + "%s = struct.unpack_from('B', encoded, offset)[0]" % cLvalue print prefix + "offset += 1" elif type == 'short': print prefix + "%s = struct.unpack_from('>H', encoded, offset)[0]" % cLvalue print prefix + "offset += 2" elif type == 'long': print prefix + "%s = struct.unpack_from('>I', encoded, offset)[0]" % cLvalue print prefix + "offset += 4" elif type == 'longlong': print prefix + "%s = struct.unpack_from('>Q', encoded, offset)[0]" % cLvalue print prefix + "offset += 8" elif type == 'timestamp': print prefix + "%s = struct.unpack_from('>Q', encoded, offset)[0]" % cLvalue print prefix + "offset += 8" elif type == 'bit': raise Exception("Can't decode bit in genSingleDecode") elif type == 'table': print Exception(prefix + "(%s, offset) = data.decode_table(encoded, offset)" % \ cLvalue) else: raise Exception("Illegal domain in genSingleDecode", type) def genSingleEncode(prefix, cValue, unresolved_domain): type = spec.resolveDomain(unresolved_domain) if type == 'shortstr': print prefix + \ "assert isinstance(%s, basestring),\\\n%s 'A non-bytestring value was supplied for %s'" \ % (cValue, prefix, cValue) print prefix + "value = %s.encode('utf-8') if isinstance(%s, unicode) else %s" % ( cValue, cValue, cValue) print prefix + "pieces.append(struct.pack('B', len(value)))" print prefix + "pieces.append(value)" elif type == 'longstr': print prefix + \ "assert isinstance(%s, basestring),\\\n%s 'A non-bytestring value was supplied for %s'" \ % (cValue, prefix ,cValue) print prefix + "value = %s.encode('utf-8') if isinstance(%s, unicode) else %s" % ( cValue, cValue, cValue) print prefix + "pieces.append(struct.pack('>I', len(value)))" print prefix + "pieces.append(value)" elif type == 'octet': print prefix + "pieces.append(struct.pack('B', %s))" % cValue elif type == 'short': print prefix + "pieces.append(struct.pack('>H', %s))" % cValue elif type == 'long': print prefix + "pieces.append(struct.pack('>I', %s))" % cValue elif type == 'longlong': print prefix + "pieces.append(struct.pack('>Q', %s))" % cValue elif type == 'timestamp': print prefix + "pieces.append(struct.pack('>Q', %s))" % cValue elif type == 'bit': raise Exception("Can't encode bit in genSingleEncode") elif type == 'table': print Exception(prefix + "data.encode_table(pieces, %s)" % cValue) else: raise Exception("Illegal domain in genSingleEncode", type) def genDecodeMethodFields(m): print " def decode(self, encoded, offset=0):" bitindex = None for f in m.arguments: if spec.resolveDomain(f.domain) == 'bit': if bitindex is None: bitindex = 0 if bitindex >= 8: bitindex = 0 if not bitindex: print " bit_buffer = struct.unpack_from('B', encoded, offset)[0]" print " offset += 1" print " self.%s = (bit_buffer & (1 << %d)) != 0" % \ (pyize(f.name), bitindex) bitindex += 1 else: bitindex = None genSingleDecode(" ", "self.%s" % (pyize(f.name), ), f.domain) print " return self" print def genDecodeProperties(c): print " def decode(self, encoded, offset=0):" print " flags = 0" print " flagword_index = 0" print " while True:" print " partial_flags = struct.unpack_from('>H', encoded, offset)[0]" print " offset += 2" print " flags = flags | (partial_flags << (flagword_index * 16))" print " if not (partial_flags & 1):" print " break" print " flagword_index += 1" for f in c.fields: if spec.resolveDomain(f.domain) == 'bit': print " self.%s = (flags & %s) != 0" % (pyize( f.name), flagName(c, f)) else: print " if flags & %s:" % (flagName(c, f), ) genSingleDecode(" ", "self.%s" % (pyize(f.name), ), f.domain) print " else:" print " self.%s = None" % (pyize(f.name), ) print " return self" print def genEncodeMethodFields(m): print " def encode(self):" print " pieces = list()" bitindex = None def finishBits(): if bitindex is not None: print " pieces.append(struct.pack('B', bit_buffer))" for f in m.arguments: if spec.resolveDomain(f.domain) == 'bit': if bitindex is None: bitindex = 0 print " bit_buffer = 0" if bitindex >= 8: finishBits() print " bit_buffer = 0" bitindex = 0 print " if self.%s:" % pyize(f.name) print " bit_buffer = bit_buffer | (1 << %d)" % \ bitindex bitindex += 1 else: finishBits() bitindex = None genSingleEncode(" ", "self.%s" % (pyize(f.name), ), f.domain) finishBits() print " return pieces" print def genEncodeProperties(c): print " def encode(self):" print " pieces = list()" print " flags = 0" for f in c.fields: if spec.resolveDomain(f.domain) == 'bit': print " if self.%s: flags = flags | %s" % (pyize( f.name), flagName(c, f)) else: print " if self.%s is not None:" % (pyize(f.name), ) print " flags = flags | %s" % (flagName(c, f), ) genSingleEncode(" ", "self.%s" % (pyize(f.name), ), f.domain) print " flag_pieces = list()" print " while True:" print " remainder = flags >> 16" print " partial_flags = flags & 0xFFFE" print " if remainder != 0:" print " partial_flags |= 1" print " flag_pieces.append(struct.pack('>H', partial_flags))" print " flags = remainder" print " if not flags:" print " break" print " return flag_pieces + pieces" print def fieldDeclList(fields): return ''.join([ ", %s=%s" % (pyize(f.name), fieldvalue(f.defaultvalue)) for f in fields ]) def fieldInitList(prefix, fields): if fields: return ''.join(["%sself.%s = %s\n" % (prefix, pyize(f.name), pyize(f.name)) \ for f in fields]) else: return '%spass\n' % (prefix, ) print """# ***** BEGIN LICENSE BLOCK ***** # # For copyright and licensing please refer to COPYING. # # ***** END LICENSE BLOCK ***** # NOTE: Autogenerated code by codegen.py, do not edit import struct from pika import amqp_object from pika import data """ print "PROTOCOL_VERSION = (%d, %d, %d)" % (spec.major, spec.minor, spec.revision) print "PORT = %d" % spec.port print # Append some constants that arent in the spec json file spec.constants.append(('FRAME_MAX_SIZE', 131072, '')) spec.constants.append(('FRAME_HEADER_SIZE', 7, '')) spec.constants.append(('FRAME_END_SIZE', 1, '')) constants = {} for c, v, cls in spec.constants: constants[constantName(c)] = v for key in sorted(constants.iterkeys()): print "%s = %s" % (key, constants[key]) print for c in spec.allClasses(): print print 'class %s(amqp_object.Class):' % (camel(c.name), ) print print " INDEX = 0x%.04X # %d" % (c.index, c.index) print " NAME = %s" % (fieldvalue(camel(c.name)), ) print for m in c.allMethods(): print ' class %s(amqp_object.Method):' % (camel(m.name), ) print methodid = m.klass.index << 16 | m.index print " INDEX = 0x%.08X # %d, %d; %d" % \ (methodid, m.klass.index, m.index, methodid) print " NAME = %s" % (fieldvalue(m.structName(), )) print print " def __init__(self%s):" % (fieldDeclList( m.arguments), ) print fieldInitList(' ', m.arguments) print " @property" print " def synchronous(self):" print " return %s" % m.isSynchronous print genDecodeMethodFields(m) genEncodeMethodFields(m) for c in spec.allClasses(): if c.fields: print print 'class %s(amqp_object.Properties):' % (c.structName(), ) print print " CLASS = %s" % (camel(c.name), ) print " INDEX = 0x%.04X # %d" % (c.index, c.index) print " NAME = %s" % (fieldvalue(c.structName(), )) print index = 0 if c.fields: for f in c.fields: if index % 16 == 15: index += 1 shortnum = index / 16 partialindex = 15 - (index % 16) bitindex = shortnum * 16 + partialindex print ' %s = (1 << %d)' % (flagName(None, f), bitindex) index += 1 print print " def __init__(self%s):" % (fieldDeclList(c.fields), ) print fieldInitList(' ', c.fields) genDecodeProperties(c) genEncodeProperties(c) print "methods = {" print ',\n'.join([" 0x%08X: %s" % (m.klass.index << 16 | m.index, m.structName()) \ for m in spec.allMethods()]) print "}" print print "props = {" print ',\n'.join([" 0x%04X: %s" % (c.index, c.structName()) \ for c in spec.allClasses() \ if c.fields]) print "}" print print print "def has_content(methodNumber):" print for m in spec.allMethods(): if m.hasContent: print ' if methodNumber == %s.INDEX:' % m.structName() print ' return True' print " return False" print