Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions
mar_read.c File Reference
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mar.h"
#include "mar_private.h"
#include <netinet/in.h>

Go to the source code of this file.

Classes

struct  MarFile_

Defines

#define TABLESIZE   256

Functions

static PRUint32 mar_hash_name (const char *name)
static int mar_insert_item (MarFile *mar, const char *name, int namelen, PRUint32 offset, PRUint32 length, PRUint32 flags)
static int mar_consume_index (MarFile *mar, char **buf, const char *buf_end)
static int mar_read_index (MarFile *mar)
MarFile * mar_open (const char *path)
 Open a MAR file for reading.
void mar_close (MarFile *mar)
 Close a MAR file that was opened using mar_open.
const MarItemmar_find_item (MarFile *mar, const char *name)
 Find an item in the MAR file by name.
int mar_enum_items (MarFile *mar, MarItemCallback callback, void *closure)
 Enumerate all MAR items via callback function.
int mar_read (MarFile *mar, const MarItem *item, int offset, char *buf, int bufsize)
 Read from MAR item at given offset up to bufsize bytes.

Class Documentation

struct MarFile_

Definition at line 55 of file mar_read.c.

Collaboration diagram for MarFile_:
Class Members
FILE * fp
MarItem * item_table

Define Documentation

#define TABLESIZE   256

Definition at line 53 of file mar_read.c.


Function Documentation

void mar_close ( MarFile *  mar)

Close a MAR file that was opened using mar_open.

Parameters:
marThe MarFile object to close.

Definition at line 206 of file mar_read.c.

                             {
  MarItem *item;
  int i;

  fclose(mar->fp);

  for (i = 0; i < TABLESIZE; ++i) {
    item = mar->item_table[i];
    while (item) {
      MarItem *temp = item;
      item = item->next;
      free(temp);
    }
  }

  free(mar);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int mar_consume_index ( MarFile *  mar,
char **  buf,
const char *  buf_end 
) [static]

Definition at line 99 of file mar_read.c.

                                                                            {
  /*
   * Each item has the following structure:
   *   PRUint32 offset      (network byte order)
   *   PRUint32 length      (network byte order)
   *   PRUint32 flags       (network byte order)
   *   char     name[N]     (where N >= 1)
   *   char     null_byte;
   */
  PRUint32 offset;
  PRUint32 length;
  PRUint32 flags;
  const char *name;
  int namelen;

  if ((buf_end - *buf) < (int)(3*sizeof(PRUint32) + 2))
    return -1;

  memcpy(&offset, *buf, sizeof(offset));
  *buf += sizeof(offset);

  memcpy(&length, *buf, sizeof(length));
  *buf += sizeof(length);

  memcpy(&flags, *buf, sizeof(flags));
  *buf += sizeof(flags);

  offset = ntohl(offset);
  length = ntohl(length);
  flags = ntohl(flags);

  name = *buf;
  /* find namelen; must take care not to read beyond buf_end */
  while (**buf) {
    if (*buf == buf_end)
      return -1;
    ++(*buf);
  }
  namelen = (*buf - name);
  /* consume null byte */
  if (*buf == buf_end)
    return -1;
  ++(*buf);

  return mar_insert_item(mar, name, namelen, offset, length, flags);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mar_enum_items ( MarFile *  mar,
MarItemCallback  callback,
void data 
)

Enumerate all MAR items via callback function.

Parameters:
marThe MAR file to enumerate.
callbackThe function to call for each MAR item.
dataA caller specified value that is passed along to the callback function.
Returns:
Zero if the enumeration ran to completion. Otherwise, any non-zero return value from the callback is returned.

Definition at line 237 of file mar_read.c.

                                                                          {
  MarItem *item;
  int i;

  for (i = 0; i < TABLESIZE; ++i) {
    item = mar->item_table[i];
    while (item) {
      int rv = callback(mar, item, closure);
      if (rv)
        return rv;
      item = item->next;
    }
  }

  return 0;
}

Here is the caller graph for this function:

const MarItem* mar_find_item ( MarFile *  mar,
const char *  item 
)

Find an item in the MAR file by name.

Parameters:
marThe MarFile object to query.
itemThe name of the item to query.
Returns:
A const reference to a MAR item or NULL if not found.

Definition at line 224 of file mar_read.c.

                                                             {
  PRUint32 hash;
  const MarItem *item;

  hash = mar_hash_name(name);

  item = mar->item_table[hash];
  while (item && strcmp(item->name, name) != 0)
    item = item->next;

  return item;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRUint32 mar_hash_name ( const char *  name) [static]

Definition at line 61 of file mar_read.c.

                                                {
  PRUint32 val = 0;
  unsigned char* c;

  for (c = (unsigned char *) name; *c; ++c)
    val = val*37 + *c;

  return val % TABLESIZE;
}

Here is the caller graph for this function:

static int mar_insert_item ( MarFile *  mar,
const char *  name,
int  namelen,
PRUint32  offset,
PRUint32  length,
PRUint32  flags 
) [static]

Definition at line 71 of file mar_read.c.

                                                                             {
  MarItem *item, *root;
  PRUint32 hash;
  
  item = (MarItem *) malloc(sizeof(MarItem) + namelen);
  if (!item)
    return -1;
  item->next = NULL;
  item->offset = offset;
  item->length = length;
  item->flags = flags;
  memcpy(item->name, name, namelen + 1);

  hash = mar_hash_name(name);

  root = mar->item_table[hash];
  if (!root) {
    mar->item_table[hash] = item;
  } else {
    /* append item */
    while (root->next)
      root = root->next;
    root->next = item;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

MarFile* mar_open ( const char *  path)

Open a MAR file for reading.

Parameters:
pathSpecifies the path to the MAR file to open. This path must be compatible with fopen.
Returns:
NULL if an error occurs.

Definition at line 182 of file mar_read.c.

                                    {
  MarFile *mar;
  FILE *fp;

  fp = fopen(path, "rb");
  if (!fp)
    return NULL;

  mar = (MarFile *) malloc(sizeof(*mar));
  if (!mar) {
    fclose(fp);
    return NULL;
  }

  mar->fp = fp;
  memset(mar->item_table, 0, sizeof(mar->item_table));
  if (mar_read_index(mar)) {
    mar_close(mar);
    return NULL;
  }

  return mar;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mar_read ( MarFile *  mar,
const MarItem item,
int  offset,
char *  buf,
int  bufsize 
)

Read from MAR item at given offset up to bufsize bytes.

Parameters:
marThe MAR file to read.
itemThe MAR item to read.
offsetThe byte offset relative to the start of the item.
bufA pointer to a buffer to copy the data into.
bufsizeThe length of the buffer to copy the data into.
Returns:
The number of bytes written or a negative value if an error occurs.

Definition at line 254 of file mar_read.c.

                          {
  int nr;

  if (offset == (int) item->length)
    return 0;
  if (offset > (int) item->length)
    return -1;

  nr = item->length - offset;
  if (nr > bufsize)
    nr = bufsize;

  if (fseek(mar->fp, item->offset + offset, SEEK_SET))
    return -1;

  return fread(buf, 1, nr, mar->fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int mar_read_index ( MarFile *  mar) [static]

Definition at line 146 of file mar_read.c.

                                        {
  char id[MAR_ID_SIZE], *buf, *bufptr, *bufend;
  PRUint32 offset_to_index, size_of_index;

  /* verify MAR ID */
  if (fread(id, MAR_ID_SIZE, 1, mar->fp) != 1)
    return -1;
  if (memcmp(id, MAR_ID, MAR_ID_SIZE) != 0)
    return -1;

  if (fread(&offset_to_index, sizeof(PRUint32), 1, mar->fp) != 1)
    return -1;
  offset_to_index = ntohl(offset_to_index);

  if (fseek(mar->fp, offset_to_index, SEEK_SET))
    return -1;
  if (fread(&size_of_index, sizeof(PRUint32), 1, mar->fp) != 1)
    return -1;
  size_of_index = ntohl(size_of_index);

  buf = (char *) malloc(size_of_index);
  if (!buf)
    return -1;
  if (fread(buf, size_of_index, 1, mar->fp) != 1) {
    free(buf);
    return -1;
  }

  bufptr = buf;
  bufend = buf + size_of_index;
  while (bufptr < bufend && mar_consume_index(mar, &bufptr, bufend) == 0);

  free(buf);
  return (bufptr == bufend) ? 0 : -1;
}

Here is the call graph for this function:

Here is the caller graph for this function: