{
* Copyright 2008 ZXing authors
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
* Original Author: bbrown@google.com (Brian Brown)
* Delphi Implementation by E. Spelt and K. Gossens
}
unit ZXing.ReadResult;
interface
uses
System.SysUtils,
Generics.Collections,
ZXing.ResultPoint,
ZXing.ResultMetadataType,
ZXing.BarcodeFormat,
ZXing.ByteSegments;
type
IMetaData = Interface
['{27AEB2C5-D775-44C6-9816-3E69025CA57C}']
end;
IStringMetadata = interface(IMetaData)
['{8073F897-30AD-49B7-AE0B-B187D3373163}']
function Value:String;
end;
IIntegerMetadata = interface(IMetaData)
['{CA60A23A-57ED-4C8E-9886-4F23B832A90C}']
function Value:Integer;
end;
IByteSegmentsMetadata = interface(IMetaData)
['{CA60A23A-57ED-4C8E-9886-4F23B832A90C}']
function Value:IByteSegments;
end;
///
/// represents the metadata contained in a TReadResult and provides the
/// helping functions needed to create them
///
TResultMetaData = class(TDictionary)
public
constructor Create;
class function CreateStringMetadata(const Value:string) :IStringMetaData;
class function CreateIntegerMetadata(const Value:integer) :IIntegerMetaData;
class function CreateByteSegmentsMetadata(const Value:IByteSegments) :IByteSegmentsMetadata;
end;
TReadResult = class
private
FText: string;
FTimeStamp: TDateTime;
FResultMetadata: TResultMetaData;
FRawBytes: TArray;
FResultPoints: TArray;
FFormat: TBarcodeFormat;
procedure SetText(const AValue: String);
procedure SetMetaData( const Value: TResultMetadata);
public
///
/// Initializes a new instance of the class.
///
/// The text.
/// The raw bytes.
/// The result points.
/// The format.
constructor Create(const text: string; const rawBytes: TArray;
const resultPoints: TArray;
const format: TBarcodeFormat); overload;
///
/// Initializes a new instance of the class.
///
/// The text.
/// The raw bytes.
/// The result points.
/// The format.
/// The timestamp.
constructor Create(const text: string; const rawBytes: TArray;
const resultPoints: TArray; const format: TBarcodeFormat;
const timeStamp: TDateTime); overload;
destructor Destroy; override;
function ToString: String; override;
// we need a "write" procedure accessor because we need to properly deallocate
// existing instance if we overwrite it with another one
property ResultMetaData: TResultMetadata
read FResultMetadata write SetMetaData;
///
/// Adds one metadata to the result
///
/// The type.
/// The value.
procedure putMetadata(const ResultMetadataType: TResultMetadataType;
const Value: IMetaData);
///
/// Adds a list of metadata to the result
///
/// The metadata.
procedure putAllMetaData(const metaData: TResultMetadata);
///
/// Adds the result points.
///
/// The new points.
procedure addResultPoints(const newPoints: TArray);
/// raw text encoded by the barcode, if applicable, otherwise null
property text: String read FText write SetText;
/// raw bytes encoded by the barcode, if applicable, otherwise null
property rawBytes: TArray read FRawBytes write FRawBytes;
///
/// points related to the barcode in the image. These are typically points
/// identifying finder patterns or the corners of the barcode. The exact meaning is
/// specific to the type of barcode that was decoded.
///
property resultPoints: TArray read FResultPoints
write FResultPoints;
/// {@link TBarcodeFormat} representing the format of the barcode that was decoded
property BarcodeFormat: TBarcodeFormat read FFormat write FFormat;
///
/// Gets the timestamp.
///
property timeStamp: TDateTime read FTimeStamp;
end;
implementation
{$REGION 'IMetaData implementations'}
{ TStringMetadata }
type
TStringMetadata = class(TInterfacedObject,IMetaData,IStringMetadata)
strict private
FValue: String;
function Value: String;
private
constructor Create(const AValue: String);
end;
function TStringMetadata.Value: String;
begin
result := FValue
end;
constructor TStringMetadata.Create(const AValue: string);
begin
inherited Create;
FValue := AValue;
end;
{ TIntegerMetadata }
type
TIntegerMetadata = class(TInterfacedObject,IMetaData,IIntegerMetadata)
strict private
FValue: Integer;
function Value: Integer;
private
constructor Create(const AValue: Integer);
end;
function TIntegerMetadata.Value: Integer;
begin
result := FValue
end;
constructor TIntegerMetadata.Create(const AValue: Integer);
begin
inherited Create;
FValue := AValue;
end;
{ TByteSegmentsMetadata }
type
TByteSegmentsMetadata = class(TInterfacedObject,IMetaData,IByteSegmentsMetadata)
strict private
FValue: IByteSegments;
function Value: IByteSegments;
private
constructor Create(const AValue: IByteSegments);
end;
function TByteSegmentsMetadata.Value: IByteSegments;
begin
result := FValue
end;
constructor TByteSegmentsMetadata.Create(const AValue: IByteSegments);
begin
inherited Create;
FValue := AValue;
end;
{ TResultMetadata }
constructor TResultMetaData.Create;
begin
inherited Create;
end;
class function TResultMetadata.CreateStringMetadata(const Value:string) :IStringMetaData;
begin
result := TStringMetadata.Create(Value);
end;
class function TResultMetaData.CreateByteSegmentsMetadata(
const Value: IByteSegments): IByteSegmentsMetadata;
begin
result := TByteSegmentsMetadata.Create(value);
end;
class function TResultMetadata.CreateIntegerMetadata(const Value:integer) :IIntegerMetaData;
begin
result := TIntegerMetadata.Create(Value);
end;
{$ENDREGION 'IMetaData implementations'}
{ TReadResult }
constructor TReadResult.Create(const text: String; const rawBytes: TArray;
const resultPoints: TArray; const format: TBarcodeFormat);
begin
Self.Create(text, rawBytes, resultPoints, format, Now);
end;
constructor TReadResult.Create(const text: String; const rawBytes: TArray;
const resultPoints: TArray; const format: TBarcodeFormat;
const timeStamp: TDateTime);
begin
if ((text = '') and (rawBytes = nil)) then
raise EArgumentException.Create('Text and bytes are null.');
SetText(text);
FRawBytes := rawBytes;
FResultPoints := resultPoints;
FResultMetadata := nil;
FFormat := format;
FResultMetadata := nil;
FTimeStamp := timeStamp;
end;
destructor TReadResult.Destroy;
var i:Integer;
begin
for I := Low(FResultPoints) to High(FResultPoints) do
begin
FResultPoints[i] := nil;
end;
FResultPoints := nil;
FRawBytes := nil;
if FResultMetadata <> nil then
begin
FResultMetadata.Clear;
FreeAndNil(FResultMetadata);
end;
inherited;
end;
// Added (KG): UTF-8 compatiblity
procedure TReadResult.SetMetaData(const Value: TResultMetadata);
begin
if value = FResultMetadata then
exit; // no change
if FResultMetadata<>nil then
FResultMetadata.Free; // we need to free existing object instance, for old-gen compilers
FResultMetadata := Value;
end;
procedure TReadResult.SetText(const AValue: String);
begin
FText := AValue;
end;
procedure TReadResult.putMetadata(const ResultMetadataType: TResultMetadataType;
const Value: IMetaData);
begin
if (FResultMetadata = nil) then
FResultMetadata := TResultMetadata.Create();
FResultMetadata.AddOrSetValue(ResultMetadataType, Value);
end;
procedure TReadResult.putAllMetaData(const metaData: TResultMetadata);
var
key: TResultMetadataType;
begin
if (metaData <> nil) then
begin
if (FResultMetadata = nil) then
FResultMetadata := TResultMetadata.Create();
for key in metaData.Keys do
FResultMetadata.AddOrSetValue(key, metaData[key]);
end;
end;
procedure TReadResult.addResultPoints(const newPoints: TArray);
begin
FResultPoints := FResultPoints + newPoints;
end;
///
/// Returns a that represents this instance.
///
///
/// A that represents this instance.
///
function TReadResult.ToString(): String;
begin
if (text = '') then
Result := '[' + IntToStr(Length(rawBytes)) + ' bytes]'
else
Result := text;
end;
end.