Skip to content
Permalink
Browse files

Cleaning hierarchy

  • Loading branch information
guillep committed Nov 12, 2018
1 parent 3291ff0 commit fc95c86b5822b7d5c1296bc98b8d8a5171c14994
@@ -147,38 +147,7 @@ OSEnvironment >> at: key ifPresent: oneArgBlock ifAbsent: absentBlock [

{ #category : #accessing }
OSEnvironment >> at: aKey put: aValue [
^ self setEnv: aKey value: aValue
]

{ #category : #private }
OSEnvironment >> basicGetEnvRaw: encodedVariableName [

"PRIVATE: This primitive call works on Strings, while the correct way to manage encodings is with raw data.
Use me through #getEnvRaw: to correctly marshall data."

"Gets the value of an environment variable called `anEncodedVariableName` already encoded but in ByteString form."

<primitive: 'primitiveGetenv' module: '' error: ec>
ec ifNil: [ ^self getEnvViaFFI: encodedVariableName ].
self primitiveFail
]

{ #category : #private }
OSEnvironment >> basicGetEnvViaFFI: arg1 [

"PRIVATE: This FFI call works on Strings, while the correct way to manage encodings is with raw data.
Use me through #getEnvViaFFI: to correctly marshall data."

"This method calls the Standard C Library getenv() function.
The name of the argument (arg1) should fit decompiled version."

^ self ffiCall: #( String getenv (String arg1) ) module: LibC
]

{ #category : #private }
OSEnvironment >> defaultEncoding [

^ ZnCharacterEncoder utf8
^ self subclassResponsibility
]

{ #category : #enumeration }
@@ -192,41 +161,8 @@ OSEnvironment >> getEnv: aVariableName [
"Gets the value of an environment variable called `aVariableName`
It is the system reponsibility to manage the encoding.
Rationale: A common denominator for all platforms providing an already decoded string, because windows does not (compared to *nix systems) provide a encoded byte representation of the value. Windows has instead its own wide string representation."
^ self getEnv: aVariableName encoding: self defaultEncoding
]

{ #category : #private }
OSEnvironment >> getEnv: aVariableName encoding: anEncoding [
"Gets the value of an environment variable called `` using `anEncoding` to encode/decode arguments and return values.
Rationale: *xes could use different encodings"

| rawValue |
rawValue := self getEnvRaw: (aVariableName encodeWith: anEncoding).
^ rawValue ifNotNil: [ rawValue decodeWith: anEncoding ]
]

{ #category : #private }
OSEnvironment >> getEnvRaw: encodedVariableName [

"Gets the value of an environment variable called `anEncodedVariableName` already encoded.
It is the user responsibility to encode and decode argument and return values in the encoding of this preference.
Rationale: Some systems may want to have the liberty to use different encodings, or even to put binary data in the variables."

"This method calls the primitiveGetenv primitive and falls back into FFI if not available."

"OSEnvironment current getEnvRaw: 'HOME' utf8Encoded"

| rawValue |
rawValue := self basicGetEnvRaw: encodedVariableName asString.
^ rawValue ifNotNil: [ rawValue asByteArray ].
]

{ #category : #private }
OSEnvironment >> getEnvViaFFI: encodedString [

"The FFI call works on Strings, while the correct way to manage encodings is with raw data.
Transform back and forth from byte arrays to strings and vice versa to maintain the correct behaviour"
^ (self basicGetEnvViaFFI: encodedString asString) asByteArray
self subclassResponsibility
]

{ #category : #testing }
@@ -282,13 +218,7 @@ OSEnvironment >> platform [

{ #category : #accessing }
OSEnvironment >> removeKey: key [
^ self unsetEnv: key
]

{ #category : #accessing }
OSEnvironment >> unsetEnv: string [
"This method calls the Standard C Library getenv() function"
^ self ffiCall: #( int unsetenv (String string) ) module: LibC
^ self subclassResponsibility
]

{ #category : #accessing }
@@ -19,6 +19,12 @@ PlatformIndependentEnvironment class >> isDefaultFor: aPlatform [
^ false
]

{ #category : #accessing }
PlatformIndependentEnvironment >> at: aKey put: aValue [

"Do nothing"
]

{ #category : #private }
PlatformIndependentEnvironment >> getEnv: aVariableName [
^ nil
@@ -29,6 +35,12 @@ PlatformIndependentEnvironment >> keysAndValuesDo: aBlock [
"Do nothing"
]

{ #category : #accessing }
PlatformIndependentEnvironment >> removeKey: key [

"Do nothing"
]

{ #category : #private }
PlatformIndependentEnvironment >> setEnv: nameString value: valueString [
"Do nothing"
@@ -14,6 +14,51 @@ UnixEnvironment class >> isDefaultFor: aPlatform [
or: [ aPlatform isMacOS ] ]
]

{ #category : #accessing }
UnixEnvironment >> at: aKey put: aValue [

^ self at: aKey put: aValue encoding: self defaultEncoding
]

{ #category : #accessing }
UnixEnvironment >> at: aKey put: aValue encoding: anEncoding [

^ self
rawAt: (aKey encodeWith: anEncoding)
put: (aValue encodeWith: anEncoding)
]

{ #category : #private }
UnixEnvironment >> basicGetEnvRaw: encodedVariableName [

"PRIVATE: This primitive call works on Strings, while the correct way to manage encodings is with raw data.
Use me through #getEnvRaw: to correctly marshall data."

"Gets the value of an environment variable called `anEncodedVariableName` already encoded but in ByteString form."

<primitive: 'primitiveGetenv' module: '' error: ec>
ec ifNil: [ ^self getEnvViaFFI: encodedVariableName ].
self primitiveFail
]

{ #category : #private }
UnixEnvironment >> basicGetEnvViaFFI: arg1 [

"PRIVATE: This FFI call works on Strings, while the correct way to manage encodings is with raw data.
Use me through #getEnvViaFFI: to correctly marshall data."

"This method calls the Standard C Library getenv() function.
The name of the argument (arg1) should fit decompiled version."

^ self ffiCall: #( String getenv (String arg1) ) module: LibC
]

{ #category : #private }
UnixEnvironment >> defaultEncoding [

^ ZnCharacterEncoder utf8
]

{ #category : #accessing }
UnixEnvironment >> environ [
"Return the address of the array holding the environment variables"
@@ -27,6 +72,48 @@ UnixEnvironment >> environAt: index [
^ self environ at: index
]

{ #category : #private }
UnixEnvironment >> getEnv: aVariableName [
"Gets the value of an environment variable called `aVariableName`
It is the system reponsibility to manage the encoding.
Rationale: A common denominator for all platforms providing an already decoded string, because windows does not (compared to *nix systems) provide a encoded byte representation of the value. Windows has instead its own wide string representation."
^ self getEnv: aVariableName encoding: self defaultEncoding
]

{ #category : #private }
UnixEnvironment >> getEnv: aVariableName encoding: anEncoding [
"Gets the value of an environment variable called `` using `anEncoding` to encode/decode arguments and return values.
Rationale: *xes could use different encodings"

| rawValue |
rawValue := self getEnvRaw: (aVariableName encodeWith: anEncoding).
^ rawValue ifNotNil: [ rawValue decodeWith: anEncoding ]
]

{ #category : #private }
UnixEnvironment >> getEnvRaw: encodedVariableName [

"Gets the value of an environment variable called `anEncodedVariableName` already encoded.
It is the user responsibility to encode and decode argument and return values in the encoding of this preference.
Rationale: Some systems may want to have the liberty to use different encodings, or even to put binary data in the variables."

"This method calls the primitiveGetenv primitive and falls back into FFI if not available."

"OSEnvironment current getEnvRaw: 'HOME' utf8Encoded"

| rawValue |
rawValue := self basicGetEnvRaw: encodedVariableName asString.
^ rawValue ifNotNil: [ rawValue asByteArray ].
]

{ #category : #private }
UnixEnvironment >> getEnvViaFFI: encodedString [

"The FFI call works on Strings, while the correct way to manage encodings is with raw data.
Transform back and forth from byte arrays to strings and vice versa to maintain the correct behaviour"
^ (self basicGetEnvViaFFI: encodedString asString) asByteArray
]

{ #category : #enumeration }
UnixEnvironment >> keysAndValuesDo: aBlock [
| index associationString |
@@ -39,8 +126,25 @@ UnixEnvironment >> keysAndValuesDo: aBlock [
] repeat.
]

{ #category : #accessing }
UnixEnvironment >> rawAt: anEncodedName put: bytes [

^ self setEnv: anEncodedName asString value: bytes asString
]

{ #category : #accessing }
UnixEnvironment >> removeKey: key [
^ self unsetEnv: key
]

{ #category : #private }
UnixEnvironment >> setEnv: nameString value: valueString [
"This method calls the Standard C Library getenv() function"
^ self ffiCall: #( int setenv (String nameString, String valueString, 1) ) module: LibC
]

{ #category : #private }
UnixEnvironment >> unsetEnv: string [
"This method calls the Standard C Library getenv() function"
^ self ffiCall: #( int unsetenv (String string) ) module: LibC
]
@@ -12,21 +12,28 @@ Win32Environment class >> isDefaultFor: aPlatform [
^ aPlatform isWin32
]

{ #category : #accessing }
Win32Environment >> at: aKey put: aValue [

| w32Key w32Value return |
w32Key := aKey asWin32WideString.
w32Value := aValue asWin32WideString.
return := OSPlatform current setEnvironmentVariable: w32Key value: w32Value.

"From MSDN: If the function fails, the return value is zero."
return = 0 ifTrue: [
self error: 'An error occurred while setting environment variable ', aKey asString, ' to ', aValue asString ].
]

{ #category : #accessing }
Win32Environment >> environmentStrings [
^ self ffiCall: #( void * GetEnvironmentStrings () ) module: #Kernel32
]

{ #category : #accessing }
{ #category : #private }
Win32Environment >> getEnv: aVariableName [
"The primitive on Windows currently uses the ascii version of the Windows API.
In such chase try to get value of the environment variable using FFI."
^ self getEnvViaFFI: aVariableName
]

{ #category : #private }
Win32Environment >> getEnvViaFFI: aVariableName [

^ self getEnvViaFFI: aVariableName bufferSize: 500
]

@@ -40,7 +47,7 @@ Win32Environment >> getEnvViaFFI: aVariableName bufferSize: aSize [

"From MSDN: If the function fails, the return value is zero. If the specified environment variable was not found in the environment block, GetLastError returns ERROR_ENVVAR_NOT_FOUND."
return = 0 ifTrue: [
OSPlatform current lastError = 16r000000CB
OSPlatform current lastError = "ERROR_ENVVAR_NOT_FOUND" 16r000000CB
ifTrue: [ ^ nil ]
ifFalse: [ self error: 'An error occurred while fetching environment variable ', aVariableName asString ] ].

@@ -68,13 +75,14 @@ Win32Environment >> keysAndValuesDo: aBlock [
environmentStrings := environmentStrings + nextString size + 1 ] repeat
]

{ #category : #private }
Win32Environment >> setEnv: nameString value: valueString [
"This method calls the Standard C Library getenv() function"
^ self ffiCall: #( int SetEnvironmentVariableA ( String nameString, String valueString ) ) module: #Kernel32
]

{ #category : #accessing }
Win32Environment >> unsetEnv: aString [
^ self setEnv: aString value: nil
Win32Environment >> removeKey: aKey [

| w32Key w32Value return |
w32Key := aKey asWin32WideString.
return := OSPlatform current setEnvironmentVariable: w32Key value: nil.

"From MSDN: If the function fails, the return value is zero."
return = 0 ifTrue: [
self error: 'An error occurred while removing environment variable ', aKey asString ].
]
@@ -109,6 +109,12 @@ WinPlatform >> multiByteToWideCharacterCodepage: codepage flags: flags input: in
^self ffiCall: #(int MultiByteToWideChar(uint codepage, ulong flags, String input, int inputLen, Win32WideString output, int outputLen ))
]

{ #category : #'environment-variables' }
WinPlatform >> setEnvironmentVariable: nameString value: valueString [

^ self ffiCall: #( int SetEnvironmentVariableW ( String nameString, String valueString ) )
]

{ #category : #accessing }
WinPlatform >> virtualKey: virtualKeyCode [
"Win32Platform virtualKey: $C charCode"

0 comments on commit fc95c86

Please sign in to comment.
You can’t perform that action at this time.