All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hcl.domino.jna.internal.ItemDecoder Maven / Gradle / Ivy

/*
 * ==========================================================================
 * Copyright (C) 2019-2022 HCL America, Inc. ( http://www.hcl.com/ )
 *                            All rights reserved.
 * ==========================================================================
 * Licensed under the  Apache License, Version 2.0  (the "License").  You may
 * not use this file except in compliance with the License.  You may obtain a
 * copy of the License at .
 *
 * Unless  required  by applicable  law or  agreed  to  in writing,  software
 * distributed under the License is distributed on an  "AS IS" BASIS, WITHOUT
 * WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the  specific language  governing permissions  and limitations
 * under the License.
 * ==========================================================================
 */
package com.hcl.domino.jna.internal;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;

import com.hcl.domino.commons.data.DefaultDominoDateRange;
import com.hcl.domino.commons.richtext.RichTextUtil;
import com.hcl.domino.commons.util.NotesDateTimeUtils;
import com.hcl.domino.commons.util.NotesErrorUtils;
import com.hcl.domino.data.DominoDateTime;
import com.hcl.domino.data.ItemDataType;
import com.hcl.domino.jna.data.JNADominoDateTime;
import com.hcl.domino.jna.internal.capi.NotesCAPI;
import com.hcl.domino.jna.internal.structs.NotesNumberPairStruct;
import com.hcl.domino.jna.internal.structs.NotesRangeStruct;
import com.hcl.domino.jna.internal.structs.NotesTimeDatePairStruct;
import com.hcl.domino.jna.internal.structs.NotesTimeDateStruct;
import com.hcl.domino.misc.DominoEnumUtil;
import com.hcl.domino.richtext.records.RecordType;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.ShortByReference;

public class ItemDecoder {

	public static double decodeNumber(Pointer ptr, int valueLength) {
		double numVal = ptr.getDouble(0);
		return numVal;
	}
	
	public static Object decodeTextValue(Pointer ptr, int valueLength, boolean convertStringsLazily) {
		if (valueLength<=0) {
			return ""; //$NON-NLS-1$
		}
		
		if (convertStringsLazily) {
			byte[] stringDataArr = new byte[valueLength];
			ptr.read(0, stringDataArr, 0, valueLength);

			LMBCSString lmbcsString = new LMBCSString(stringDataArr);
			return lmbcsString;
		}
		else {
			String txtVal = NotesStringUtils.fromLMBCS(ptr, valueLength);
			return txtVal;
		}
	}
	
	public static List decodeTextListValue(Pointer ptr, boolean convertStringsLazily) {
		//read a text list item value
		int listCountAsInt = ptr.getShort(0) & 0xffff;
		
		List listValues = new ArrayList<>(listCountAsInt);
		
		try(DisposableMemory retTextPointer = new DisposableMemory(Native.POINTER_SIZE)) {
    		ShortByReference retTextLength = new ShortByReference();
    		
    		for (int i=0; i decodeNumberList(Pointer ptr, int valueLength) {
		NotesRangeStruct range = NotesRangeStruct.newInstance(ptr);
		range.read();
		
		//read number of list and range entries in range
		int listEntriesAsInt = range.ListEntries & 0xffff;
		int rangeEntriesAsInt = range.RangeEntries & 0xffff;
		
		//skip range header
		Pointer ptrAfterRange = ptr.share(JNANotesConstants.rangeSize);
		
		//we create an object list, because number ranges contain double[] array
		//(not sure whether number ranges exist in real life)
		List numberValues = new ArrayList<>(listEntriesAsInt + rangeEntriesAsInt);
		for (int t=0; t decodeTimeDateListAsNotesTimeDate(Pointer ptr) {
		NotesRangeStruct range = NotesRangeStruct.newInstance(ptr);
		range.read();
		
		//read number of list and range entries in range
		int listEntriesAsInt = range.ListEntries & 0xffff;
		int rangeEntriesAsInt = range.RangeEntries & 0xffff;
		
		//skip range header
		Pointer ptrAfterRange = ptr.share(JNANotesConstants.rangeSize);
		
		List calendarValues = new ArrayList<>(listEntriesAsInt + rangeEntriesAsInt);
		
		for (int t=0; t decodeTimeDateList(Pointer ptr) {
		NotesRangeStruct range = NotesRangeStruct.newInstance(ptr);
		range.read();
		
		//read number of list and range entries in range
		int listEntriesAsInt = range.ListEntries & 0xffff;
		int rangeEntriesAsInt = range.RangeEntries & 0xffff;
		
		//skip range header
		Pointer ptrAfterRange = ptr.share(JNANotesConstants.rangeSize);
		
		List calendarValues = new ArrayList<>(listEntriesAsInt + rangeEntriesAsInt);
		
		for (int t=0; t new IllegalArgumentException(MessageFormat.format("Unsupported data type: {0}", typeVal)));
		
		switch(type) {
		case TYPE_TEXT:
			return decodeTextValue(ptr, length, false);
		case TYPE_TEXT_LIST:
			return length==0 ? Collections.emptyList() : decodeTextListValue(ptr, false);
		case TYPE_NUMBER:
			return decodeNumber(ptr, length);
		case TYPE_TIME:
			return decodeTimeDateAsNotesTimeDate(ptr, length);
		case TYPE_NUMBER_RANGE:
			return decodeNumberList(ptr, length);
		case TYPE_TIME_RANGE:
			return decodeTimeDateListAsNotesTimeDate(ptr);
		case TYPE_COMPOSITE:
		  // Add back space for the type val skipped below
		  byte[] data = new byte[length+2];
		  ptr.read(0, data, 2, length);
		  return RichTextUtil.readMemoryRecords(data, area);
		default:
			throw new IllegalArgumentException(MessageFormat.format("Unsupported data type: {0}", type));
		}
	}
	
}