text: #!/usr/bin/env python
  import struct
  from .gdsPrimitives import *
  
  class Gds2writer:
      """Class to take a populated layout class and write it to a file in GDSII format"""
      ## Based on info from http://www.rulabinsky.com/cavd/text/chapc.html
      
      def __init__(self,layoutObject):
          self.fileHandle = 0
          self.layoutObject = layoutObject
          self.debugToTerminal=0  #do we dump debug data to the screen
          
      def print64AsBinary(self,number):
          #debugging method for binary inspection
          for index in range(0,64):
              print((number>>(63-index))&0x1,eol='')
          print("\n")
          
      def ieeeDoubleFromIbmData(self,ibmData):
          #the GDS double is in IBM 370 format like this:
          #(1)sign (7)exponent (56)mantissa
          #exponent is excess 64, mantissa has no implied 1
          #a normal IEEE double is like this:
          #(1)sign (11)exponent (52)mantissa        
          data = struct.unpack('>q',ibmData)[0]
          sign = (data >> 63)&0x01
          exponent = (data >> 56) & 0x7f
          mantissa = data<<8 #chop off sign and exponent
          
          if mantissa == 0:
              newFloat = 0.0
          else:
              exponent = ((exponent-64)*4)+1023 #convert to double exponent
              #re normalize
              while mantissa & 0x8000000000000000 == 0:            
                  mantissa<<=1
                  exponent-=1 
              mantissa<<=1  #remove the assumed high bit
              exponent-=1
              #check for underflow error  -- should handle these properly!
              if(exponent<=0):
                  print("Underflow Error")
              elif(exponent == 2047):
                  print("Overflow Error")
              #re assemble
              newFloat=(sign<<63)|(exponent<<52)|((mantissa>>12)&0xfffffffffffff)
              asciiDouble = struct.pack('>q',newFloat)
              #convert back to double
              newFloat = struct.unpack('>d',asciiDouble)[0]
          return newFloat
      
      def ibmDataFromIeeeDouble(self,ieeeDouble):
          asciiDouble = struct.pack('>d',ieeeDouble)
          data = struct.unpack('>q',asciiDouble)[0]
          sign = (data >> 63) & 0x01
          exponent = ((data >> 52) & 0x7ff)-1023                
          mantissa = data << 12 #chop off sign and exponent
          if(ieeeDouble == 0):
              mantissa = 0
              exponent = 0
              sign = 0
          else:
              #add back the assumed digit
              mantissa >>= 1
              mantissa = mantissa|0x8000000000000000
              exponent += 1
              #convert the exponent
              #need to do this in a loop to prevent sign extension!
              for index in range (0,-exponent&3):
                  mantissa >>= 1
                  mantissa = mantissa & 0x7fffffffffffffff
                  
              exponent = (exponent+3) >> 2        
              exponent+=64
          
          newFloat =(sign<<63)|(exponent<<56)|((mantissa>>8)&0xffffffffffffff)        
          asciiDouble = struct.pack('>q',newFloat)        
          return asciiDouble
      
      def ieeeFloatCheck(self,aFloat):
          #debugging method for float construction
          asciiDouble = struct.pack('>d',aFloat)
          data = struct.unpack('>q',asciiDouble)[0]
          sign = data >> 63
          exponent = ((data >> 52) & 0x7ff)-1023
          print(exponent+1023)
          mantissa = data << 12 #chop off sign and exponent
          #self.print64AsBinary((sign<<63)|((exponent+1023)<<52)|(mantissa>>12))
          asciiDouble = struct.pack('>q',(sign<<63)|(exponent+1023<<52)|(mantissa>>12))
          newFloat = struct.unpack('>d',asciiDouble)[0]
          print("Check:"+str(newFloat))
          
      def writeRecord(self,record):
          recordLength = len(record)+2  #make sure to include this in the length
          recordLengthAscii=struct.pack(">h",recordLength)
          self.fileHandle.write(recordLengthAscii+record)
  
      def writeHeader(self):
          ##  Header
          if("gdsVersion" in self.layoutObject.info):
              idBits=b'\x00\x02'
              gdsVersion = struct.pack(">h",self.layoutObject.info["gdsVersion"])
              self.writeRecord(idBits+gdsVersion)
          ## Modified Date
          if("dates" in self.layoutObject.info):
              idBits=b'\x01\x02'
              modYear = struct.pack(">h",self.layoutObject.info["dates"][0])
              modMonth = struct.pack(">h",self.layoutObject.info["dates"][1])
              modDay = struct.pack(">h",self.layoutObject.info["dates"][2])
              modHour = struct.pack(">h",self.layoutObject.info["dates"][3])
              modMinute = struct.pack(">h",self.layoutObject.info["dates"][4])
              modSecond = struct.pack(">h",self.layoutObject.info["dates"][5])
              lastAccessYear = struct.pack(">h",self.layoutObject.info["dates"][6])
              lastAccessMonth = struct.pack(">h",self.layoutObject.info["dates"][7])
              lastAccessDay = struct.pack(">h",self.layoutObject.info["dates"][8])
              lastAccessHour = struct.pack(">h",self.layoutObject.info["dates"][9])
              lastAccessMinute = struct.pack(">h",self.layoutObject.info["dates"][10])
              lastAccessSecond = struct.pack(">h",self.layoutObject.info["dates"][11])
              self.writeRecord(idBits+modYear+modMonth+modDay+modHour+modMinute+modSecond+\
                               lastAccessYear+lastAccessMonth+lastAccessDay+lastAccessHour+\
                               lastAccessMinute+lastAccessSecond)
          ##  LibraryName
          if("libraryName" in self.layoutObject.info):
              idBits=b'\x02\x06'
              if (len(self.layoutObject.info["libraryName"]) % 2 != 0):
                  libraryName = self.layoutObject.info["libraryName"].encode() + "\0"
              else:
                  libraryName = self.layoutObject.info["libraryName"].encode()
              self.writeRecord(idBits+libraryName)                
          ## reference libraries
          if("referenceLibraries" in self.layoutObject.info):
              idBits=b'\x1F\x06'
              referenceLibraryA = self.layoutObject.info["referenceLibraries"][0]
              referenceLibraryB = self.layoutObject.info["referenceLibraries"][1]
              self.writeRecord(idBits+referenceLibraryA+referenceLibraryB)
          if("fonts" in self.layoutObject.info):
              idBits=b'\x20\x06'
              fontA = self.layoutObject.info["fonts"][0]
              fontB = self.layoutObject.info["fonts"][1]
              fontC = self.layoutObject.info["fonts"][2]
              fontD = self.layoutObject.info["fonts"][3]
              self.writeRecord(idBits+fontA+fontB+fontC+fontD)
          if("attributeTable" in self.layoutObject.info):
              idBits=b'\x23\x06'
              attributeTable = self.layoutObject.info["attributeTable"]
              self.writeRecord(idBits+attributeTable)
          if("generations" in self.layoutObject.info):
              idBits=b'\x22\x02'
              generations = struct.pack(">h",self.layoutObject.info["generations"])
              self.writeRecord(idBits+generations)
          if("fileFormat" in self.layoutObject.info):
              idBits=b'\x36\x02'
              fileFormat = struct.pack(">h",self.layoutObject.info["fileFormat"])
              self.writeRecord(idBits+fileFormat)
          if("mask" in self.layoutObject.info):
              idBits=b'\x37\x06'
              mask = self.layoutObject.info["mask"]
              self.writeRecord(idBits+mask)
          if("units" in self.layoutObject.info):
              idBits=b'\x03\x05'  
              userUnits=self.ibmDataFromIeeeDouble(self.layoutObject.info["units"][0])
              dbUnits=self.ibmDataFromIeeeDouble((self.layoutObject.info["units"][0]*1e-6/self.layoutObject.info["units"][1])*self.layoutObject.info["units"][1])
  
              #User Units are hardcoded, since the floating point implementation of gdsMill is not adequate, 
  		#resulting in a different value being written in output stream.  Hardcoded to sram compiler's outputed gds units.
  	    #db="39225c17d04dad2a"
  	    #uu="3e20c49ba5e353f8"
  
              #userUnits="3e20c49ba5e353f8".decode("hex")
              #dbUnits="39225c17d04dad2a".decode("hex")
  
              #dbUnits="39225c17d04dad2a".decode("hex")
  	    #db=39225c17d04dad2a
              
  		
              self.writeRecord(idBits+userUnits+dbUnits)
          if(self.debugToTerminal==1): 
              print("writer: userUnits %s"%(userUnits.encode("hex")))
              print("writer: dbUnits   %s"%(dbUnits.encode("hex")))
  	    #self.ieeeFloatCheck(1.3e-6)
  	    
              print("End of GDSII Header Written")
          return 1
      
      def writeBoundary(self,thisBoundary):
          idBits=b'\x08\x00'  #record Type
          self.writeRecord(idBits)
          if(thisBoundary.elementFlags!=""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisBoundary.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisBoundary.plex!=""):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisBoundary.plex)
              self.writeRecord(idBits+plex)
          if(thisBoundary.drawingLayer!=""):
              idBits=b'\x0D\x02' #drawig layer
              drawingLayer = struct.pack(">h",thisBoundary.drawingLayer)
              self.writeRecord(idBits+drawingLayer)
          if(thisBoundary.purposeLayer):
              idBits=b'\x16\x02' #purpose layer
              purposeLayer = struct.pack(">h",thisBoundary.purposeLayer)
              self.writeRecord(idBits+purposeLayer)
          if(thisBoundary.dataType!=""):
              idBits=b'\x0E\x02'#DataType
              dataType = struct.pack(">h",thisBoundary.dataType)
              self.writeRecord(idBits+dataType)
          if(thisBoundary.coordinates!=""):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              for coordinate in thisBoundary.coordinates:
                  x=struct.pack(">i",int(coordinate[0]))
                  y=struct.pack(">i",int(coordinate[1]))
                  coordinateRecord+=x
                  coordinateRecord+=y
              self.writeRecord(coordinateRecord)
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
      
      def writePath(self,thisPath):  #writes out a path structure
          idBits=b'\x09\x00'  #record Type
          self.writeRecord(idBits)
          if(thisPath.elementFlags != ""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisPath.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisPath.plex!=""):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisPath.plex)
              self.writeRecord(idBits+plex)
          if(thisPath.drawingLayer):
              idBits=b'\x0D\x02' #drawig layer
              drawingLayer = struct.pack(">h",thisPath.drawingLayer)
              self.writeRecord(idBits+drawingLayer)
          if(thisPath.purposeLayer):
              idBits=b'\x16\x02' #purpose layer
              purposeLayer = struct.pack(">h",thisPath.purposeLayer)
              self.writeRecord(idBits+purposeLayer)
          if(thisPath.pathType):
              idBits=b'\x21\x02'  #Path type
              pathType = struct.pack(">h",thisPath.pathType)
              self.writeRecord(idBits+pathType)
          if(thisPath.pathWidth):
              idBits=b'\x0F\x03'
              pathWidth = struct.pack(">i",thisPath.pathWidth)
              self.writeRecord(idBits+pathWidth)
          if(thisPath.coordinates):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              for coordinate in thisPath.coordinates:
                  x=struct.pack(">i",int(coordinate[0]))
                  y=struct.pack(">i",int(coordinate[1]))
                  coordinateRecord+=x
                  coordinateRecord+=y
              self.writeRecord(coordinateRecord)
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
      
      def writeSref(self,thisSref):  #reads in a reference to another structure
          idBits=b'\x0A\x00'  #record Type
          self.writeRecord(idBits)
          if(thisSref.elementFlags != ""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisSref.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisSref.plex!=""):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisSref.plex)
              self.writeRecord(idBits+plex)
          if(thisSref.sName!=""):
              idBits=b'\x12\x06'
              if (len(thisSref.sName) % 2 != 0):
                  sName = thisSref.sName+"\0"
              else:
                  sName = thisSref.sName
              self.writeRecord(idBits+sName.encode())
          if(thisSref.transFlags!=""):
              idBits=b'\x1A\x01'
              mirrorFlag = int(thisSref.transFlags[0])<<15
              # The rotate and magnify flags specify "absolute" rotate and magnify.
              # It is unclear what that is (ignore all further rotates/mags in the
              # hierarchy? But anyway, calibre doesn't support it.
              rotateFlag=0
              magnifyFlag = 0
              #rotateFlag = int(thisSref.transFlags[2])<<1
              #magnifyFlag = int(thisSref.transFlags[1])<<2
              transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
              self.writeRecord(idBits+transFlags)
          if(thisSref.magFactor!=""):
              idBits=b'\x1B\x05'
              magFactor=self.ibmDataFromIeeeDouble(thisSref.magFactor)
              self.writeRecord(idBits+magFactor)
          if(thisSref.rotateAngle!=""):
              idBits=b'\x1C\x05'            
              rotateAngle=self.ibmDataFromIeeeDouble(thisSref.rotateAngle)
              self.writeRecord(idBits+rotateAngle)
          if(thisSref.coordinates!=""):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              coordinate = thisSref.coordinates
              x=struct.pack(">i",int(coordinate[0]))
              y=struct.pack(">i",int(coordinate[1]))
              coordinateRecord+=x
              coordinateRecord+=y
  	    #print(thisSref.coordinates)
              self.writeRecord(coordinateRecord)
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
      
      def writeAref(self,thisAref):  #an array of references
          idBits=b'\x0B\x00'  #record Type
          self.writeRecord(idBits)
          if(thisAref.elementFlags!=""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisAref.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisAref.plex):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisAref.plex)
              self.writeRecord(idBits+plex)
          if(thisAref.aName):
              idBits=b'\x12\x06'
              if (len(thisAref.aName) % 2 != 0):
                  aName = thisAref.aName+"\0"
              else:
                  aName = thisAref.aName
              self.writeRecord(idBits+aName)
          if(thisAref.transFlags):
              idBits=b'\x1A\x01'
              mirrorFlag = int(thisAref.transFlags[0])<<15
              # The rotate and magnify flags specify "absolute" rotate and magnify.
              # It is unclear what that is (ignore all further rotates/mags in the
              # hierarchy? But anyway, calibre doesn't support it.
              rotateFlag=0
              magnifyFlag = 0
              #rotateFlag = int(thisAref.transFlags[2])<<1
              #magnifyFlag = int(thisAref.transFlags[1])<<2
              transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
              self.writeRecord(idBits+transFlags)
          if(thisAref.magFactor!=""):
              idBits=b'\x1B\x05'
              magFactor=self.ibmDataFromIeeeDouble(thisAref.magFactor)
              self.writeRecord(idBits+magFactor)
          if(thisAref.rotateAngle!=""):
              idBits=b'\x1C\x05'            
              rotateAngle=self.ibmDataFromIeeeDouble(thisAref.rotateAngle)
              self.writeRecord(idBits+rotateAngle)
          if(thisAref.coordinates):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              for coordinate in thisAref.coordinates:
                  x=struct.pack(">i",coordinate[0])
                  y=struct.pack(">i",coordinate[1])
                  coordinateRecord+=x
                  coordinateRecord+=y
              self.writeRecord(coordinateRecord)
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
      
      def writeText(self,thisText):
          idBits=b'\x0C\x00'  #record Type
          self.writeRecord(idBits)
          if(thisText.elementFlags!=""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisText.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisText.plex !=""):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisText.plex)
              self.writeRecord(idBits+plex)
          if(thisText.drawingLayer != ""):
              idBits=b'\x0D\x02' #drawing layer
              drawingLayer = struct.pack(">h",thisText.drawingLayer)
              self.writeRecord(idBits+drawingLayer)
          #if(thisText.purposeLayer):
              idBits=b'\x16\x02' #purpose layer
              purposeLayer = struct.pack(">h",thisText.purposeLayer)
              self.writeRecord(idBits+purposeLayer)
          if(thisText.transFlags != ""):
              idBits=b'\x1A\x01'
              mirrorFlag = int(thisText.transFlags[0])<<15
              # The rotate and magnify flags specify "absolute" rotate and magnify.
              # It is unclear what that is (ignore all further rotates/mags in the
              # hierarchy? But anyway, calibre doesn't support it.
              rotateFlag=0
              magnifyFlag = 0
              #rotateFlag = int(thisText.transFlags[2])<<1
              #magnifyFlag = int(thisText.transFlags[1])<<2
              transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
              self.writeRecord(idBits+transFlags)
          if(thisText.magFactor!=""):
              idBits=b'\x1B\x05'
              magFactor=self.ibmDataFromIeeeDouble(thisText.magFactor)
              self.writeRecord(idBits+magFactor)
          if(thisText.rotateAngle!=""):
              idBits=b'\x1C\x05'            
              rotateAngle=self.ibmDataFromIeeeDouble(thisText.rotateAngle)
              self.writeRecord(idBits+rotateAngle)
          if(thisText.pathType !=""):
              idBits=b'\x21\x02'  #Path type
              pathType = struct.pack(">h",thisText.pathType)
              self.writeRecord(idBits+pathType)
          if(thisText.pathWidth != ""):
              idBits=b'\x0F\x03'
              pathWidth = struct.pack(">i",thisText.pathWidth)
              self.writeRecord(idBits+pathWidth)
          if(thisText.presentationFlags!=""):
              idBits=b'\x1A\x01'            
              font = thisText.presentationFlags[0]<<4
              verticalFlags = int(thisText.presentationFlags[1])<<2
              horizontalFlags = int(thisText.presentationFlags[2])
              presentationFlags = struct.pack(">H",font|verticalFlags|horizontalFlags)
              self.writeRecord(idBits+transFlags)            
          if(thisText.coordinates!=""):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              for coordinate in thisText.coordinates:
                  x=struct.pack(">i",int(coordinate[0]))
                  y=struct.pack(">i",int(coordinate[1]))
                  coordinateRecord+=x
                  coordinateRecord+=y
              self.writeRecord(coordinateRecord)
          if(thisText.textString):
              idBits=b'\x19\x06'
              textString = thisText.textString
              self.writeRecord(idBits+textString.encode())
              
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
      
      def writeNode(self,thisNode):
          idBits=b'\x15\x00'  #record Type
          self.writeRecord(idBits)
          if(thisNode.elementFlags!=""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisNode.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisNode.plex!=""):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisNode.plex)
              self.writeRecord(idBits+plex)
          if(thisNode.drawingLayer!=""):
              idBits=b'\x0D\x02' #drawig layer
              drawingLayer = struct.pack(">h",thisNode.drawingLayer)
              self.writeRecord(idBits+drawingLayer)            
          if(thisNode.nodeType!=""):
              idBits=b'\x2A\x02'
              nodeType = struct.pack(">h",thisNode.nodeType)
              self.writeRecord(idBits+nodeType)            
          if(thisText.coordinates!=""):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              for coordinate in thisText.coordinates:
                  x=struct.pack(">i",int(coordinate[0]))
                  y=struct.pack(">i",int(coordinate[1]))
                  coordinateRecord+=x
                  coordinateRecord+=y
              self.writeRecord(coordinateRecord)
          
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
      
      def writeBox(self,thisBox):
          idBits=b'\x2E\x02'  #record Type
          self.writeRecord(idBits)
          if(thisBox.elementFlags!=""):
              idBits=b'\x26\x01' #ELFLAGS
              elementFlags = struct.pack(">h",thisBox.elementFlags)
              self.writeRecord(idBits+elementFlags)
          if(thisBox.plex!=""):
              idBits=b'\x2F\x03'  #PLEX
              plex = struct.pack(">i",thisBox.plex)
              self.writeRecord(idBits+plex)
          if(thisBox.drawingLayer!=""):
              idBits=b'\x0D\x02' #drawig layer
              drawingLayer = struct.pack(">h",thisBox.drawingLayer)
              self.writeRecord(idBits+drawingLayer)
          if(thisBox.purposeLayer):
              idBits=b'\x16\x02' #purpose layer
              purposeLayer = struct.pack(">h",thisBox.purposeLayer)
              self.writeRecord(idBits+purposeLayer)
          if(thisBox.boxValue!=""):
              idBits=b'\x2D\x00'
              boxValue = struct.pack(">h",thisBox.boxValue)
              self.writeRecord(idBits+boxValue)            
          if(thisBox.coordinates!=""):
              idBits=b'\x10\x03' #XY Data Points
              coordinateRecord = idBits
              for coordinate in thisBox.coordinates:
                  x=struct.pack(">i",int(coordinate[0]))
                  y=struct.pack(">i",int(coordinate[1]))
                  coordinateRecord+=x
                  coordinateRecord+=y
              self.writeRecord(coordinateRecord)
          
          idBits=b'\x11\x00' #End Of Element
          coordinateRecord = idBits
          self.writeRecord(coordinateRecord)
              
      def writeNextStructure(self,structureName):
          #first put in the structure head
          thisStructure = self.layoutObject.structures[structureName]
          idBits=b'\x05\x02'
          createYear = struct.pack(">h",thisStructure.createDate[0])
          createMonth = struct.pack(">h",thisStructure.createDate[1])
          createDay = struct.pack(">h",thisStructure.createDate[2])
          createHour = struct.pack(">h",thisStructure.createDate[3])
          createMinute = struct.pack(">h",thisStructure.createDate[4])
          createSecond = struct.pack(">h",thisStructure.createDate[5])
          modYear = struct.pack(">h",thisStructure.modDate[0])
          modMonth = struct.pack(">h",thisStructure.modDate[1])
          modDay = struct.pack(">h",thisStructure.modDate[2])
          modHour = struct.pack(">h",thisStructure.modDate[3])
          modMinute = struct.pack(">h",thisStructure.modDate[4])
          modSecond = struct.pack(">h",thisStructure.modDate[5])
          self.writeRecord(idBits+createYear+createMonth+createDay+createHour+createMinute+createSecond\
                           +modYear+modMonth+modDay+modHour+modMinute+modSecond)
          #now the structure name
          idBits=b'\x06\x06'
          ##caveat: the name needs to be an EVEN number of characters
          if(len(structureName)%2 == 1):
              #pad with a zero
              structureName = structureName + '\x00'
          self.writeRecord(idBits+structureName.encode())
          #now go through all the structure elements and write them in
          
          for boundary in thisStructure.boundaries:
              self.writeBoundary(boundary)
          for path in thisStructure.paths:
              self.writePath(path)
          for sref in thisStructure.srefs:
              self.writeSref(sref)
          for aref in thisStructure.arefs:
              self.writeAref(aref)
          for text in thisStructure.texts:
              self.writeText(text)
          for node in thisStructure.nodes:
              self.writeNode(node)
          for box in thisStructure.boxes:
              self.writeBox(box)
          #put in the structure tail
          idBits=b'\x07\x00'
          self.writeRecord(idBits)
      
      def writeGds2(self):
          self.writeHeader();  #first, put the header in
          #go through each structure in the layout and write it to the file
          for structureName in self.layoutObject.structures:
              self.writeNextStructure(structureName)
          #at the end, put in the END LIB record
          idBits=b'\x04\x00'
          self.writeRecord(idBits)
          
      def writeToFile(self,fileName):
          self.fileHandle = open(fileName,"wb")
          self.writeGds2()
          self.fileHandle.close()
  