unit ABSTypesRoutines;

{$I ABSVer.inc}

interface

uses
     {$IFDEF DEBUG_LOG}
     ABSDebug,
     {$ENDIF}
     ABSTypes,
     ABSConverts,
     ABSMemory,
     ABSExcept,
     ABSConst;


//  Return DataSize
function GetDataSizeInMemory(DataType: TABSBaseFieldType; Length: Integer = 0): Integer; overload;

//  Return DataSize
function GetDataSizeInMemory(DataType: TABSBaseFieldType; Data: Pointer): Integer; overload;

// Allocate Memory and Set Data
procedure AllocMemAndSetData(DataType: TABSBaseFieldType; const Value; out Buffer; out BufferSize: Integer);

implementation


//------------------------------------------------------------------------------
//  Return DataSize
//------------------------------------------------------------------------------
function GetDataSizeInMemory(DataType: TABSBaseFieldType; Length: Integer): Integer;
begin
  case DataType of
    bftChar,            // AsciZ
    bftVarchar:         Result := Length + 1;
    bftWideChar,
    bftWideVarchar:     Result := (Length + 1) * 2;

    bftSignedInt8:      Result := SizeOf(Shortint);
    bftSignedInt16:     Result := SizeOf(Smallint);
    bftSignedInt32:     Result := SizeOf(Integer);
    bftSignedInt64:     Result := SizeOf(Int64);
    bftUnSignedInt8:    Result := SizeOf(Byte);
    bftUnSignedInt16:   Result := SizeOf(Word);
    bftUnSignedInt32:   Result := SizeOf(Cardinal);

    bftSingle:          Result := SizeOf(Single);
    bftDouble:          Result := SizeOf(Double);
    bftExtended:        Result := SizeOf(Extended);

    bftDate:            Result := SizeOf(TABSDate);
    bftTime:            Result := SizeOf(TABSTime);
    bftDateTime:        Result := SizeOf(TABSDateTime);

    bftBlob,
    bftClob,
    bftWideClob:        Result := SizeOf(TABSPageItemID)+SizeOf(PAnsiChar); // 10

    bftLogical:         Result := SizeOf(TABSLogical);
    bftCurrency:        Result := SizeOf(TABSCurrency);
    // 5.07 Bytes bugfix
    // begin old code
    // bftBytes:           Result := Length;
    //  bftVarBytes:        Result := Length;
    // end old code
    bftBytes:           Result := Length + 1;
    bftVarBytes:        Result := Length + 1;

    else
      raise EABSException.Create(30050, ErrorGUnknownDataType, [BftToStr(DataType)]);
  end;
end;//GetDataSizeInMemory


//------------------------------------------------------------------------------
//  Return DataSize
//------------------------------------------------------------------------------
function GetDataSizeInMemory(DataType: TABSBaseFieldType; Data: Pointer): Integer; overload;
begin
//  Result := -1;
  case DataType of
    bftChar,
    bftVarchar:
        Result := GetDataSizeInMemory(DataType, Length(PAnsiChar(Data)));
    bftWideChar,
    bftWideVarchar:
        Result := GetDataSizeInMemory(DataType, Length(PWideChar(Data)));
    else
        Result := GetDataSizeInMemory(DataType);
  end;
end;//GetDataSizeInMemory


//------------------------------------------------------------------------------
// Allocate Memory and Set Data
//------------------------------------------------------------------------------
procedure AllocMemAndSetData(DataType: TABSBaseFieldType;
                             const Value;
                             out Buffer;
                             out BufferSize: Integer);
var len: Integer;
begin
  Pointer(Buffer) := nil;
  try
    case DataType of
      bftChar,
      bftVarchar:
        begin
          len := Length(PAnsiChar(Value));
          BufferSize := GetDataSizeInMemory(DataType,len);
          Pointer(Buffer) := MemoryManager.GetMem(BufferSize);
          Move(PAnsiChar(AnsiString(Value))^, PAnsiChar(Buffer)^, BufferSize);
        end;
      bftWideChar,
      bftWideVarchar:
        begin
          len := Length(PWideChar(Value));
          BufferSize := GetDataSizeInMemory(DataType,len);
          Pointer(Buffer) := MemoryManager.GetMem(BufferSize);
          Move(PWideChar(Value)^, PAnsiChar(Buffer)^, BufferSize);
        end;
      else
        begin
          BufferSize := GetDataSizeInMemory(DataType);
          Pointer(Buffer) := MemoryManager.GetMem(BufferSize);
          case BufferSize of
            1:      PByte(Buffer)^ := Byte(Value);
            2:      PWord(Buffer)^ := Word(Value);
            4:      PInteger(Buffer)^ := Integer(Value);
            8:      PInt64(Buffer)^ := Int64(Value);
            10:     PExtended(Buffer)^ := Extended(Value);
            else    Move(Value, PAnsiChar(Buffer)^, BufferSize);
          end;
        end;
    end;
  except
    if Pointer(Buffer) <> nil then
      raise EABSException.Create(30054, ErrorGCannotCopyDataIntoNewMemory);
  end;
end;//AllocMemAndSetData



end.

