Files
harbour-core/harbour/external/libhpdf/hpdf_dict.c
Viktor Szakats c356496480 2009-03-29 11:02 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
* INSTALL
  * external/Makefile
  + external/libhpdf/*
  + external/libpng/*
    + Added libharu and libpng to Harbour repository.
      Now it's possible to use libhpdf as static lib on all
      platforms. This is useful because this lib isn't yet part
      of Linux distros.
      libpng is only built for win/dos/os2 platforms.
      It's possible to override libpng location by using
      HB_INC_LIBPNG envvar.

  * contrib/hbhpdf/Makefile
    + Look for libharu headers in /external dir.

  * external/sqlite3/Makefile
    - Disabled for bcc. Latest sqlite3 version breaks with this compiler:
      ---
      Error E2293 ../../sqlite3.c 29156: ) expected in function winCurrentTime
      Warning W8013 ../../sqlite3.c 29157: Possible use of 'timeW' before definition in function winCurrentTime
      Error E2379 ../../sqlite3.c 29157: Statement missing ; in function winCurrentTime
      Error E2379 ../../sqlite3.c 29158: Statement missing ; in function winCurrentTime
      Error E2379 ../../sqlite3.c 29160: Statement missing ; in function winCurrentTime
      Error E2293 ../../sqlite3.c 29161: ) expected in function winCurrentTime
      Error E2379 ../../sqlite3.c 29162: Statement missing ; in function winCurrentTime
      Error E2293 ../../sqlite3.c 29163: ) expected in function winCurrentTime
      Warning W8057 ../../sqlite3.c 29171: Parameter 'prNow' is never used in function winCurrentTime
      *** 7 errors in Compile ***
      ---
      bcc users can report this problem here:
      http://www.sqlite.org/cvstrac/tktnew

  + tests/bnch_win.bat
  - tests/bnchmark
    * Moved bnch_win.bat to tests.
2009-03-29 09:09:24 +00:00

492 lines
13 KiB
C

/*
* << Haru Free PDF Library >> -- hpdf_dict.c
*
* URL: http://libharu.org
*
* Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
* Copyright (c) 2007-2008 Antony Dovgal <tony@daylessday.org>
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
* It is provided "as is" without express or implied warranty.
*
*/
#include "hpdf_conf.h"
#include "hpdf_utils.h"
#include "hpdf_objects.h"
HPDF_DictElement
GetElement (HPDF_Dict dict,
const char *key);
/*--------------------------------------------------------------------------*/
HPDF_Dict
HPDF_Dict_New (HPDF_MMgr mmgr)
{
HPDF_Dict obj;
obj = (HPDF_Dict)HPDF_GetMem (mmgr, sizeof(HPDF_Dict_Rec));
if (obj) {
HPDF_MemSet (obj, 0, sizeof(HPDF_Dict_Rec));
obj->header.obj_class = HPDF_OCLASS_DICT;
obj->mmgr = mmgr;
obj->error = mmgr->error;
obj->list = HPDF_List_New (mmgr, HPDF_DEF_ITEMS_PER_BLOCK);
obj->filter = HPDF_STREAM_FILTER_NONE;
if (!obj->list) {
HPDF_FreeMem (mmgr, obj);
obj = NULL;
}
}
return obj;
}
HPDF_Dict
HPDF_DictStream_New (HPDF_MMgr mmgr,
HPDF_Xref xref)
{
HPDF_Dict obj;
HPDF_Number length;
HPDF_STATUS ret = 0;
obj = HPDF_Dict_New (mmgr);
if (!obj)
return NULL;
/* only stream object is added to xref automatically */
ret += HPDF_Xref_Add (xref, obj);
if (ret != HPDF_OK)
return NULL;
length = HPDF_Number_New (mmgr, 0);
if (!length)
return NULL;
ret = HPDF_Xref_Add (xref, length);
if (ret != HPDF_OK)
return NULL;
ret = HPDF_Dict_Add (obj, "Length", length);
if (ret != HPDF_OK)
return NULL;
obj->stream = HPDF_MemStream_New (mmgr, HPDF_STREAM_BUF_SIZ);
if (!obj->stream)
return NULL;
return obj;
}
void
HPDF_Dict_Free (HPDF_Dict dict)
{
HPDF_UINT i;
if (!dict)
return;
if (dict->free_fn)
dict->free_fn (dict);
for (i = 0; i < dict->list->count; i++) {
HPDF_DictElement element =
(HPDF_DictElement)HPDF_List_ItemAt (dict->list, i);
if (element) {
HPDF_Obj_Free (dict->mmgr, element->value);
HPDF_FreeMem (dict->mmgr, element);
}
}
if (dict->stream)
HPDF_Stream_Free (dict->stream);
HPDF_List_Free (dict->list);
dict->header.obj_class = 0;
HPDF_FreeMem (dict->mmgr, dict);
}
HPDF_STATUS
HPDF_Dict_Write (HPDF_Dict dict,
HPDF_Stream stream,
HPDF_Encrypt e)
{
HPDF_UINT i;
HPDF_STATUS ret;
ret = HPDF_Stream_WriteStr (stream, "<<\012");
if (ret != HPDF_OK)
return ret;
if (dict->before_write_fn) {
if ((ret = dict->before_write_fn (dict)) != HPDF_OK)
return ret;
}
/* encrypt-dict must not be encrypted. */
if (dict->header.obj_class == (HPDF_OCLASS_DICT | HPDF_OSUBCLASS_ENCRYPT))
e = NULL;
if (dict->stream) {
/* set filter element */
if (dict->filter == HPDF_STREAM_FILTER_NONE)
HPDF_Dict_RemoveElement (dict, "Filter");
else {
HPDF_Array array = HPDF_Dict_GetItem (dict, "Filter",
HPDF_OCLASS_ARRAY);
if (!array) {
array = HPDF_Array_New (dict->mmgr);
if (!array)
return HPDF_Error_GetCode (dict->error);
ret = HPDF_Dict_Add (dict, "Filter", array);
if (ret != HPDF_OK)
return ret;
}
HPDF_Array_Clear (array);
#ifndef HPDF_NOZLIB
if (dict->filter & HPDF_STREAM_FILTER_FLATE_DECODE)
HPDF_Array_AddName (array, "FlateDecode");
#endif /* HPDF_NOZLIB */
if (dict->filter & HPDF_STREAM_FILTER_DCT_DECODE)
HPDF_Array_AddName (array, "DCTDecode");
}
}
for (i = 0; i < dict->list->count; i++) {
HPDF_DictElement element =
(HPDF_DictElement)HPDF_List_ItemAt (dict->list, i);
HPDF_Obj_Header *header = (HPDF_Obj_Header *)(element->value);
if (!element->value)
return HPDF_SetError (dict->error, HPDF_INVALID_OBJECT, 0);
if (header->obj_id & HPDF_OTYPE_HIDDEN) {
HPDF_PTRACE((" HPDF_Dict_Write obj=%p skipped obj_id=0x%08X\n",
element->value, (HPDF_UINT)header->obj_id));
} else {
ret = HPDF_Stream_WriteEscapeName (stream, element->key);
if (ret != HPDF_OK)
return ret;
ret = HPDF_Stream_WriteChar (stream, ' ');
if (ret != HPDF_OK)
return ret;
ret = HPDF_Obj_Write (element->value, stream, e);
if (ret != HPDF_OK)
return ret;
ret = HPDF_Stream_WriteStr (stream, "\012");
if (ret != HPDF_OK)
return ret;
}
}
if (dict->write_fn) {
if ((ret = dict->write_fn (dict, stream)) != HPDF_OK)
return ret;
}
if ((ret = HPDF_Stream_WriteStr (stream, ">>")) != HPDF_OK)
return ret;
if (dict->stream) {
HPDF_UINT32 strptr;
HPDF_Number length;
/* get "length" element */
length = (HPDF_Number)HPDF_Dict_GetItem (dict, "Length",
HPDF_OCLASS_NUMBER);
if (!length)
return HPDF_SetError (dict->error,
HPDF_DICT_STREAM_LENGTH_NOT_FOUND, 0);
/* "length" element must be indirect-object */
if (!(length->header.obj_id & HPDF_OTYPE_INDIRECT)) {
return HPDF_SetError (dict->error, HPDF_DICT_ITEM_UNEXPECTED_TYPE,
0);
}
if ((ret = HPDF_Stream_WriteStr (stream, "\012stream\015\012"))
!= HPDF_OK)
return ret;
strptr = stream->size;
if (e)
HPDF_Encrypt_Reset (e);
if ((ret = HPDF_Stream_WriteToStream (dict->stream, stream,
dict->filter, e)) != HPDF_OK)
return ret;
HPDF_Number_SetValue (length, stream->size - strptr);
ret = HPDF_Stream_WriteStr (stream, "\012endstream");
}
/* 2006.08.13 add. */
if (dict->after_write_fn) {
if ((ret = dict->after_write_fn (dict)) != HPDF_OK)
return ret;
}
return ret;
}
HPDF_STATUS
HPDF_Dict_Add (HPDF_Dict dict,
const char *key,
void *obj)
{
HPDF_Obj_Header *header;
HPDF_STATUS ret = HPDF_OK;
HPDF_DictElement element;
if (!obj) {
if (HPDF_Error_GetCode (dict->error) == HPDF_OK)
return HPDF_SetError (dict->error, HPDF_INVALID_OBJECT, 0);
else
return HPDF_INVALID_OBJECT;
}
header = (HPDF_Obj_Header *)obj;
if (header->obj_id & HPDF_OTYPE_DIRECT)
return HPDF_SetError (dict->error, HPDF_INVALID_OBJECT, 0);
if (!key) {
HPDF_Obj_Free (dict->mmgr, obj);
return HPDF_SetError (dict->error, HPDF_INVALID_OBJECT, 0);
}
if (dict->list->count >= HPDF_LIMIT_MAX_DICT_ELEMENT) {
HPDF_PTRACE((" HPDF_Dict_Add exceed limitatin of dict count(%d)\n",
HPDF_LIMIT_MAX_DICT_ELEMENT));
HPDF_Obj_Free (dict->mmgr, obj);
return HPDF_SetError (dict->error, HPDF_DICT_COUNT_ERR, 0);
}
/* check whether there is an object which has same name */
element = GetElement (dict, key);
if (element) {
HPDF_Obj_Free (dict->mmgr, element->value);
element->value = NULL;
} else {
element = (HPDF_DictElement)HPDF_GetMem (dict->mmgr,
sizeof(HPDF_DictElement_Rec));
if (!element) {
/* cannot create element object */
if (!(header->obj_id & HPDF_OTYPE_INDIRECT))
HPDF_Obj_Free (dict->mmgr, obj);
return HPDF_Error_GetCode (dict->error);
}
HPDF_StrCpy (element->key, key, element->key +
HPDF_LIMIT_MAX_NAME_LEN + 1);
element->value = NULL;
ret = HPDF_List_Add (dict->list, element);
if (ret != HPDF_OK) {
if (!(header->obj_id & HPDF_OTYPE_INDIRECT))
HPDF_Obj_Free (dict->mmgr, obj);
HPDF_FreeMem (dict->mmgr, element);
return HPDF_Error_GetCode (dict->error);
}
}
if (header->obj_id & HPDF_OTYPE_INDIRECT) {
HPDF_Proxy proxy = HPDF_Proxy_New (dict->mmgr, obj);
if (!proxy)
return HPDF_Error_GetCode (dict->error);
element->value = proxy;
proxy->header.obj_id |= HPDF_OTYPE_DIRECT;
} else {
element->value = obj;
header->obj_id |= HPDF_OTYPE_DIRECT;
}
return ret;
}
HPDF_STATUS
HPDF_Dict_AddName (HPDF_Dict dict,
const char *key,
const char *value)
{
HPDF_Name name = HPDF_Name_New (dict->mmgr, value);
if (!name)
return HPDF_Error_GetCode (dict->error);
return HPDF_Dict_Add (dict, key, name);
}
HPDF_STATUS
HPDF_Dict_AddNumber (HPDF_Dict dict,
const char *key,
HPDF_INT32 value)
{
HPDF_Number number = HPDF_Number_New (dict->mmgr, value);
if (!number)
return HPDF_Error_GetCode (dict->error);
return HPDF_Dict_Add (dict, key, number);
}
HPDF_STATUS
HPDF_Dict_AddReal (HPDF_Dict dict,
const char *key,
HPDF_REAL value)
{
HPDF_Real real = HPDF_Real_New (dict->mmgr, value);
if (!real)
return HPDF_Error_GetCode (dict->error);
return HPDF_Dict_Add (dict, key, real);
}
HPDF_STATUS
HPDF_Dict_AddBoolean (HPDF_Dict dict,
const char *key,
HPDF_BOOL value)
{
HPDF_Boolean obj = HPDF_Boolean_New (dict->mmgr, value);
if (!obj)
return HPDF_Error_GetCode (dict->error);
return HPDF_Dict_Add (dict, key, obj);
}
void*
HPDF_Dict_GetItem (HPDF_Dict dict,
const char *key,
HPDF_UINT16 obj_class)
{
HPDF_DictElement element = GetElement (dict, key);
void *obj;
if (element && HPDF_StrCmp(key, element->key) == 0) {
HPDF_Obj_Header *header = (HPDF_Obj_Header *)element->value;
if (header->obj_class == HPDF_OCLASS_PROXY) {
HPDF_Proxy p = element->value;
header = (HPDF_Obj_Header *)p->obj;
obj = p->obj;
} else
obj = element->value;
if ((header->obj_class & HPDF_OCLASS_ANY) != obj_class) {
HPDF_PTRACE((" HPDF_Dict_GetItem dict=%p key=%s obj_class=0x%08X\n",
dict, key, (HPDF_UINT)header->obj_class));
HPDF_SetError (dict->error, HPDF_DICT_ITEM_UNEXPECTED_TYPE, 0);
return NULL;
}
return obj;
}
return NULL;
}
HPDF_DictElement
GetElement (HPDF_Dict dict,
const char *key)
{
HPDF_UINT i;
for (i = 0; i < dict->list->count; i++) {
HPDF_DictElement element =
(HPDF_DictElement)HPDF_List_ItemAt (dict->list, i);
if (HPDF_StrCmp (key, element->key) == 0)
return element;
}
return NULL;
}
HPDF_STATUS
HPDF_Dict_RemoveElement (HPDF_Dict dict,
const char *key)
{
HPDF_UINT i;
for (i = 0; i < dict->list->count; i++) {
HPDF_DictElement element =
(HPDF_DictElement)HPDF_List_ItemAt (dict->list, i);
if (HPDF_StrCmp (key, element->key) == 0) {
HPDF_List_Remove (dict->list, element);
HPDF_Obj_Free (dict->mmgr, element->value);
HPDF_FreeMem (dict->mmgr, element);
return HPDF_OK;
}
}
return HPDF_DICT_ITEM_NOT_FOUND;
}
const char*
HPDF_Dict_GetKeyByObj (HPDF_Dict dict,
void *obj)
{
HPDF_UINT i;
for (i = 0; i < dict->list->count; i++) {
HPDF_Obj_Header *header;
HPDF_DictElement element =
(HPDF_DictElement)HPDF_List_ItemAt (dict->list, i);
header = (HPDF_Obj_Header *)(element->value);
if (header->obj_class == HPDF_OCLASS_PROXY) {
HPDF_Proxy p = element->value;
if (p->obj == obj)
return element->key;
} else {
if (element->value == obj)
return element->key;
}
}
return NULL;
}