Beispiel #1
0
/*
 * ole_ptr should point to the original blob value of the field.
 * If omited, there will be no multi-page check to that the caller is
 * responsible for not calling this function. Then, it doesn't have to
 * preserve the original value.
 */
size_t 
mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr)
{
	guint32 ole_len;
	void *buf;
	int row_start;
	size_t len;

    if (ole_ptr) {
	    ole_len = mdb_get_int32(ole_ptr, 0);
	    mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %02x",
	    	ole_len & 0x00ffffff, ole_len >> 24);

	    if ((ole_len & 0x80000000)
	     || (ole_len & 0x40000000))
	    	/* inline or single-page fields don't have a next */
	    	return 0;
	}
	mdb_debug(MDB_DEBUG_OLE, "pg_row %d", col->cur_blob_pg_row);
	if (!col->cur_blob_pg_row)
		return 0; /* we are done */
	if (mdb_find_pg_row(mdb, col->cur_blob_pg_row,
		&buf, &row_start, &len)) {
		return 0;
	}
	mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);

	if (col->bind_ptr)
		memcpy(col->bind_ptr, buf + row_start + 4, len - 4);
	col->cur_blob_pg_row = mdb_get_int32(buf, row_start);

	return len - 4;
}
Beispiel #2
0
static MdbProperties *
mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
{
	guint32 record_len, name_len;
	int pos = 0;
	int elem, dtype, dsize;
	gchar *name, *value;
	MdbProperties *props;
	int i=0;

#if MDB_DEBUG
	mdb_buffer_dump(kkd, 0, len);
#endif
	pos = 0;

	record_len = mdb_get_int16(kkd, pos);
	pos += 4;
	name_len = mdb_get_int16(kkd, pos);
	pos += 2;
	props = mdb_alloc_props();
	if (name_len) {
		props->name = g_malloc(3*name_len + 1);
		mdb_unicode2ascii(mdb, kkd+pos, name_len, props->name, 3*name_len);
		mdb_debug(MDB_DEBUG_PROPS,"prop block named: %s", props->name);
	}
	pos += name_len;

	props->hash = g_hash_table_new(g_str_hash, g_str_equal);

	while (pos < len) {
		record_len = mdb_get_int16(kkd, pos);
		dtype = kkd[pos + 3];
		elem = mdb_get_int16(kkd, pos + 4);
		dsize = mdb_get_int16(kkd, pos + 6);
		value = g_malloc(dsize + 1);
		strncpy(value, &kkd[pos + 8], dsize);
		value[dsize] = '\0';
		name = g_ptr_array_index(names,elem);
		if (mdb_get_option(MDB_DEBUG_PROPS)) {
			fprintf(stderr, "%02d ",i++);
			mdb_debug(MDB_DEBUG_PROPS,"elem %d (%s) dsize %d dtype %d", elem, name, dsize, dtype);
			mdb_buffer_dump(value, 0, dsize);
		}
		if (dtype == MDB_MEMO) dtype = MDB_TEXT;
		if (dtype == MDB_BOOL) {
			g_hash_table_insert(props->hash, g_strdup(name),
				g_strdup(kkd[pos + 8] ? "yes" : "no"));
		} else {
			g_hash_table_insert(props->hash, g_strdup(name),
			  mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize));
		}
		g_free(value);
		pos += record_len;
	}
	return props;
	
}
Beispiel #3
0
/*
 * That function takes a raw KKD/MR2 binary buffer,
 * typically read from LvProp in table MSysbjects
 * and returns a GPtrArray of MdbProps*
 */
GArray*
mdb_kkd_to_props(MdbHandle *mdb, void *buffer, size_t len) {
	guint32 record_len;
	guint16 record_type;
	size_t pos;
	GPtrArray *names = NULL;
	MdbProperties *props;
	GArray *result;

#if MDB_DEBUG
	mdb_buffer_dump(buffer, 0, len);
#endif
	mdb_debug(MDB_DEBUG_PROPS,"starting prop parsing of type %s", buffer);

	if (strcmp("KKD", buffer) && strcmp("MR2", buffer)) {
		fprintf(stderr, "Unrecognized format.\n");
		mdb_buffer_dump(buffer, 0, len);
		return NULL;
	}

	result = g_array_new(0, 0, sizeof(MdbProperties*));

	pos = 4;
	while (pos < len) {
		record_len = mdb_get_int32(buffer, pos);
		record_type = mdb_get_int16(buffer, pos + 4);
		mdb_debug(MDB_DEBUG_PROPS,"prop chunk type:0x%04x len:%d", record_type, record_len);
		//mdb_buffer_dump(buffer, pos+4, record_len);
		switch (record_type) {
			case 0x80:
				if (names) free_names(names);
				names = mdb_read_props_list(mdb, buffer+pos+6, record_len - 6);
				break;
			case 0x00:
			case 0x01:
				if (!names) {
					fprintf(stderr,"sequence error!\n");
					break;
				}
				props = mdb_read_props(mdb, names, buffer+pos+6, record_len - 6);
				g_array_append_val(result, props);
				//mdb_dump_props(props, stderr, 1);
				break;
			default:
				fprintf(stderr,"Unknown record type %d\n", record_type);
				break;
		}
		pos += record_len;
	}
	if (names) free_names(names);
	return result;
}
Beispiel #4
0
/**
 * mdb_like_cmp
 * @s: String to search within.
 * @r: Search pattern.
 *
 * Tests the string @s to see if it matches the search pattern @r.  In the
 * search pattern, a percent sign indicates matching on any number of
 * characters, and an underscore indicates matching any single character.
 *
 * Returns: 1 if the string matches, 0 if the string does not match.
 */
int mdb_like_cmp(char *s, char *r)
{
	unsigned int i;
	int ret;

	mdb_debug(MDB_DEBUG_LIKE, "comparing %s and %s", s, r);
	switch (r[0]) {
		case '\0':
			if (s[0]=='\0') {
				return 1;
			} else {
				return 0;
			}
		case '_':
			/* skip one character */
			return mdb_like_cmp(&s[1],&r[1]);
		case '%':
			/* skip any number of characters */
			/* the strlen(s)+1 is important so the next call can */
			/* if there are trailing characters */
			for(i=0;i<strlen(s)+1;i++) {
				if (mdb_like_cmp(&s[i],&r[1])) {
					return 1;
				}
			}
			return 0;
		default:
			for(i=0;i<strlen(r);i++) {
				if (r[i]=='_' || r[i]=='%') break;
			}
			if (strncmp(s,r,i)) {
				return 0;
			} else {
				mdb_debug(MDB_DEBUG_LIKE, "at pos %d comparing %s and %s", i, &s[i], &r[i]);
				ret = mdb_like_cmp(&s[i],&r[i]);
				mdb_debug(MDB_DEBUG_LIKE, "returning %d (%s and %s)", ret, &s[i], &r[i]);
				return ret;
			}
	}
}
Beispiel #5
0
size_t 
mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size)
{
	guint32 ole_len;
	void *buf;
	int row_start;
	size_t len;

	ole_len = mdb_get_int32(ole_ptr, 0);
	mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %02x",
		ole_len & 0x00ffffff, ole_len >> 24);

	col->chunk_size = chunk_size;

	if (ole_len & 0x80000000) {
		/* inline ole field, if we can satisfy it, then do it */
		len = col->cur_value_len - MDB_MEMO_OVERHEAD;
		if ((size_t)chunk_size >= len) {
			if (col->bind_ptr) 
				memcpy(col->bind_ptr, 
					&mdb->pg_buf[col->cur_value_start + 
						MDB_MEMO_OVERHEAD],
					len);
			return len;
		} else {
			return 0;
		}
	} else if (ole_len & 0x40000000) {
		col->cur_blob_pg_row = mdb_get_int32(ole_ptr, 4);
		mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld",
			col->cur_blob_pg_row & 0xff,
			col->cur_blob_pg_row >> 8);

		if (mdb_find_pg_row(mdb, col->cur_blob_pg_row,
			&buf, &row_start, &len)) {
			return 0;
		}
		mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);

		if (col->bind_ptr) {
			memcpy(col->bind_ptr, (char*)buf + row_start, len);
			if (mdb_get_option(MDB_DEBUG_OLE))
				buffer_dump(col->bind_ptr, 0, 16);
		}
		return len;
	} else if ((ole_len & 0xff000000) == 0) {