Implement decent seeking in DTSC::File.
This commit is contained in:
parent
c6407b3aa1
commit
b8a2993c73
2 changed files with 44 additions and 7 deletions
48
lib/dtsc.cpp
48
lib/dtsc.cpp
|
@ -221,20 +221,24 @@ DTSC::File::File(std::string filename, bool create){
|
||||||
headerSize = ntohl(ubuffer[0]);
|
headerSize = ntohl(ubuffer[0]);
|
||||||
}
|
}
|
||||||
fseek(F, 8+headerSize, SEEK_SET);
|
fseek(F, 8+headerSize, SEEK_SET);
|
||||||
|
currframe = 1;
|
||||||
|
frames[currframe] = ftell(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the header metadata for this file as a std::string.
|
/// Returns the header metadata for this file as a std::string.
|
||||||
/// Sets the file pointer to the first packet.
|
/// Sets the file pointer to the first packet.
|
||||||
std::string & DTSC::File::getHeader(){
|
std::string & DTSC::File::getHeader(){
|
||||||
fseek(F, 8, SEEK_SET);
|
if (fseek(F, 8, SEEK_SET) != 0){
|
||||||
|
strbuffer = "";
|
||||||
|
return strbuffer;
|
||||||
|
}
|
||||||
strbuffer.resize(headerSize);
|
strbuffer.resize(headerSize);
|
||||||
if (fread((void*)strbuffer.c_str(), headerSize, 1, F) != headerSize){
|
if (fread((void*)strbuffer.c_str(), headerSize, 1, F) != 1){
|
||||||
/// \todo check seek as well and do something more sensible...
|
strbuffer = "";
|
||||||
#if DEBUG >= 10
|
return strbuffer;
|
||||||
fprintf(stderr, "Panic! Invalid DTSC File header\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
fseek(F, 8+headerSize, SEEK_SET);
|
fseek(F, 8+headerSize, SEEK_SET);
|
||||||
|
currframe = 1;
|
||||||
return strbuffer;
|
return strbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +258,7 @@ bool DTSC::File::writeHeader(std::string & header, bool force){
|
||||||
|
|
||||||
/// Reads the packet available at the current file position, returning it as a std::string.
|
/// Reads the packet available at the current file position, returning it as a std::string.
|
||||||
/// If the packet could not be read for any reason, the reason is printed to stderr and an empty string returned.
|
/// If the packet could not be read for any reason, the reason is printed to stderr and an empty string returned.
|
||||||
|
/// Reading the packet means the file position is increased to the next packet.
|
||||||
std::string & DTSC::File::getPacket(){
|
std::string & DTSC::File::getPacket(){
|
||||||
if (fread(buffer, 4, 1, F) != 1){
|
if (fread(buffer, 4, 1, F) != 1){
|
||||||
fprintf(stderr, "Could not read header\n");
|
fprintf(stderr, "Could not read header\n");
|
||||||
|
@ -261,7 +266,7 @@ std::string & DTSC::File::getPacket(){
|
||||||
return strbuffer;
|
return strbuffer;
|
||||||
}
|
}
|
||||||
if (memcmp(buffer, DTSC::Magic_Packet, 4) != 0){
|
if (memcmp(buffer, DTSC::Magic_Packet, 4) != 0){
|
||||||
fprintf(stderr, "Could not overwrite header - not equal size\n");
|
fprintf(stderr, "Invalid header\n");
|
||||||
strbuffer = "";
|
strbuffer = "";
|
||||||
return strbuffer;
|
return strbuffer;
|
||||||
}
|
}
|
||||||
|
@ -278,9 +283,38 @@ std::string & DTSC::File::getPacket(){
|
||||||
strbuffer = "";
|
strbuffer = "";
|
||||||
return strbuffer;
|
return strbuffer;
|
||||||
}
|
}
|
||||||
|
currframe++;
|
||||||
|
frames[currframe] = ftell(F);
|
||||||
return strbuffer;
|
return strbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to seek to the given frame number within the file.
|
||||||
|
/// Returns true if successful, false otherwise.
|
||||||
|
bool DTSC::File::seek_frame(int frameno){
|
||||||
|
std::map<int, long>::iterator it = frames.lower_bound(frameno);
|
||||||
|
if (it->first == frameno){
|
||||||
|
if (fseek(F, it->second, SEEK_SET) == 0){
|
||||||
|
currframe = frameno;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (fseek(F, it->second, SEEK_SET) == 0){
|
||||||
|
currframe = it->first;
|
||||||
|
while (currframe < frameno){
|
||||||
|
if (fread(buffer, 4, 1, F) != 1){return false;}//read header
|
||||||
|
if (memcmp(buffer, DTSC::Magic_Packet, 4) != 0){return false;}//check header
|
||||||
|
if (fread(buffer, 4, 1, F) != 1){return false;}//read size
|
||||||
|
uint32_t * ubuffer = (uint32_t *)buffer;
|
||||||
|
long packSize = ntohl(ubuffer[0]);
|
||||||
|
if (fseek(F, packSize, SEEK_CUR) != 0){return false;}//seek to next packet
|
||||||
|
currframe++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Close the file if open
|
/// Close the file if open
|
||||||
DTSC::File::~File(){
|
DTSC::File::~File(){
|
||||||
if (F){
|
if (F){
|
||||||
|
|
|
@ -70,8 +70,11 @@ namespace DTSC{
|
||||||
std::string & getHeader();
|
std::string & getHeader();
|
||||||
bool writeHeader(std::string & header, bool force = false);
|
bool writeHeader(std::string & header, bool force = false);
|
||||||
std::string & getPacket();
|
std::string & getPacket();
|
||||||
|
bool seek_frame(int frameno);
|
||||||
private:
|
private:
|
||||||
std::string strbuffer;
|
std::string strbuffer;
|
||||||
|
std::map<int, long> frames;
|
||||||
|
int currframe;
|
||||||
FILE * F;
|
FILE * F;
|
||||||
unsigned long headerSize;
|
unsigned long headerSize;
|
||||||
char buffer[4];
|
char buffer[4];
|
||||||
|
|
Loading…
Add table
Reference in a new issue