public void testSkipToPageOfGranuleAfterTargetPage() throws IOException, InterruptedException { byte[] packet = TestUtil.buildTestData(3 * 254, random); FakeExtractorInput input = TestData.createInput( TestUtil.joinByteArrays( TestData.buildOggHeader(0x01, 20000, 1000, 0x03), TestUtil.createByteArray(254, 254, 254), // Laces. packet, TestData.buildOggHeader(0x04, 40000, 1001, 0x03), TestUtil.createByteArray(254, 254, 254), // Laces. packet, TestData.buildOggHeader(0x04, 60000, 1002, 0x03), TestUtil.createByteArray(254, 254, 254), // Laces. packet), false); try { skipToPageOfGranule(input, 10000, 20000); fail(); } catch (ParserException e) { // ignored } assertEquals(0, input.getPosition()); }
/** * Parses a ContentProtection element. * * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. **/ protected ContentProtection parseContentProtection(XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri"); UUID uuid = null; byte[] psshAtom = null; do { xpp.next(); // The cenc:pssh element is defined in 23001-7:2015 if (isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) { psshAtom = Base64.decode(xpp.getText(), Base64.DEFAULT); uuid = PsshAtomUtil.parseUuid(psshAtom); if (uuid == null) { throw new ParserException("Invalid pssh atom in cenc:pssh element"); } } } while (!isEndTag(xpp, "ContentProtection")); return buildContentProtection(schemeIdUri, uuid, psshAtom); }
/** * Parses an MS/ACM codec private, returning whether it indicates PCM audio. * * @return True if the codec private indicates PCM audio. False otherwise. * @throws ParserException If a parsing error occurs. */ private static boolean parseMsAcmCodecPrivate(ParsableByteArray buffer) throws ParserException { try { int formatTag = buffer.readLittleEndianUnsignedShort(); if (formatTag == WAVE_FORMAT_PCM) { return true; } else if (formatTag == WAVE_FORMAT_EXTENSIBLE) { buffer.setPosition(WAVE_FORMAT_SIZE + 6); // unionSamples(2), channelMask(4) return buffer.readLong() == WAVE_SUBFORMAT_PCM.getMostSignificantBits() && buffer.readLong() == WAVE_SUBFORMAT_PCM.getLeastSignificantBits(); } else { return false; } } catch (ArrayIndexOutOfBoundsException e) { throw new ParserException("Error parsing MS/ACM codec private"); } }
private void parseStreamElementStartTag(XmlPullParser parser) throws ParserException { type = parseType(parser); putNormalizedAttribute(KEY_TYPE, type); if (type == StreamElement.TYPE_TEXT) { subType = parseRequiredString(parser, KEY_SUB_TYPE); } else { subType = parser.getAttributeValue(null, KEY_SUB_TYPE); } name = parser.getAttributeValue(null, KEY_NAME); qualityLevels = parseInt(parser, KEY_QUALITY_LEVELS, -1); url = parseRequiredString(parser, KEY_URL); maxWidth = parseInt(parser, KEY_MAX_WIDTH, -1); maxHeight = parseInt(parser, KEY_MAX_HEIGHT, -1); displayWidth = parseInt(parser, KEY_DISPLAY_WIDTH, -1); displayHeight = parseInt(parser, KEY_DISPLAY_HEIGHT, -1); language = parser.getAttributeValue(null, KEY_LANGUAGE); timescale = parseInt(parser, KEY_TIME_SCALE, -1); if (timescale == -1) { timescale = (Long) getNormalizedAttribute(KEY_TIME_SCALE); } startTimes = new ArrayList<>(); }
/** * Verifies whether the next bytes in {@code header} are a vorbis header of the given * {@code headerType}. * * @param headerType the type of the header expected. * @param header the alleged header bytes. * @param quite if {@code true} no exceptions are thrown. Instead {@code false} is returned. * @return the number of bytes read. * @throws ParserException thrown if header type or capture pattern is not as expected. */ public static boolean verifyVorbisHeaderCapturePattern(int headerType, ParsableByteArray header, boolean quite) throws ParserException { if (header.readUnsignedByte() != headerType) { if (quite) { return false; } else { throw new ParserException("expected header type " + Integer.toHexString(headerType)); } } if (!(header.readUnsignedByte() == 'v' && header.readUnsignedByte() == 'o' && header.readUnsignedByte() == 'r' && header.readUnsignedByte() == 'b' && header.readUnsignedByte() == 'i' && header.readUnsignedByte() == 's')) { if (quite) { return false; } else { throw new ParserException("expected characters 'vorbis'"); } } return true; }
/** * Skips to the position of the start of the page containing the {@code targetGranule} and * returns the elapsed samples which is the granule of the page previous to the target page. * <p> * Note that the position of the {@code input} must be before the start of the page previous to * the page containing the targetGranule to get the correct number of elapsed samples. * Which is in short like: {@code pos(input) <= pos(targetPage.pageSequence - 1)}. * * @param input the {@link ExtractorInput} to read from. * @param targetGranule the target granule (number of frames per channel). * @return the number of elapsed samples at the start of the target page. * @throws ParserException thrown if populating the page header fails. * @throws IOException thrown if reading from the input fails. * @throws InterruptedException thrown if interrupted while reading from the input. */ public long skipToPageOfGranule(ExtractorInput input, long targetGranule) throws IOException, InterruptedException { OggUtil.skipToNextPage(input); OggUtil.populatePageHeader(input, pageHeader, headerArray, false); while (pageHeader.granulePosition < targetGranule) { input.skipFully(pageHeader.headerSize + pageHeader.bodySize); // Store in a member field to be able to resume after IOExceptions. elapsedSamples = pageHeader.granulePosition; // Peek next header. OggUtil.populatePageHeader(input, pageHeader, headerArray, false); } if (elapsedSamples == 0) { throw new ParserException(); } input.resetPeekPosition(); long returnValue = elapsedSamples; // Reset member state. elapsedSamples = 0; currentSegmentIndex = -1; return returnValue; }
void stringElement(int id, String value) throws ParserException { switch (id) { case ID_DOC_TYPE: // Validate that DocType is supported. if (!DOC_TYPE_WEBM.equals(value) && !DOC_TYPE_MATROSKA.equals(value)) { throw new ParserException("DocType " + value + " not supported"); } return; case ID_CODEC_ID: currentTrack.codecId = value; return; case ID_LANGUAGE: currentTrack.language = value; return; default: return; } }
/** * Parses a saio atom (defined in 14496-12). * * @param saio The saio atom to parse. * @param out The {@link TrackFragment} to populate with data from the saio atom. */ private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException { saio.setPosition(Atom.HEADER_SIZE); int fullAtom = saio.readInt(); int flags = Atom.parseFullAtomFlags(fullAtom); if ((flags & 0x01) == 1) { saio.skipBytes(8); } int entryCount = saio.readUnsignedIntToInt(); if (entryCount != 1) { // We only support one trun element currently, so always expect one entry. throw new ParserException("Unexpected saio entry count: " + entryCount); } int version = Atom.parseFullAtomVersion(fullAtom); out.auxiliaryDataPosition += version == 0 ? saio.readUnsignedInt() : saio.readUnsignedLongToLong(); }
private static void parseSenc(ParsableByteArray senc, int offset, TrackFragment out) throws ParserException { senc.setPosition(Atom.HEADER_SIZE + offset); int fullAtom = senc.readInt(); int flags = Atom.parseFullAtomFlags(fullAtom); if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) { // TODO: Implement this. throw new ParserException("Overriding TrackEncryptionBox parameters is unsupported."); } boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0; int sampleCount = senc.readUnsignedIntToInt(); if (sampleCount != out.length) { throw new ParserException("Length mismatch: " + sampleCount + ", " + out.length); } Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption); out.initEncryptionData(senc.bytesLeft()); out.fillEncryptionData(senc); }
public void testReadVorbisModes() throws ParserException { byte[] data = TestData.getSetupHeaderData(); ParsableByteArray headerData = new ParsableByteArray(data, data.length); VorbisUtil.Mode[] modes = VorbisUtil.readVorbisModes(headerData, 2); assertEquals(2, modes.length); assertEquals(false, modes[0].blockFlag); assertEquals(0, modes[0].mapping); assertEquals(0, modes[0].transformType); assertEquals(0, modes[0].windowType); assertEquals(true, modes[1].blockFlag); assertEquals(1, modes[1].mapping); assertEquals(0, modes[1].transformType); assertEquals(0, modes[1].windowType); }
private void readEncryptionData(ExtractorInput input) throws IOException, InterruptedException { TrackBundle nextTrackBundle = null; long nextDataOffset = Long.MAX_VALUE; int trackBundlesSize = trackBundles.size(); for (int i = 0; i < trackBundlesSize; i++) { TrackFragment trackFragment = trackBundles.valueAt(i).fragment; if (trackFragment.sampleEncryptionDataNeedsFill && trackFragment.auxiliaryDataPosition < nextDataOffset) { nextDataOffset = trackFragment.auxiliaryDataPosition; nextTrackBundle = trackBundles.valueAt(i); } } if (nextTrackBundle == null) { parserState = STATE_READING_SAMPLE_START; return; } int bytesToSkip = (int) (nextDataOffset - input.getPosition()); if (bytesToSkip < 0) { throw new ParserException("Offset to encryption data was negative."); } input.skipFully(bytesToSkip); nextTrackBundle.fragment.fillEncryptionData(input); }
private static Cue parseVttCueBox(ParsableByteArray sampleData, WebvttCue.Builder builder, int remainingCueBoxBytes) throws ParserException { builder.reset(); while (remainingCueBoxBytes > 0) { if (remainingCueBoxBytes < BOX_HEADER_SIZE) { throw new ParserException("Incomplete vtt cue box header found."); } int boxSize = sampleData.readInt(); int boxType = sampleData.readInt(); remainingCueBoxBytes -= BOX_HEADER_SIZE; int payloadLength = boxSize - BOX_HEADER_SIZE; String boxPayload = new String(sampleData.data, sampleData.getPosition(), payloadLength); sampleData.skipBytes(payloadLength); remainingCueBoxBytes -= payloadLength; if (boxType == TYPE_sttg) { WebvttCueParser.parseCueSettingsList(boxPayload, builder); } else if (boxType == TYPE_payl) { WebvttCueParser.parseCueText(boxPayload.trim(), builder); } else { // Other VTTCueBox children are still not supported and are ignored. } } return builder.build(); }
public static TvListing parse(InputStream inputStream) { try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(inputStream, null); int eventType = parser.next(); if (eventType != XmlPullParser.START_TAG || !TAG_TV.equals(parser.getName())) { throw new ParserException( "inputStream does not contain a xml tv description"); } return parseTvListings(parser); } catch (XmlPullParserException | IOException | ParseException e) { e.printStackTrace(); } return null; }
@Override public HlsPlaylist parse(String connectionUrl, InputStream inputStream) throws IOException, ParserException { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); Queue<String> extraLines = new LinkedList<>(); String line; try { while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty()) { // Do nothing. } else if (line.startsWith(STREAM_INF_TAG)) { extraLines.add(line); return parseMasterPlaylist(new LineIterator(extraLines, reader), connectionUrl); } else if (line.startsWith(TARGET_DURATION_TAG) || line.startsWith(MEDIA_SEQUENCE_TAG) || line.startsWith(MEDIA_DURATION_TAG) || line.startsWith(KEY_TAG) || line.startsWith(BYTERANGE_TAG) || line.equals(DISCONTINUITY_TAG) || line.equals(ENDLIST_TAG)) { extraLines.add(line); return parseMediaPlaylist(new LineIterator(extraLines, reader), connectionUrl); } else { extraLines.add(line); } } } finally { reader.close(); } throw new ParserException("Failed to parse the playlist, could not identify any tags."); }
public void testPrepareInvalidContentEncAlgo() throws IOException, InterruptedException { ContentEncodingSettings settings = new ContentEncodingSettings(0, 1, 4, 1); byte[] data = new StreamBuilder() .setHeader(WEBM_DOC_TYPE) .setInfo(DEFAULT_TIMECODE_SCALE, TEST_DURATION_TIMECODE) .addVp9Track(VIDEO_TRACK_NUMBER, TEST_WIDTH, TEST_HEIGHT, settings) .build(1); try { TestUtil.consumeTestData(extractor, data); fail(); } catch (ParserException exception) { assertEquals("ContentEncAlgo 4 not supported", exception.getMessage()); } }
public void testPrepareInvalidContentEncodingScope() throws IOException, InterruptedException { ContentEncodingSettings settings = new ContentEncodingSettings(0, 0, 5, 1); byte[] data = new StreamBuilder() .setHeader(WEBM_DOC_TYPE) .setInfo(DEFAULT_TIMECODE_SCALE, TEST_DURATION_TIMECODE) .addVp9Track(VIDEO_TRACK_NUMBER, TEST_WIDTH, TEST_HEIGHT, settings) .build(1); try { TestUtil.consumeTestData(extractor, data); fail(); } catch (ParserException exception) { assertEquals("ContentEncodingScope 0 not supported", exception.getMessage()); } }
/** * Parses an ID3 header. * * @param id3Buffer A {@link ParsableByteArray} from which data should be read. * @return The size of ID3 frames in bytes, excluding the header and footer. * @throws ParserException If ID3 file identifier != "ID3". */ private static int parseId3Header(ParsableByteArray id3Buffer) throws ParserException { int id1 = id3Buffer.readUnsignedByte(); int id2 = id3Buffer.readUnsignedByte(); int id3 = id3Buffer.readUnsignedByte(); if (id1 != 'I' || id2 != 'D' || id3 != '3') { throw new ParserException(String.format(Locale.US, "Unexpected ID3 file identifier, expected \"ID3\", actual \"%c%c%c\".", id1, id2, id3)); } id3Buffer.skipBytes(2); // Skip version. int flags = id3Buffer.readUnsignedByte(); int id3Size = id3Buffer.readSynchSafeInt(); // Check if extended header presents. if ((flags & 0x2) != 0) { int extendedHeaderSize = id3Buffer.readSynchSafeInt(); if (extendedHeaderSize > 4) { id3Buffer.skipBytes(extendedHeaderSize - 4); } id3Size -= extendedHeaderSize; } // Check if footer presents. if ((flags & 0x8) != 0) { id3Size -= 10; } return id3Size; }
private void resolveDirect() { try { long utcTimestamp = Util.parseXsDateTime(timingElement.value); long elapsedRealtimeOffset = utcTimestamp - timingElementElapsedRealtime; callback.onTimestampResolved(timingElement, elapsedRealtimeOffset); } catch (ParseException e) { callback.onTimestampError(timingElement, new ParserException(e)); } }
public void testPrepareInvalidContentCompAlgo() throws IOException, InterruptedException { ContentEncodingSettings settings = new ContentEncodingSettings(0, 1, 0, new byte[0]); byte[] data = new StreamBuilder() .setHeader(WEBM_DOC_TYPE) .setInfo(DEFAULT_TIMECODE_SCALE, TEST_DURATION_TIMECODE) .addVp9Track(VIDEO_TRACK_NUMBER, TEST_WIDTH, TEST_HEIGHT, settings) .build(1); try { TestUtil.consumeTestData(extractor, data); fail(); } catch (ParserException exception) { assertEquals("ContentCompAlgo 0 not supported", exception.getMessage()); } }
@Override public Long parse(String connectionUrl, InputStream inputStream) throws ParserException, IOException { String firstLine = new BufferedReader(new InputStreamReader(inputStream)).readLine(); try { // TODO: It may be necessary to handle timestamp offsets from UTC. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); format.setTimeZone(TimeZone.getTimeZone("UTC")); return format.parse(firstLine).getTime(); } catch (ParseException e) { throw new ParserException(e); } }
@Override public SmoothStreamingManifest parse(String connectionUrl, InputStream inputStream) throws IOException, ParserException { try { XmlPullParser xmlParser = xmlParserFactory.newPullParser(); xmlParser.setInput(inputStream, null); SmoothStreamMediaParser smoothStreamMediaParser = new SmoothStreamMediaParser(null, connectionUrl); return (SmoothStreamingManifest) smoothStreamMediaParser.parse(xmlParser); } catch (XmlPullParserException e) { throw new ParserException(e); } }
public void testParseTextInformationFrame() throws ParserException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 23, 84, 73, 84, 50, 0, 0, 0, 13, 0, 0, 3, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0}; Id3Parser parser = new Id3Parser(); List<Id3Frame> id3Frames = parser.parse(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); TextInformationFrame textInformationFrame = (TextInformationFrame) id3Frames.get(0); assertEquals("TIT2", textInformationFrame.id); assertEquals("Hello World", textInformationFrame.description); }
protected final long parseLong(XmlPullParser parser, String key, long defaultValue) throws ParserException { String value = parser.getAttributeValue(null, key); if (value != null) { try { return Long.parseLong(value); } catch (NumberFormatException e) { throw new ParserException(e); } } else { return defaultValue; } }
protected final long parseRequiredLong(XmlPullParser parser, String key) throws ParserException { String value = parser.getAttributeValue(null, key); if (value != null) { try { return Long.parseLong(value); } catch (NumberFormatException e) { throw new ParserException(e); } } else { throw new MissingFieldException(key); } }
@Override public void parseStartTag(XmlPullParser parser) throws ParserException { majorVersion = parseRequiredInt(parser, KEY_MAJOR_VERSION); minorVersion = parseRequiredInt(parser, KEY_MINOR_VERSION); timescale = parseLong(parser, KEY_TIME_SCALE, 10000000L); duration = parseRequiredLong(parser, KEY_DURATION); dvrWindowLength = parseLong(parser, KEY_DVR_WINDOW_LENGTH, 0); lookAheadCount = parseInt(parser, KEY_LOOKAHEAD_COUNT, -1); isLive = parseBoolean(parser, KEY_IS_LIVE, false); putNormalizedAttribute(KEY_TIME_SCALE, timescale); }
private void parseStreamFragmentStartTag(XmlPullParser parser) throws ParserException { int chunkIndex = startTimes.size(); long startTime = parseLong(parser, KEY_FRAGMENT_START_TIME, -1L); if (startTime == -1L) { if (chunkIndex == 0) { // Assume the track starts at t = 0. startTime = 0; } else if (lastChunkDuration != -1L) { // Infer the start time from the previous chunk's start time and duration. startTime = startTimes.get(chunkIndex - 1) + lastChunkDuration; } else { // We don't have the start time, and we're unable to infer it. throw new ParserException("Unable to infer start time"); } } chunkIndex++; startTimes.add(startTime); lastChunkDuration = parseLong(parser, KEY_FRAGMENT_DURATION, -1L); // Handle repeated chunks. long repeatCount = parseLong(parser, KEY_FRAGMENT_REPEAT_COUNT, 1L); if (repeatCount > 1 && lastChunkDuration == -1L) { throw new ParserException("Repeated chunk with unspecified duration"); } for (int i = 1; i < repeatCount; i++) { chunkIndex++; startTimes.add(startTime + (lastChunkDuration * i)); } }
private int parseType(XmlPullParser parser) throws ParserException { String value = parser.getAttributeValue(null, KEY_TYPE); if (value != null) { if (KEY_TYPE_AUDIO.equalsIgnoreCase(value)) { return StreamElement.TYPE_AUDIO; } else if (KEY_TYPE_VIDEO.equalsIgnoreCase(value)) { return StreamElement.TYPE_VIDEO; } else if (KEY_TYPE_TEXT.equalsIgnoreCase(value)) { return StreamElement.TYPE_TEXT; } else { throw new ParserException("Invalid key value[" + value + "]"); } } throw new MissingFieldException(KEY_TYPE); }
@Override public HlsPlaylist parse(String connectionUrl, InputStream inputStream) throws IOException, ParserException { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); Queue<String> extraLines = new LinkedList<>(); String line; try { while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty()) { // Do nothing. } else if (line.startsWith(STREAM_INF_TAG)) { extraLines.add(line); return parseMasterPlaylist(new LineIterator(extraLines, reader), connectionUrl); } else if (line.startsWith(TARGET_DURATION_TAG) || line.startsWith(MEDIA_SEQUENCE_TAG) || line.startsWith(MEDIA_DURATION_TAG) || line.startsWith(KEY_TAG) || line.startsWith(BYTERANGE_TAG) || line.equals(DISCONTINUITY_TAG) || line.equals(DISCONTINUITY_SEQUENCE_TAG) || line.equals(ENDLIST_TAG)) { extraLines.add(line); return parseMediaPlaylist(new LineIterator(extraLines, reader), connectionUrl); } else { extraLines.add(line); } } } finally { reader.close(); } throw new ParserException("Failed to parse the playlist, could not identify any tags."); }
public static String parseStringAttr(String line, Pattern pattern, String tag) throws ParserException { Matcher matcher = pattern.matcher(line); if (matcher.find() && matcher.groupCount() == 1) { return matcher.group(1); } throw new ParserException("Couldn't match " + tag + " tag in " + line); }
/** * Skips to the data in the given WAV input stream and returns its data size. After calling, the * input stream's position will point to the start of sample data in the WAV. * <p> * If an exception is thrown, the input position will be left pointing to a chunk header. * * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to * a valid chunk header. * @param wavHeader WAV header to populate with data bounds. * @throws IOException If reading from the input fails. * @throws InterruptedException If interrupted while reading from input. * @throws ParserException If an error occurs parsing chunks. */ public static void skipToData(ExtractorInput input, WavHeader wavHeader) throws IOException, InterruptedException, ParserException { Assertions.checkNotNull(input); Assertions.checkNotNull(wavHeader); // Make sure the peek position is set to the read position before we peek the first header. input.resetPeekPosition(); ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES); // Skip all chunks until we hit the data header. ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch); while (chunkHeader.id != Util.getIntegerCodeForString("data")) { Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id); long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size; // Override size of RIFF chunk, since it describes its size as the entire file. if (chunkHeader.id == Util.getIntegerCodeForString("RIFF")) { bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4; } if (bytesToSkip > Integer.MAX_VALUE) { throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id); } input.skipFully((int) bytesToSkip); chunkHeader = ChunkHeader.peek(input, scratch); } // Skip past the "data" header. input.skipFully(ChunkHeader.SIZE_IN_BYTES); wavHeader.setDataBounds(input.getPosition(), chunkHeader.size); }
/** * Reads a vorbis comment header. * * @see <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3"> * Vorbis spec/Comment header</a> * @param headerData a {@link ParsableByteArray} wrapping the header data. * @return a {@link VorbisUtil.CommentHeader} with all the comments. * @throws ParserException thrown if invalid capture pattern is detected. */ public static CommentHeader readVorbisCommentHeader(ParsableByteArray headerData) throws ParserException { verifyVorbisHeaderCapturePattern(0x03, headerData, false); int length = 7; int len = (int) headerData.readLittleEndianUnsignedInt(); length += 4; String vendor = headerData.readString(len); length += vendor.length(); long commentListLen = headerData.readLittleEndianUnsignedInt(); String[] comments = new String[(int) commentListLen]; length += 4; for (int i = 0; i < commentListLen; i++) { len = (int) headerData.readLittleEndianUnsignedInt(); length += 4; comments[i] = headerData.readString(len); length += comments[i].length(); } if ((headerData.readUnsignedByte() & 0x01) == 0) { throw new ParserException("framing bit expected to be set"); } length += 1; return new CommentHeader(vendor, comments, length); }
private static void readResidues(VorbisBitArray bitArray) throws ParserException { int residueCount = bitArray.readBits(6) + 1; for (int i = 0; i < residueCount; i++) { int residueType = bitArray.readBits(16); if (residueType > 2) { throw new ParserException("residueType greater than 2 is not decodable"); } else { bitArray.skipBits(24); // begin bitArray.skipBits(24); // end bitArray.skipBits(24); // partitionSize (add one) int classifications = bitArray.readBits(6) + 1; bitArray.skipBits(8); // classbook int[] cascade = new int[classifications]; for (int j = 0; j < classifications; j++) { int highBits = 0; int lowBits = bitArray.readBits(3); if (bitArray.readBit()) { highBits = bitArray.readBits(5); } cascade[j] = highBits * 8 + lowBits; } for (int j = 0; j < classifications; j++) { for (int k = 0; k < 8; k++) { if ((cascade[j] & (0x01 << k)) != 0) { bitArray.skipBits(8); // discard } } } } } }
protected final int parseRequiredInt(XmlPullParser parser, String key) throws ParserException { String value = parser.getAttributeValue(null, key); if (value != null) { try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw new ParserException(e); } } else { throw new MissingFieldException(key); } }
public void testParseTxxxFrame() throws ParserException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 41, 84, 88, 88, 88, 0, 0, 0, 31, 0, 0, 3, 0, 109, 100, 105, 97, 108, 111, 103, 95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0}; Id3Parser parser = new Id3Parser(); List<Id3Frame> id3Frames = parser.parse(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); TxxxFrame txxxFrame = (TxxxFrame) id3Frames.get(0); assertEquals("", txxxFrame.description); assertEquals("mdialog_VINDICO1527664_start", txxxFrame.value); }
public void testPrepareInvalidAESSettingsCipherMode() throws IOException, InterruptedException { ContentEncodingSettings settings = new ContentEncodingSettings(0, 1, 5, 0); byte[] data = new StreamBuilder() .setHeader(WEBM_DOC_TYPE) .setInfo(DEFAULT_TIMECODE_SCALE, TEST_DURATION_TIMECODE) .addVp9Track(VIDEO_TRACK_NUMBER, TEST_WIDTH, TEST_HEIGHT, settings) .build(1); try { TestUtil.consumeTestData(extractor, data); fail(); } catch (ParserException exception) { assertEquals("AESSettingsCipherMode 0 not supported", exception.getMessage()); } }
private static void parseFontSize(String expression, TtmlStyle out) throws ParserException { String[] expressions = expression.split("\\s+"); Matcher matcher; if (expressions.length == 1) { matcher = FONT_SIZE.matcher(expression); } else if (expressions.length == 2){ matcher = FONT_SIZE.matcher(expressions[1]); Log.w(TAG, "Multiple values in fontSize attribute. Picking the second value for vertical font" + " size and ignoring the first."); } else { throw new ParserException("Invalid number of entries for fontSize: " + expressions.length + ""); } if (matcher.matches()) { String unit = matcher.group(3); switch (unit) { case "px": out.setFontSizeUnit(TtmlStyle.FONT_SIZE_UNIT_PIXEL); break; case "em": out.setFontSizeUnit(TtmlStyle.FONT_SIZE_UNIT_EM); break; case "%": out.setFontSizeUnit(TtmlStyle.FONT_SIZE_UNIT_PERCENT); break; default: throw new ParserException("Invalid unit for fontSize: '" + unit + "'."); } out.setFontSize(Float.valueOf(matcher.group(1))); } else { throw new ParserException("Invalid expression for fontSize: '" + expression + "'."); } }
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray, int flags, byte[] extendedTypeScratch) throws ParserException { int moofContainerChildrenSize = moof.containerChildren.size(); for (int i = 0; i < moofContainerChildrenSize; i++) { Atom.ContainerAtom child = moof.containerChildren.get(i); if (child.type == Atom.TYPE_traf) { parseTraf(child, trackBundleArray, flags, extendedTypeScratch); } } }