RODL Generation not working 9.2.103.1311

I have several RODL files which were working on previous versions 9 and 8.

Whenever I use ‘]’ in the documentation I get the following error:

CData section couldn’ contain ‘]]’ …

If I get rid of the ‘]’ by adding a ‘.’ at the end, the code can be generated. Nevertheless, if I use descriptions like

Volume [m³].

the RODL can not be loaded on runtime.

What platform is this that fails to load the RODL? It sounds like a bug either with how SB writes the RODL or with how the library reads it. Can you send us a sample broken RODL? Does it open ok in ServicBuilder, still?

The following resource file can not be interpreted during runtime. I already modified most of the descriptions without success.

RODLFile.zip (96.0 KB)

The source files:

SourceRODLS.zip (111.6 KB)

I create the resource file with the following code by passing the name of the main file which includes all other files:

class procedure RODLFunctions.RODLToResourceFile(const aInputFileName,
  aOutputFileName: string);
var
  aTempFile:string;
  aFileNameRODL:string;
  aResourceStream:TFileStream;
  aRODLStream:TFileStream;
begin
  if not FileFunctions.FileExists(aInputFileName) then
    raise EdoFileException.Create(StringFunctions.Format('RODL file [%s] not available',
      [aInputFileName]),Self.ClassName);
  aFileNameRODL := FileFunctions.ExtractFileName(aInputFileName);
  aFileNameRODL := FileFunctions.ChangeFilePath(aFileNameRODL,FileFunctions.GetTempPath);
  try
    ExpandRODLFile(aInputFileName,aFileNameRODL);
    aResourceStream := TFileStream.Create(aOutputFileName,fmCreate);
    try
      aRODLStream := TFileStream.Create(aFileNameRODL, fmOpenRead + fmShareDenyNone);
      try
        aRODLStream.Position := 0;
        uROResWriter.WriteRES(aRODLStream,aResourceStream,'RODLFILE');
      finally
        aRODLStream.Free;
      end;
    finally
      aResourceStream.Free;
    end;
  finally
    if FileFunctions.FileExists(aFileNameRODL) then
      FileFunctions.DeleteFile(aFileNameRODL);
  end;
end;

class procedure RODLFunctions.ExpandRODLFile(const aInputFileName,
        aOutputFileName: string);
    var
      aXMLRodl: TXMLToRODL;
      aLib: TRODLLibrary;
    begin
      aXMLRodl := TXMLToRODL.Create;
      try
        aLib := aXMLRodl.ReadFromFile(aInputFileName);
        try
          RODLToXMLFile(aLib, aOutputFileName, False);
        finally
          aLib.Free;
        end;
      finally
        aXMLRodl.Free;
      end;
    end;

Thanx, those RODL files look indeed ok, and they open fine in Service Builder; the XMNL is valid. At what point exactly do you get the CData section couldn’ contain ‘]]’ … error? When access there RODL or the documentation in the browser? When you try and import the RODL for a new client? Or at runtime in your client application itself? Is everything RO/Delphi, or are you using other client platforms?

thanx,
marc

Thanks, logged as bugs://78208

bugs://78208 got closed with status fixed.

sorry for inconvenience.

pls update IDE\uRORODLNotifier.pas as

function ProcessRodl(const Project: IOTAProject; aMessageList : TIDEMessageList; aRegenerateAsyncIfPresent: Boolean; aTypes: TROUnitTypes;  aFilename: string; aNested: boolean):Boolean;
...
        lr:= TRODLToXML.Create(lib,true);
        try
          lr.Buffer.SaveToFile(aFilename {$IFDEF UNICODE},TEncoding.UTF8{$ENDIF}); // changed

and recompile RemObjects_Server_IDE package

I generate all of the RODL files with a generator using msxml. I think the issue is based on the file uRODLToXML.

It generates invalid XML in some cases.

I made a simple test to check writing to XML and reading back to RODL. In my case it fails whenever i use superscript text.

ugbRODLTest.pas (5.2 KB)

The class procedure

class procedure TestRODLWithSuperscriptDocu;

generates an error.

The solution provided for the file uRORODLNotifier.pas does not help in this case.

I get the error when accesing the server from a client, The error is generated while trying to load the RODL from the RODL resource.

have you recompiled RemObjects_Server_IDE package ?
w/o it, fix won’t work with Delphi IDE at generation of .RES


in some cases, automatic delphi encoding doesn’t work as expected so
update uXMLToRODL.pas as

function TXMLToRODL.ReadFromString(const anAnsiString, aFilename: string): TRODLLibrary;
var
  ss: TMemoryStream;
  b: TBytes;
begin
  ss := TMemoryStream.Create;
  try
    {$IFDEF UNICODE}
    b := StringToUTF8Bytes(anAnsiString);
    {$ELSE}
    b := StringToAnsiBytes(anAnsiString);
    {$ENDIF}
    if Length(b) > 0 then ss.Write(b[0],Length(b));
    result := Read(ss, aFilename);
  finally
    ss.Free;
  end;
end;

and add uROEncoding into uses section of this unit.

We are not using the IDE to generate anything. The ROGEN directive is deactivated since we use our own tools to generate the RODL files I sent you.

We generate the .RES file with the procedures I sent at the beginning:

RODLFunctions.ExpandRODLFile
RODLFunctions.RODLToResourceFile

We have our own build process which includes:

  • Generation of RODL Files using a MSXML based genarator (The files I sent you were generated with the tool).
  • Generation of Interface and Invoker files usint TROCodegen4.
  • Generation of our own implementation (It was a surprise to realize you moved from AnsiString to String).
  • Generation of the RODL resource file.
  • Binaries build

Everything was working on prior versions.

your test (TestRODLWithSuperscriptDocu) is passed with change in TXMLToRODL.ReadFromString

migration from Ansistring was in favor of Linux support.
you could enable CODEGEN4_LEGACYSTRINGS definition in RemObjects.inc or set TROCodegen4.DelphiLegacyStrings := '1'. in this case, codegen4 generated code as before.

Yes the test passed.

Unfortunately it works only for that test. In the usual way to load a RODL from a resource file, there are other functions involved which in my case are still not working.

My main issue is writing the RODL files using RODLToXML. I would say that the problem lies in the function WriteAsCData.

It would be better to use an XMLDocument to generate the RODL files. The way you are writing the files (using a TStringList) causes XML issues in some cases.

I will go back to version 9 if I do not find a better solution at the moment.

Regarding the AnsiStrings, I will try to move on and test if the performance is better as you pointed out in another thread. In my case there are only a few cases where I really need an AnsiString or UTF8String (passwords perhaps), but it is definately a big move I can understand many users which are not happy with the changes.

I will keep you informed. For me is the current version not stable enough to be used for production.

Keep the good work.

I will try it as well, but since we are also interested in the Linux platform, It would be better to go ahead and update the API.

Thanks

note: this method returns string (i.e. UnicodeString for unicode versions of delphi and UTF8String for non-unicode versions of Delphi), so you need to save it to file with proper encoding.

you can use our method like :

  • convert this string to TBytes with UTF8 encoding with StringToUTF8Bytes and save TBytes to file
    or
  • specify TEncoding.UTF8 as 2nd parameter in TStrings.SaveToFile

We use already the procedure RODLToXMLFile which includes the conversions you mention.

Without including the documentation in the files it works as expected. If we include the documentation (with superscripted text fragments) the files can not be loaded. The error message we get is:

Project… raised exception class EROException with message 'Cannot load XML document. Reason: An invalid character was found in text content.

Line: 18067
Position: 33’

The call stack:

:763141c8 KERNELBASE.RaiseException + 0x48
uROClasses.RaiseError(‘Cannot load XML document.’#$D’Reason: %s’#$D’Line: %d’#$D’Position: %d’,(…))
uROMSXMLImpl.TROMSXMLDocument.LoadFromStream($5A163B0)
uXMLToRODL.TXMLToRODL.LoadStreamToLibrary($5A163B0,$4DF9FE0,’’,nil,True)
uXMLToRODL.TXMLToRODL.IntReadFromStream($5A163B0,’’)
uRODL.TRODLReader.Read($5A163B0,’’)
uRODLSupport.GetRodlLibrary(nil,False)
uRORTTIServerSupport.TRORTTIRODLReader.DoReadRODLResource($551D990)
uROCustomRODLReader.TROCustomRODLReader.ReadRODLResource($551D990)
uRODLSupport.GetRodl($551D970,nil,’’,$4DF9E60,False)
uRODLSupport.GetRodlLibrary($4DF9E60,False)
uROCustomHTTPServer.TROCustomHTTPServer.DoProcessDocs(TIndyHTTPTransport($54BD1DC) as IInterface,TIPHTTPResponseHeaders($5500810) as IROHTTPResponse,$551D8F0,’/’,’’)
uROBaseHTTPServer.TROBaseHTTPServer.ProcessRequest(TIndyHTTPTransport($54BD1DC) as IROHTTPTransportEx,$551D9B0,$551D8F0,TIPHTTPResponseHeaders($5500810) as IROHTTPResponse)
uROIndyHTTPServer.TROIndyHTTPServer.InternalServerCommandGet($4EA41B0,$4D9F080,$54D3000)
:0083e778 TIdCustomHTTPServer.DoCommandGet + $20
:0083f73e TIdCustomHTTPServer.DoExecute + $68E
:0080d52a TIdContext.Run + $12
:004d07d0 ThreadProc + $4C
:0040ad36 ThreadWrapper + $2A
:75593744 KERNEL32.BaseThreadInitThunk + 0x24
:770e9e54 ntdll.RtlSetCurrentTransaction + 0xd4
:770e9e1f ntdll.RtlSetCurrentTransaction + 0x9f

this means that RODLFile.res was generated incorrectly.

after

IDE generated valid RODL file: RODLFile.zip (90.6 KB) that doesn’t cause any problems.

empty project that returns the same rodl via http://localhost:8099/rodl - NewProject.zip (2.1 MB)

I still get the same error message with the file you sent me.

I gill investigate further and let you know.

Can you send me the empty project files please?

what’s your system non-unicode locale?
we have recently caught some bugs with chinese locale and UTF8 encoding in delphi std code.

13833.zip (889.2 KB)