Recent

Author Topic: Function to understand the level of a directory  (Read 811 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2043
    • Lazarus and Free Pascal italian community
Function to understand the level of a directory
« on: January 27, 2020, 09:52:36 pm »
Hi guys, is there a function that tells me the level of a function? For example, if I pass two parameters, it tells me which of the two is higher

par1: /tmp/hello_world/
par2: /tmp/hello_world/../

You must tell me that par1 is at a higher level than par2.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

winni

  • Hero Member
  • *****
  • Posts: 870
Re: Function to understand the level of a directory
« Reply #1 on: January 27, 2020, 10:30:50 pm »
Hi!

Just count the slashes in the path - that tells you how deep that directory tree is.

Take care that all pathes have as ending a slash.

Winni

PaulRowntree

  • Full Member
  • ***
  • Posts: 109
    • Paul Rowntree
Re: Function to understand the level of a directory
« Reply #2 on: January 27, 2020, 11:27:45 pm »
You also must check that one path is within the other.  I would determine the length of the two strings, then verify that the shorter string is found a the start of the longer string.
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6704
Re: Function to understand the level of a directory
« Reply #3 on: January 27, 2020, 11:43:50 pm »
Just count the slashes in the path - that tells you how deep that directory tree is.
But you must remove embedded '..' first. You can use CleanAndExpandDirectory for this purpose (in unit LazFileUtils).
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Zvoni

  • Sr. Member
  • ****
  • Posts: 332
Re: Function to understand the level of a directory
« Reply #4 on: January 28, 2020, 08:38:49 am »
If it's windows only, you could use strcmp or memcmp
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

Thaddy

  • Hero Member
  • *****
  • Posts: 9596
Re: Function to understand the level of a directory
« Reply #5 on: January 28, 2020, 08:43:52 am »
Just count the slashes in the path - that tells you how deep that directory tree is.
But you must remove embedded '..' first. You can use CleanAndExpandDirectory for this purpose (in unit LazFileUtils).
Indeed, and also resolve possible hardlinks and symlinks as well as canonical paths.
Mac died, can't really support it right now.

Zvoni

  • Sr. Member
  • ****
  • Posts: 332
Re: Function to understand the level of a directory
« Reply #6 on: January 28, 2020, 08:50:14 am »
Just remembered the actual WinAPI-Function i was looking for:
If it's windows only: RTLCompareMemory
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcomparememory
Quote
The RtlCompareMemory routine compares two blocks of memory and returns the number of bytes that match.
In combination with strcmp or memcmp it would be quite easy.
The CleanAndExpandDirectory not withstanding.
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

PascalDragon

  • Hero Member
  • *****
  • Posts: 951
  • Compiler Developer
Re: Function to understand the level of a directory
« Reply #7 on: January 28, 2020, 09:26:32 am »
Just remembered the actual WinAPI-Function i was looking for:
If it's windows only: RTLCompareMemory
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcomparememory
Quote
The RtlCompareMemory routine compares two blocks of memory and returns the number of bytes that match.
In combination with strcmp or memcmp it would be quite easy.

Why do you recommend some Windows specific functionality when the paths that xinyiman showed are clearly Unix paths? Also this wouldn't help anything. This would just return whether they are equal or at what position they differ.

For the depth - as xinyiman asked for - resolving the two paths and then counting the slashes is the more correct approach.

Zvoni

  • Sr. Member
  • ****
  • Posts: 332
Re: Function to understand the level of a directory
« Reply #8 on: January 28, 2020, 10:27:26 am »

Why do you recommend some Windows specific functionality when the paths that xinyiman showed are clearly Unix paths? Also this wouldn't help anything. This would just return whether they are equal or at what position they differ.

For the depth - as xinyiman asked for - resolving the two paths and then counting the slashes is the more correct approach.
I saw a "Win10" in his signature, but you're correct with the Unix-Paths. I missed that.
As for "RtlCompareMemory": That function actually returns the number of matching bytes, as in: To which position are the strings (better said: memory-blocks) equal.
If that number of bytes equals the length of par1, then par1 is on a higher level!
That was the idea behind my approach.
I looked into sysutils, and you're right: i could only find the equivalents to strcmp and memcmp, but nothing equal to RtlCompareMemory (a pity. I like RtlCompareMemory for fast comparing strings or arrays)
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

Bart

  • Hero Member
  • *****
  • Posts: 3626
    • Bart en Mariska's Webstek
Re: Function to understand the level of a directory
« Reply #9 on: January 28, 2020, 10:31:12 am »
If that number of bytes equals the length of par1, then par1 is on a higher level!
That's rather unreliable if you do not expand the pathnane before you start.
Also it assumes that one folder is a subfolder of the other, which we don't know to be true always (it ma be, it's just not specified in the question).

Bart

Zvoni

  • Sr. Member
  • ****
  • Posts: 332
Re: Function to understand the level of a directory
« Reply #10 on: January 28, 2020, 10:36:54 am »
If that number of bytes equals the length of par1, then par1 is on a higher level!
That's rather unreliable if you do not expand the pathnane before you start.
Also it assumes that one folder is a subfolder of the other, which we don't know to be true always (it ma be, it's just not specified in the question).

Bart
I did write "CleanAndExpandDirectory not withstanding"!
Of course he has to clean up the paths beforehand,
and his example did imply explicitely, that par2 is actually a subfolder of par1 *shrug*.
So, in that case: If MatchingBytes is smaller than length of par1, then par2 is not a direct subfolder
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

wp

  • Hero Member
  • *****
  • Posts: 6704
Re: Function to understand the level of a directory
« Reply #11 on: January 28, 2020, 10:55:50 am »
I don't see why a string comparison can decide about directory level.

par1: /tmp/hello_world/
par2: /tmp/hello/

In this example, par2 is shorter by characters, but at the same directory level as par1.
« Last Edit: January 28, 2020, 11:49:19 am by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Zvoni

  • Sr. Member
  • ****
  • Posts: 332
Re: Function to understand the level of a directory
« Reply #12 on: January 28, 2020, 11:19:51 am »
I never said, that my algorithm is complete.
Of course there have to be sanity-checks (last character of par2 being a DirectorySeparator etc.) as said in the very first reply:
Hi!

Just count the slashes in the path - that tells you how deep that directory tree is.

Take care that all pathes have as ending a slash.

Winni
EDIT: and i'm out of this discussion.
The OP was served a few ideas how to skin that cat.
« Last Edit: January 28, 2020, 11:50:01 am by Zvoni »
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

xinyiman

  • Hero Member
  • *****
  • Posts: 2043
    • Lazarus and Free Pascal italian community
Re: Function to understand the level of a directory
« Reply #13 on: January 29, 2020, 08:27:11 am »
Hi guys, then I think I solved it for unix environments (mac os and linux) using the CleanAndExpandDirectory function as you suggested. Then check if path2 starts with path1.
if Pos (path1, path2) <> 1 then
    result: = path1;
Basically so the user cannot get out of that path. This I need because I am writing a small web service for remote file transfer. A kind of ftp but through the http / https protocol thanks to the lazarus embedded http server.
I have yet to try if it works properly on windows.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1