12#define BDEBUG(...)     Ase::debug ("blob", __VA_ARGS__) 
   17error_result (
String url, 
int fallback_errno = EINVAL, 
String msg = 
"failed to load")
 
   19  const int saved_errno = 
errno ? 
errno : fallback_errno;
 
   20  BDEBUG (
"%s %s: %s", msg.c_str(), 
CQUOTE (url), strerror (saved_errno));
 
   33  explicit              BlobImpl (
const String &name, 
size_t dsize, 
const char *data) :
 
   34    name_ (name), size_ (dsize), data_ (data)
 
 
   40  void operator() (
const char*) {}      
 
 
   51StringBlob::StringBlob (
const String &name, 
const String &str) :
 
   52  BlobImpl (name, str.size(), NULL), string_ (str)
 
   54  data_ = string_.
data();
 
   58template<
class Deleter>
 
   64  explicit              ByteBlob        (
const String &name, 
size_t dsize, 
const char *data, 
const Deleter &deleter);
 
   65  virtual              ~ByteBlob        ()              { deleter_ (data_); }
 
 
   68template<
class Deleter>
 
   70  BlobImpl (name, dsize, data), deleter_ (deleter)
 
   73template<
class Deleter> 
String 
   74ByteBlob<Deleter>::string ()
 
   76  if (string_.empty() && size_)
 
   81        string_ = 
String (data_, size_);
 
   90  return implp_ ? implp_->name_ : 
"";
 
 
   93Blob::operator 
bool ()
 const 
   95  return implp_ && implp_->size_;
 
 
  101  return implp_ ? implp_->data_ : NULL;
 
 
  107  return reinterpret_cast<const uint8*
> (
data());
 
 
  113  return implp_ ? implp_->size_ : 0;
 
 
  131  if ((auto_url[0] >= 
'a' && auto_url[0] <= 
'z') || (auto_url[0] >= 
'A' && auto_url[0] <= 
'Z'))
 
  134      while ((auto_url[i] >= 
'a' && auto_url[i] <= 
'z') || (auto_url[i] >= 
'A' && auto_url[i] <= 
'Z') ||
 
  136             (auto_url[i] >= 
'0' && auto_url[i] <= 
'9'))
 
  138      if (auto_url[i] == 
':')
 
  142          implp_ = other.implp_;
 
  148  implp_ = other.implp_;
 
 
  155  if (lurl.
compare (0, 4, 
"res:") == 0)
 
  156    return from_res (url.
c_str() + 4);
 
  157  if (lurl.
compare (0, 5, 
"file:") == 0)
 
 
  164Blob::from_string (
const String &name, 
const String &data)
 
  170string_read (
const String &filename, 
const int fd, 
size_t guess)
 
  174    data.resize (guess + 1);            
 
  178  for (ssize_t l = 1; l > 0; )
 
  180      if (stored >= data.size())        
 
  181        data.resize (2 * data.size());
 
  183        l = 
read (fd, &data[stored], data.size() - stored);
 
  184      while (l < 0 && (errno == EAGAIN || errno == EINTR));
 
  185      stored += 
std::max (ssize_t (0), l);
 
  187        BDEBUG (
"%s: read: %s", filename, strerror (errno));
 
  191  data.resize (stored);
 
  200  const int fd = 
open (filename.
c_str(), O_RDONLY | O_NOCTTY | O_CLOEXEC, 0);
 
  201  struct stat sbuf = { 0, };
 
  202  size_t file_size = 0;
 
  204    return error_result (filename, 
ENOENT);
 
  205  if (
fstat (fd, &sbuf) == 0 && sbuf.st_size)
 
  206    file_size = sbuf.st_size;
 
  209  if (file_size >= 128 * 1024 &&
 
  210      MAP_FAILED != (maddr = 
mmap (NULL, file_size, PROT_READ, MAP_SHARED | MAP_DENYWRITE | MAP_POPULATE, fd, 0)))
 
  213      struct MunmapDeleter {
 
  215        explicit MunmapDeleter (
size_t l) : length (l) {}
 
  216        void     operator()    (
const char *d)         { 
munmap ((
void*) d, length); }
 
  222  String iodata = string_read (filename, fd, file_size);
 
  223  const int saved_errno = 
errno;
 
  227    return from_string (filename, iodata);
 
  229  return error_result (filename, 
ENOENT);
 
 
  257zintern_decompress (
unsigned int decompressed_size, 
const unsigned char *cdata, 
unsigned int cdata_size)
 
  259  uLongf dlen = decompressed_size;
 
  264  int64 result = uncompress (text, &dlen, cdata, cdata_size);
 
  269      if (dlen == decompressed_size)
 
  276      err = 
"internal data corruption";
 
  284      err = 
"insufficient buffer size";
 
  287      err = 
"unknown error";
 
  293      BDEBUG (
"failed to decompress (%p, %u): %s", cdata, cdata_size, err);
 
 
  303  const char *
const           filename_;
 
  304  const size_t                filesize_;
 
  305  const char *
const           packdata_;
 
  306  const size_t                packsize_;
 
  310  LocalResourceEntry (
const char *filename, 
size_t filesize, 
const char *packdata, 
size_t packsize) :
 
  311    filename_ (filename), filesize_ (filesize), packdata_ (packdata), packsize_ (packsize), next_ (chain_)
 
 
  321Blob::from_res (
const char *resource)
 
  326    if (strcmp (resource, entry->filename_) == 0)
 
  329      entry = entry->next_;
 
  332      (entry->filesize_ == entry->packsize_ ||          
 
  333       entry->filesize_ + 1 == entry->packsize_))       
 
  335      if (entry->filesize_ + 1 == entry->packsize_)
 
  340           entry->packsize_ && entry->filesize_ == 0)   
 
  341    return Blob (
std::make_shared<ByteBlob<NoDelete>> (resource, entry->packsize_, entry->packdata_, NoDelete()));
 
  343  if (entry && entry->packsize_ < entry->filesize_)
 
  346      const char *
data = 
reinterpret_cast<const char*
> (u8data);
 
  347      struct ZinternDeleter { 
void operator() (
const char *d) { zintern_free ((uint8*) d); } };
 
  351  return error_result (resource, ENOENT, 
String (entry ? 
"invalid" : 
"unknown") + 
" resource entry");
 
Binary large object storage container.
 
static Blob from_file(const String &filename)
Create Blob by loading from filename.
 
const uint8 * bytes()
Retrieve the Blob's data as uint8 buffer.
 
static Blob from_url(const String &url)
Create Blob by opening a url.
 
String name()
Retrieve the Blob's filename or url.
 
const char * data()
Retrieve the Blob's data.
 
size_t size()
Retrieve the Blob's data size in bytes.
 
String string()
Copy Blob data into a zero terminated string.
 
Blob()
Construct an empty Blob.
 
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
 
#define assert_return_unreached(...)
Return from the current function and issue an assertion warning.
 
#define CQUOTE(str)
Produce a const char* string, wrapping str into C-style double quotes.
 
The Anklang C++ API namespace.
 
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
String string_tolower(const String &str)
Convert all string characters into Unicode lower case characters.
 
uint8_t uint8
An 8-bit unsigned integer.
 
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
uint8 * zintern_decompress(unsigned int decompressed_size, const unsigned char *cdata, unsigned int cdata_size)
 
std::string String
Convenience alias for std::string.
 
void zintern_free(uint8 *dc_data)
Free data returned from zintern_decompress().