]> git.tdb.fi Git - libs/al.git/commitdiff
Add dedicated exception classes for decoding sounds
authorMikko Rasa <tdb@tdb.fi>
Tue, 20 Nov 2012 22:53:11 +0000 (00:53 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 20 Nov 2012 22:53:11 +0000 (00:53 +0200)
source/oggdecoder.cpp
source/oggdecoder.h
source/sounddecoder.cpp
source/sounddecoder.h

index a00b78ed7341bbfb42e1229d006490f15a6514b1..5462b79bb4d8c6c0cdd0c3871cf9e91d1bafdb81 100644 (file)
@@ -1,5 +1,5 @@
-#include <stdexcept>
 #include <vorbis/vorbisfile.h>
+#include <msp/strings/format.h>
 #include "oggdecoder.h"
 
 using namespace std;
@@ -48,6 +48,30 @@ ov_callbacks io_callbacks =
 namespace Msp {
 namespace AL {
 
+ogg_error::ogg_error(const std::string &func, int code):
+       runtime_error(format("%s: %s", func, get_message(code)))
+{ }
+
+string ogg_error::get_message(int code)
+{
+       switch(code)
+       {
+       case OV_FALSE: return "No data available";
+       case OV_HOLE: return "Missing or corrupt data";
+       case OV_EREAD: return "Read error";
+       case OV_EFAULT: return "Internal inconsistency";
+       case OV_EIMPL: return "Not implemented";
+       case OV_EINVAL: return "Invalid argument";
+       case OV_ENOTVORBIS: return "Not Vorbis data";
+       case OV_EBADHEADER: return "Corrupt Vorbis header";
+       case OV_EVERSION: return "Unsupported version";
+       case OV_EBADLINK: return "Bad link";
+       case OV_ENOSEEK: return "Stream is not seekable";
+       default: return format("Unknown error (%d)", code);
+       }
+}
+
+
 struct OggDecoder::Private
 {
        OggVorbis_File ovfile;  
@@ -56,8 +80,9 @@ struct OggDecoder::Private
 OggDecoder::OggDecoder(IO::Seekable &io):
        priv(new Private)
 {
-       if(ov_open_callbacks(&io, &priv->ovfile, 0, 0, io_callbacks)<0)
-               throw runtime_error("Could not open ogg vorbis resource");
+       int ret = ov_open_callbacks(&io, &priv->ovfile, 0, 0, io_callbacks);
+       if(ret<0)
+               throw ogg_error("ov_open_callbacks", ret);
 
        vorbis_info *info = ov_info(&priv->ovfile, -1);
        freq = info->rate;
@@ -68,7 +93,7 @@ OggDecoder::OggDecoder(IO::Seekable &io):
        {
        case 1: format = MONO16; break;
        case 2: format = STEREO16; break;
-       default: throw runtime_error("Unsupported number of channels");
+       default: throw unsupported_sound(Msp::format("%d channels", info->channels));
        }
 }
 
@@ -89,7 +114,7 @@ unsigned OggDecoder::read(char *buf, unsigned len)
        int section = 0;
        int res = ov_read(&priv->ovfile, buf, len, 0, 2, 1, &section);
        if(res<0)
-               throw runtime_error("Error reading ogg vorbis file");
+               throw ogg_error("ov_read", res);
        else if(res==0)
                eof_flag = true;
        return res;
index a3f5504c4c00bac79a4d46f61ea703c13e6eabc0..49cadbb1bea56f3c29b40cd59f4b5f117ca9728f 100644 (file)
@@ -1,11 +1,23 @@
 #ifndef MSP_AL_OGGDECODER_H_
 #define MSP_AL_OGGDECODER_H_
 
+#include <stdexcept>
 #include "sounddecoder.h"
 
 namespace Msp {
 namespace AL {
 
+class ogg_error: public std::runtime_error
+{
+public:
+       ogg_error(const std::string &, int);
+       virtual ~ogg_error() throw() { }
+
+private:
+       static std::string get_message(int);
+};
+
+
 class OggDecoder: public SoundDecoder
 {
 private:
index 77e3b408da40737cb7854af1a8283e489ae7ae99..138117f730a9210545b807a0338bd8887861fa1d 100644 (file)
@@ -8,6 +8,11 @@ using namespace std;
 namespace Msp {
 namespace AL {
 
+unsupported_sound::unsupported_sound(const string &w):
+       runtime_error(w)
+{ }
+
+
 SoundDecoder::SoundDecoder():
        source(0),
        freq(0),
index 7a08644117317623d629b88559788036b5f16e8b..ee5b07d5f33abea2410dc95076f026c0586a1ffc 100644 (file)
@@ -8,6 +8,14 @@
 namespace Msp {
 namespace AL {
 
+class unsupported_sound: public std::runtime_error
+{
+public:
+       unsupported_sound(const std::string &);
+       virtual ~unsupported_sound() throw() { }
+};
+
+
 /**
 This class facilitates loading sound files.  Currently only Ogg Vorbis is
 supported.