Beispiel #1
0
static int
seekChars(void* state, long offset, int whence) {
    long absPos;
    char* pszError;

    switch (whence) {
    case SEEK_SET:
        absPos = offset;
        storagePosition(&pszError, (int)state, absPos);
        break;

    case SEEK_END:
        absPos = sizeOfFile(state) + offset;
        storagePosition(&pszError, (int)state, absPos);
        break;

    case SEEK_CUR:
        absPos = storageRelativePosition(&pszError, (int)state, offset);
        break;

    default:
        return -1;
    }

    storageFreeError(pszError);
    return absPos;
}
/**
 * Store content handler information into a registry.
 *
 * @param handler description of a registering handler. Implementation MUST NOT 
 * retain pointed object
 * @return JSR211_OK if content handler registered successfully
 */
jsr211_result jsr211_register_handler(const JSR211_content_handler* handler) {
  long current_position;
  unsigned int record_size = sizeof(int);

  if (open_table_file(1) != JSR211_OK) {
    return JSR211_FAILED;
  }
  storagePosition(&io_error_message, table_file, 
                                storageSizeOf(&io_error_message, table_file));
  current_position = storageRelativePosition(&io_error_message, table_file, 0);
  storageWrite(&io_error_message, table_file, (char *)&record_size, 
                        sizeof(record_size)); /* Placeholder for record size */

  record_size += write_string(&(handler->id));
  record_size += write_int(handler->flag);
  record_size += write_int(handler->suite_id);
  record_size += write_string(&(handler->class_name));
  record_size += write_string_array(handler->type_num, handler->types);
  record_size += write_string_array(handler->suff_num, handler->suffixes);
  record_size += write_string_array(handler->act_num, handler->actions);
  record_size += write_string_array(handler->locale_num, handler->locales);
  record_size += write_string_array(handler->locale_num * handler->act_num, 
                                                           handler->action_map);
  record_size += write_string_array(handler->access_num, handler->accesses);

  storagePosition(&io_error_message, table_file, current_position);
  storageWrite(&io_error_message, table_file, (char *)&record_size, 
                                                           sizeof(record_size));
  storageRelativePosition(&io_error_message, table_file, record_size - 
                                                                   sizeof(int));
  
  close_table_file();
  return JSR211_OK;
}
/**
 * Searches the next content handler in the file by its suite id.
 *
 * @param suite search suite ID
 * @return offset of found record or -1
 */
static long find_next_by_suite(int suite) {
  long current_position;
  int record_size;
  int testSuite;
  int found = 0;

  current_position = storageRelativePosition(&io_error_message, table_file, 0);
  do {
    record_size = position_field(JSR211_CHR_SUITE);
    if (record_size <= 0) {
      current_position = -1;
      break;
    }

    storageRead(&io_error_message, table_file, (char*)&testSuite, sizeof(int));
    found = (testSuite == suite? 1: 0);
    storagePosition(&io_error_message, table_file, current_position);
    if (found) {
      break;
    }
    current_position = storageRelativePosition(&io_error_message, table_file, 
                                    record_size);
  } while (current_position > 0);

  return current_position;
}
/**
 * Loads current handler's main fields (ID, suite_ID, class_name, flag).
 * @param handler loaded structure pointer.
 * @return operation result
 */
static void load_current_handler(JSR211_CH* ch) {
    long pos = storageRelativePosition(&io_error_message, table_file, 
                                       sizeof(int)) - sizeof(int);
    read_string(&(ch->id));
    storageRead(&io_error_message, table_file, (char*)&(ch->flag), sizeof(int));
    storageRead(&io_error_message, table_file, (char*)&(ch->suite_id), sizeof(int));
    read_string(&(ch->class_name));
    storagePosition(&io_error_message, table_file, pos);
}
Beispiel #5
0
/* Directly write to storage. File position will be updated also. */
static
void uncachedWrite(char** ppszError, int handle, char *buffer, int length) {
    *ppszError = NULL;
    storagePosition(ppszError, handle, mFileCache->cachedPosition);
    if (*ppszError == NULL) {
        storageWrite(ppszError, handle, buffer, length);
        if (*ppszError == NULL) {
            updateCachedSizes(length);
        }
    }
}
Beispiel #6
0
/**
 * Flush the cache and stop current file caching.
 * Seek cached position for the case the file won't be closed after
 * flushing (it's possible if a few files are openned simultaneously).
 */
static void midp_file_cache_finalize(char **ppszError, int stayOpen) {
    *ppszError = NULL;

    if (mFileCache != NULL) {
        midp_file_cache_flush(ppszError, mFileCache->handle);
        /* Do no seek for the file that is either damaged or to be closed */
        if (*ppszError == NULL && stayOpen) {
            storagePosition(ppszError, mFileCache->handle,
                            mFileCache->cachedPosition);
        }
        /* If read is cached, free all read blocks here */
        midpFree(mFileCache);
        mFileCache = NULL;
    }
}
/**
 * Searches the next content handler in the file by specified conditions.
 *
 * @param caller_id caller ID
 * @param number number of key field
 * @param key search key
 * @param case_sensitive case sensivity flag
 * @param cond comparision mode
 * @return offset of found record or -1
 */
static long find_next_by_field(const pcsl_string* caller_id, 
                        jsr211_field number, const pcsl_string* key, 
                        jsr211_boolean case_sensitive, find_condition cond) {
  long current_position;
  int    current_size, access;
  int    found = 0;
  int chr = CHR_INDEX((int)(number));  // Content Handler Record index
  int isString;

  switch (record_struct[chr]) {
    case field_string:
      isString = 1;
      break;
    case field_array:
      isString = 0;
      break;
    default:
      return -1;
  }

  current_position = storageRelativePosition(&io_error_message, table_file, 0);
  for (;;) {
    /* check access */
    access = check_access(caller_id, current_position, &current_size);
    if (access == -1) {
      return -1;
    }
    else if (access) {
      position_field(chr);
      found = (isString? 
                    compare_string(key, case_sensitive, cond):
                    compare_array(key, case_sensitive, cond));
    }

    storagePosition(&io_error_message, table_file, current_position);
    if (found) {
      break;
    }
    current_position += current_size;
    goto_next_record();
  }

  return current_position;
}
/**
 * Deletes content handler information from a registry.
 *
 * @param handler_id content handler ID
 * @return JSR211_OK if content handler unregistered successfully
 */
jsr211_result jsr211_unregister_handler(const pcsl_string* handler_id) {
  long current_position, file_size, buffer_size;
  int record_size;
  char *buffer;

  if (open_table_file(1) != JSR211_OK) {
    return JSR211_FAILED;
  }
  if (find_next_by_field(NULL, JSR211_FIELD_ID, handler_id, JSR211_TRUE,
                                                            find_exact) == -1) {
    close_table_file();
    return JSR211_FAILED;
  }
  
  storageRead(&io_error_message, table_file, (char *)&record_size, sizeof(int));
  current_position = storageRelativePosition(&io_error_message, table_file, 
                                                            -(long)sizeof(int));
  file_size = storageSizeOf(&io_error_message, table_file);
  goto_next_record();
  
  if (!(buffer = JSR211_MALLOC((buffer_size = file_size - current_position - 
                                                            record_size)))) {
    close_table_file();
    return JSR211_FAILED;
  }
  
  storageRead(&io_error_message, table_file, buffer, buffer_size);
  storagePosition(&io_error_message, table_file, current_position);
  storageWrite(&io_error_message, table_file, buffer, buffer_size);
  JSR211_FREE(buffer);
  storageTruncate(&io_error_message, table_file, current_position + 
                                                                   buffer_size);
  
  close_table_file();
  return JSR211_OK;
}
/**
 * Verifies access of caller for current content handler.
 * Reads access restrictions from a current record and
 * compares it with a passed caller_id.
 *
 * @param caller_id caller
 * @param current_position current position of the file
 * @param current_size [out] size of current record
 * @return 1 if access is permitted
 */
static int check_access(const pcsl_string* caller_id, long current_position, 
                                                            int* current_size) {
  int    access_len, access_ok;

  if ((*current_size = position_field(JSR211_CHR_ACCESSES)) <= 0) {
    return -1;
  }
  if (caller_id != NULL && pcsl_string_length(caller_id) > 0) {
    storageRelativePosition(&io_error_message, table_file, sizeof(int));
    storageRead(&io_error_message, table_file, (char*)&access_len, sizeof(int));
    if (!access_len) {
      access_ok = 1;
    }
    else {
      storageRelativePosition(&io_error_message, table_file, -2 * (long)sizeof(int));
      access_ok = compare_array(caller_id, JSR211_TRUE, find_first);
    }
  }
  else {
    access_ok = 1;
  }
  storagePosition(&io_error_message, table_file, current_position);
  return access_ok;
}
Beispiel #10
0
/**
 * Writes string array to the file.
 *
 * @param array_len length of array to be written
 * @param array array to be written
 * @return number of bytes written
 */
static int write_string_array(int array_len, const pcsl_string* array) {
  long current_pos;
  int write_count;
  const pcsl_string *current_string, *end;

  current_pos = storageRelativePosition(&io_error_message, table_file, 0);
  /* array size placeholder */
  storageWrite(&io_error_message, table_file, (char*)&write_count, sizeof(int));

  /* array size saving */
  storageWrite(&io_error_message, table_file, (char *)&array_len, sizeof(int));
  write_count = sizeof(int);

  for (current_string = array, end = array + array_len;
       current_string < end;
       current_string ++) {
    write_count += write_string(current_string);
  }
  storagePosition(&io_error_message, table_file, current_pos);
  storageWrite(&io_error_message, table_file, (char*)&write_count, sizeof(int));
  storageRelativePosition(&io_error_message, table_file, write_count);

  return write_count + sizeof(int);
}
Beispiel #11
0
/** A helper function for midp_file_cache_flush(). */
static
void midp_file_cache_flush_using_buffer(char** ppszError, int handle,
                                        char* buf, long bufsize) {
    MidpFileCacheBlock *b; /* current cache block */
    MidpFileCacheBlock *n; /* next cache block */
    MidpFileCacheBlock *q; /* first block not (yet) copied to the buffer,
                              finally, the value to be stored
                              in mFileCache->blocks */
    char *bufPos;          /* first not yet used byte in the write buffer */
    long startPos, endPos; /* positions in the file cached in a series
                              of buffers, from...upto */
    long len;
    *ppszError = NULL;

    while ((b = mFileCache->blocks) != NULL) {

        if (  NULL != buf
                && NULL != (n = b->next)
                && n->position == b->position + b->length /* adjacent? */
                && b->length + n->length < bufsize
           ) {  /* begin merging blocks */

            /* position in the buffer */
            bufPos = buf;
            /* position in the file */
            startPos = endPos = b->position;

            b = mFileCache->blocks;
            /* now copy a series of adjacent blocks to the write buffer */
            do {
                len = b->length;
                memcpy(bufPos,DATA(b),len);
                endPos += len;
                bufPos += len;
                b = b->next;
            } while (  NULL != b
                       && b->position == endPos
                       && endPos - startPos + b->length < bufsize
                    );

            q = b; /* q is next to the last copied block */
            /* the cache state has not been modified yet */

            /* now write from the write buffer */
            storagePosition(ppszError, handle, startPos);
            CHECK_ERROR(*ppszError);
            storageWrite(ppszError, handle, buf, endPos-startPos);
            CHECK_ERROR(*ppszError);

            /* write successful, now free the cache blocks */
            while ( q != (b = mFileCache->blocks)) {
                mFileCache->size -= b->length + sizeof(MidpFileCacheBlock);
                mFileCache->blocks = b->next;
                midpFree(b);
            }
        } else {
            storagePosition(ppszError, handle, b->position);
            CHECK_ERROR(*ppszError);
            storageWrite(ppszError, handle, DATA(b), b->length);
            CHECK_ERROR(*ppszError);

            mFileCache->size -= b->length + sizeof(MidpFileCacheBlock);
            mFileCache->blocks = b->next;
            midpFree(b);
        }
    }
    storageCommitWrite(ppszError, handle);
    CHECK_ERROR(*ppszError);

    /* ASSERT (mFileCache->size == 0) */
    if (mFileCache->size != 0) {
        REPORT_ERROR(LC_RMS, "File cache out of sync");
    }
}
Beispiel #12
0
/**
 * Returns all found values for specified field. Tha allowed fields are: <ul>
 *    <li> JSR211_FIELD_ID, <li> JSR211_FIELD_TYPES, <li> JSR211_FIELD_SUFFIXES,
 *    <li> and JSR211_FIELD_ACTIONS. </ul>
 * Values should be selected only from handlers accessible for given caller_id.
 *
 * @param caller_id calling application identifier.
 * @param field search field id
 * @param result output structure where result is placed to.
 *  <br>Use @link jsr211_fillStringArray function to fill this structure.
 * @return status of the operation
 */
jsr211_result jsr211_get_all(const pcsl_string* caller_id, jsr211_field field,
                        /*OUT*/ JSR211_RESULT_STRARRAY* result) {
  long current_position;
  int found_num, access, current_size;
  pcsl_string *res_buffer = NULL;
  pcsl_string *current_result, *last;
  int chr = CHR_INDEX((int)(field));
  int isString;

  switch (record_struct[chr]) {
    case field_string:
      isString = 1;
      break;
    case field_array:
      isString = 0;
      break;
    default:
      return JSR211_FAILED;
  }

  if (open_table_file(0) != JSR211_OK) {
    return JSR211_FAILED;
  }
  res_buffer = alloc_pcsl_string_list(JSR211_MAX_RESULT_SET);
  if (res_buffer == NULL) {
    close_table_file();
    return JSR211_FAILED;
  }

  current_position = 0;
  for (current_result = res_buffer, last = res_buffer + JSR211_MAX_RESULT_SET;
       current_result < last;) {
    
    access = check_access(caller_id, current_position, &current_size);
    if (access == -1) {
      break;
    }
    
    if (access && position_field(chr) > 0) {
      if (isString) {
        read_string(current_result);
        if (!findStringInArray(res_buffer, current_result - res_buffer, 
                                                            current_result)) {
          current_result++;
        }
      }
      else {
        pcsl_string *array_res = NULL, *results, *last_res;
        int array_length = 0;

        read_string_array(&array_length, &array_res);
        if (array_length > 0) {
            for (results = array_res, last_res = array_res + array_length;
                 results < last_res && current_result < last;
                 results++) {
              if (!findStringInArray(res_buffer, current_result - res_buffer, 
                                                                    results)) {
                *(current_result++) = *results;
                *results = PCSL_STRING_NULL;
              }
            }
            free_pcsl_string_list(array_res, array_length);
        }
      }
    }
    
    storagePosition(&io_error_message, table_file, current_position);
    current_position += current_size;
    goto_next_record();
  }
  
  if ((found_num = (int)(current_result - res_buffer))) {
    jsr211_fillStringArray(res_buffer, found_num, result);
  }

  free_pcsl_string_list(res_buffer, JSR211_MAX_RESULT_SET);
  close_table_file();
  return JSR211_OK;
}