summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2019-06-22 17:15:10 +1000
committerDamien Zammit <damien@zamaudio.com>2019-06-22 17:15:56 +1000
commit6240b87cc8639d8402049fdccef2214286d6e0e3 (patch)
tree0eb48da2e05482932ffd20faef4f295bdc0210e6
parentea2a1744a6aeb8d4411586de524952209c263c2f (diff)
Remove nesting limit && fix wasted time recursively scanning regions with no children
-rw-r--r--ptformat.cc18
-rw-r--r--ptformat/ptformat.h2
2 files changed, 10 insertions, 10 deletions
diff --git a/ptformat.cc b/ptformat.cc
index 2fdc2db..b6b13b7 100644
--- a/ptformat.cc
+++ b/ptformat.cc
@@ -566,25 +566,25 @@ PTFFormat::setrates(void) {
}
bool
-PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, int level) {
+PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, struct block_t *parent, int level) {
struct block_t b;
int childjump = 0;
uint32_t i;
+ uint32_t max = _len;
- if (pos + 7 > _len)
- return false;
- if (level > 5)
- return false;
if (_ptfunxored[pos] != ZMARK)
return false;
+ if (parent)
+ max = parent->block_size + parent->offset;
+
b.zmark = ZMARK;
b.block_type = u_endian_read2(&_ptfunxored[pos+1], is_bigendian);
b.block_size = u_endian_read4(&_ptfunxored[pos+3], is_bigendian);
b.content_type = u_endian_read2(&_ptfunxored[pos+7], is_bigendian);
b.offset = pos + 7;
- if (b.block_size + b.offset > _len)
+ if (b.block_size + b.offset > max)
return false;
if (b.block_type & 0xff00)
return false;
@@ -596,11 +596,11 @@ PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, int level) {
block->offset = b.offset;
memset(&block->child, 0, sizeof(block->child));
- for (i = 1; (i < block->block_size) && (pos + i + childjump < _len); i += childjump ? childjump : 1) {
+ for (i = 1; (i < block->block_size) && (pos + i + childjump < max); i += childjump ? childjump : 1) {
int p = pos + i;
struct block_t bchild;
childjump = 0;
- if (parse_block_at(p, &bchild, level+1)) {
+ if (parse_block_at(p, &bchild, block, level+1)) {
block->child.push_back(bchild);
childjump = bchild.block_size + 7;
}
@@ -661,7 +661,7 @@ PTFFormat::parseblocks(void) {
while (i < _len) {
struct block_t b;
- if (parse_block_at(i, &b, 0)) {
+ if (parse_block_at(i, &b, NULL, 0)) {
blocks.push_back(b);
}
i += b.block_size ? b.block_size + 7 : 1;
diff --git a/ptformat/ptformat.h b/ptformat/ptformat.h
index 4b0e8bd..43b4dc1 100644
--- a/ptformat/ptformat.h
+++ b/ptformat/ptformat.h
@@ -267,7 +267,7 @@ private:
bool parseaudio(void);
bool parsemidi(void);
void dump(void);
- bool parse_block_at(uint32_t pos, struct block_t *b, int level);
+ bool parse_block_at(uint32_t pos, struct block_t *b, struct block_t *parent, int level);
void dump_block(struct block_t& b, int level);
bool parse_version();
void parse_region_info(uint32_t j, block_t& blk, region_t& r);