public void ReadTableRecord(MemoryStream ms) { _validationStatus = OTFile.OTFileValidation_PartialValidation; if (ms.Length - ms.Position < TableRecordSize) { _validationStatus |= OTFile.OTFileValidation_StructureLengthOutOfRange; } try { _tableTag = OTTag.ReadTag(ms); _checksum = OTFile.ReadUInt32(ms); _tableOffset = OTFile.ReadUInt32(ms); _tableLength = OTFile.ReadUInt32(ms); } catch (OTDataIncompleteReadException e) { _validationStatus |= OTFile.OTFileValidation_ReadTrunctated; throw new OTRecordParseException("OT parse error: unable to read table record", e); } } // ReadTableRecord
public void ReadOffsetTable(MemoryStream ms, uint fileOffset) { // offset was validated as in bounds by upstream caller; set read position _offsetInFile = fileOffset; ms.Seek((long)fileOffset, SeekOrigin.Begin); _validationStatus = OTFile.OTFileValidation_PartialValidation; // check length to read sfnt version tag and read if (_offsetInFile + 4 > ms.Length) { _validationStatus |= OTFile.OTFileValidation_OffsetTableLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange; } try { _sfntTag = OTTag.ReadTag(ms); } catch (OTDataIncompleteReadException e) { _validationStatus |= OTFile.OTFileValidation_ReadTrunctated; throw new OTTableParseException("OT parse error: unable to read Offset Table", e); } // check that the sfnt version is supported before continuing if (!OTFont.IsSupportedSfntVersion(_sfntTag)) { _validationStatus |= OTFile.OTFileValidation_SfntVersionNotSupported; throw new OTTableParseException("OT parse error: font resource has an unsupported sfnt version"); } // check length to read remaining header fields, then read if (_offsetInFile + 12 > ms.Length) { _validationStatus |= OTFile.OTFileValidation_OffsetTableLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange; } try { _numTables = OTFile.ReadUInt16(ms); _searchRange = OTFile.ReadUInt16(ms); _entrySelector = OTFile.ReadUInt16(ms); _rangeShift = OTFile.ReadUInt16(ms); } catch (OTDataIncompleteReadException e) { _validationStatus |= OTFile.OTFileValidation_ReadTrunctated; throw new OTTableParseException("OT parse error: unable to read Offset Table", e); } // check length to read encoding records array, then read the records if (_offsetInFile + 12 + _numTables * TableRecord.TableRecordSize > ms.Length) { _validationStatus |= OTFile.OTFileValidation_OffsetTableLengthOutOfRange | OTFile.OTFileValidation_StructureLengthOutOfRange; } _tableRecords = new TableRecord[_numTables]; // constructs struct records with default values _tableMap = new Dictionary <string, uint>(); try { for (uint i = 0; i < _numTables; i++) { _tableRecords[i].ReadTableRecord(ms); try { _tableMap.Add(_tableRecords[i].Tag.ToString(), i); } catch (ArgumentException) { // duplicate tag; first one wins _validationStatus |= OTFile.OTFileValidation_StructureHasDuplicateEntries; } } } catch (OTDataIncompleteReadException e) { _validationStatus |= OTFile.OTFileValidation_ReadTrunctated; throw new OTTableParseException("OT parse error: unable to read Offset Table", e); } } // ReadOffsetTable
public void ReadFromFile(FileInfo fileInfo) { // save fileinfo for later reference _fi = fileInfo; // Check that file exists. (Handle FileStream exception in advance.) if (!_fi.Exists) { throw new FileNotFoundException("File " + _fi.FullName + " was not found.", _fi.FullName); } // read file as a byte array, then construct memory stream from byte array { byte[] bytes; try { // File.ReadAllBytes opens a filestream and then ensures it is closed bytes = File.ReadAllBytes(_fi.FullName); _ms = new MemoryStream(bytes, 0, bytes.Length, false, true); } catch (IOException e) { throw e; } } // Read sfntVersion tag try { _sfntVersionTag = OTTag.ReadTag(_ms); } catch (OTDataIncompleteReadException e) { throw new OTFileParseException("OT parse error: unable to read sfnt tag", e); } // supported format? if (!IsSupportedSfntVersion(_sfntVersionTag)) { _validationStatus = OTFileValidation_SfntVersionNotSupported; throw new OTFileParseException("OT parse error: not a known and supported sfnt type (sfnt tag = " + _sfntVersionTag.ToString()); } _validationStatus = OTFile.OTFileValidation_PartialValidation; // TTC? get TTC header if (_sfntVersionTag == (OTTag)"ttcf") { try { _ttcHeader.ReadTtcHeader(_ms); // will set read position to start of file } catch (OTException e) { _validationStatus = _ttcHeader.ValidationStatus; throw new OTFileParseException("OT parse error: unable to read TTC header", e); } _numFonts = _ttcHeader.NumFonts; } else { _numFonts = 1; } // initialize new font object(s); this will get the font headers for each font resource _fonts = new OTFont[_numFonts]; if (_sfntVersionTag == (OTTag)"ttcf") { for (uint i = 0; i < _numFonts; i++) { _fonts[i] = new OTFont(this, _ttcHeader.OffsetTableOffsets[i], i); } } else // single font { _fonts[0] = new OTFont(this); } // got TTC header; created font objects and got all the header info for each // caller can now poke individual fonts to get additional info as needed // finally, get validation status on ttc header, offset tables _validationStatusOfFonts = new UInt64[_numFonts]; for (int i = 0; i < _numFonts; i++) { // simple validations -- full validation on a table-by-table basis _fonts[i].Validate(_ms.Length, true); } if (_sfntVersionTag == (OTTag)"ttcf") { // treat ttc header validation as part of the file validation _validationStatus |= _ttcHeader.Validate(_ms.Length); // check for validation issues in any of the font resources for (int i = 0; i < _numFonts; i++) { if ((_fonts[i].ValidationStatus & OTFile.OTFileValidation_ValidationIssueMask) != 0) { _validationStatus |= OTFile.OTFileValidation_ValidationIssueInChildStructure; break; } } } else { // treat font resource validation as part of the file validation _validationStatus |= (_fonts[0].ValidationStatus & OTFile.OTFileValidation_ValidationIssueMask); } } // ReadFromFile