HomeForumSourceResearchGuide
Sign in to contribute to source. how it works
Component composition.ObjectReader by barry
expand copy to clipboardexpand
//magic header of a Dana object matching the below format
const byte danaMagic[] = new int[](0x44, 0x41, 0x4E, 0x41, 0x0, 0x1)

//a Dana object header
data SourceHeader{
	//basic identification; this part is always the same total size
	byte magic[6]
	byte checksum[4]
	byte objectType[2]
	byte hostType[2]
	byte vpuType[2]
	//the below fields are each the size of the target host machine's native address width
	//machine code
	int textOffset
	int textSize
	//local relocations; a list of addresses to add the start address of this object to
	int lrTableOffset
	int lrTableSize
	int lrTableCount
	//info sections (if one of these is hardlinks then this object file is not fit to be loaded)
	int infoSectionsOffset
	int infoSectionsSize
	int infoSectionsCount
	}

//an info section header
data DanaInfoSection{
	byte sectionType[4] //type code identifying the section's purpose (0.x.x.x, D.N.x.x, F.R.x.x are reserved)
	byte contentType[4] //type code identifying the kind of content (json, xml, jpeg, etc.)
	int size //size of the section's content, excluding this header
	}

component provides ObjectReader requires io.File, System system {
	
	char objectPath[]
	ObjectInfo info
	int lastInfoIndex
	int infoSectionsOffset
	
	ObjectReader:ObjectReader(char path[])
		{
		File fd = new File(path, File.READ)
		
		if (fd == null)
			throw new Exception("File not found")
		
		SourceHeader hdr = new SourceHeader()
		byte serialHDR[] = dana.serial(hdr)
		
		byte buf[]
		
		if ((buf = fd.read(serialHDR.arrayLength)).arrayLength != serialHDR.arrayLength)
			{
			throw new Exception("Error: File is not a Dana object")
			}
		
		serialHDR =[] buf
		
		if (hdr.magic != danaMagic)
			{
			throw new Exception("Error: File is not a Dana object")
			}
		
		if (hdr.hostType != system.getHostType())
			{
			throw new Exception("Error: File was compiled for a different architecture")
			}
		
		if (hdr.vpuType != system.getVMType())
			{
			throw new Exception("Error: File was compiled for a different VPU version")
			}
		
		info = new ObjectInfo(hdr.textSize, hdr.infoSectionsCount, hdr.lrTableCount)
		infoSectionsOffset = hdr.infoSectionsOffset
		
		fd.close()
		
		objectPath = path
		}
	
	ObjectInfo ObjectReader:getInfo()
		{
		return info
		}
	
	InfoSection ObjectReader:getNextSection()
		{
		File fd = new File(objectPath, File.READ)
		
		if (fd == null)
			{
			throw new Exception("Object file $objectPath is no longer readable")
			}
		
		if (lastInfoIndex >= info.infoSectionCount)
			{
			lastInfoIndex = 0
			return null
			}
		
		fd.setPos(infoSectionsOffset)
		for (int i = 0; i < lastInfoIndex; i++)
			{
			byte serialData[]
			
			DanaInfoSection is = new DanaInfoSection()
			serialData = dana.serial(is)
			serialData =[] fd.read(serialData.arrayLength)
			
			byte contents[] = fd.read(is.size)
			}
		
		//read the actual one we want
		InfoSection section = new InfoSection()
		
		byte serialData[]
		
		DanaInfoSection is
		serialData = dana.serial(is)
		serialData =[] fd.read(serialData.arrayLength)
		
		section.sectionType = is.sectionType
		section.contentType = is.contentType
		section.content = fd.read(is.size)
		
		fd.close()
		
		lastInfoIndex ++
		
		return section
		}
	
	InfoSection ObjectReader:getInfoSection(char type[])
		{
		File fd = new File(objectPath, File.READ)
		
		if (fd == null)
			{
			throw new Exception("Object file $objectPath is no longer readable")
			}
		
		fd.setPos(infoSectionsOffset)
		for (int i = 0; i < info.infoSectionCount; i++)
			{
			byte serialData[]
			
			DanaInfoSection is = new DanaInfoSection()
			serialData = dana.serial(is)
			serialData =[] fd.read(serialData.arrayLength)
			
			byte contents[] = fd.read(is.size)
			
			if (is.sectionType == type)
				{
				InfoSection section = new InfoSection(is.sectionType, is.contentType, contents)
				fd.close()
				return section
				}
			}
		
		fd.close()
		
		return null
		}
	
	char[] ObjectReader:getPath()
		{
		return objectPath
		}
	
	int ObjectReader:getCurrentInfoSectionIndex()
		{
		if (lastInfoIndex > 0)
			return lastInfoIndex - 1
			else
			return lastInfoIndex
		}
	
	}
Revision history
To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n composition.ObjectReader -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: Standard Library Initialisation