├── ConsultaProduto.prw
├── Enderecos.prw
├── Filiais.prw
├── Produtos.prw
├── README.md
├── RecebeDadosInv.prw
└── Util
├── JSON.prg
├── RmvCharEsp.prw
└── SHash.prg
/ConsultaProduto.prw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielAlbuquerque/ADVPL-API-APP-ESTOQUE/f8c51639d7ef712508bb0e5d955d4d51f85109fb/ConsultaProduto.prw
--------------------------------------------------------------------------------
/Enderecos.prw:
--------------------------------------------------------------------------------
1 | #INCLUDE "TOTVS.CH"
2 | #INCLUDE "RESTFUL.CH"
3 |
4 | WSRESTFUL enderecos DESCRIPTION "Retorna os enderecos"
5 | WSMETHOD GET DESCRIPTION "Retorna os enderecos" WSSYNTAX "/enderecos/"
6 | END WSRESTFUL
7 |
8 | WSMETHOD GET WSSERVICE enderecos
9 | Local nI := 1
10 |
11 | ::SetContentType("application/json")
12 |
13 | dbSelectArea("SBE")
14 | SBE->(dbGoTop())
15 |
16 | ::SetResponse('[')
17 |
18 | While SBE->(!EOF())
19 | If nI > 1
20 | ::SetResponse(',')
21 | Endif
22 | ::SetResponse('{')
23 | ::SetResponse('"filial":"' + alltrim(SBE->BE_FILIAL)+ '",')
24 | ::SetResponse('"local":"' + alltrim(SBE->BE_LOCAL)+ '",')
25 | ::SetResponse('"endereco":"' + alltrim(SBE->BE_LOCALIZ)+ '"')
26 | ::SetResponse('}')
27 | nI++
28 | SBE->(dbSkip())
29 | End While
30 |
31 | ::SetResponse(']')
32 | Return .t.
--------------------------------------------------------------------------------
/Filiais.prw:
--------------------------------------------------------------------------------
1 | #INCLUDE "TOTVS.CH"
2 | #INCLUDE "RESTFUL.CH"
3 |
4 | WSRESTFUL filiais DESCRIPTION "Retorna as filiais"
5 | WSMETHOD GET DESCRIPTION "Retorna as filiais" WSSYNTAX "/filiais/"
6 | END WSRESTFUL
7 |
8 | WSMETHOD GET WSSERVICE filiais
9 | Local nI := 1
10 |
11 | ::SetContentType("application/json")
12 |
13 | dbSelectArea("SM0")
14 | SM0->(dbGoTop())
15 |
16 | ::SetResponse('[')
17 |
18 | While SM0->(!EOF())
19 | If nI > 1
20 | ::SetResponse(',')
21 | Endif
22 | ::SetResponse('{')
23 | ::SetResponse('"nome":"' + alltrim(SM0->M0_NOME)+ '",')
24 | ::SetResponse('"cod_filial":"' + alltrim(SM0->M0_CODFIL)+ '",')
25 | ::SetResponse('"filial":"' + alltrim(SM0->M0_FILIAL)+ '"')
26 | ::SetResponse('}')
27 | nI++
28 | SM0->(dbSkip())
29 | End While
30 |
31 | ::SetResponse(']')
32 | Return .t.
--------------------------------------------------------------------------------
/Produtos.prw:
--------------------------------------------------------------------------------
1 | #INCLUDE "TOTVS.CH"
2 | #INCLUDE "RESTFUL.CH"
3 |
4 | WSRESTFUL produtos DESCRIPTION "Retorna os produtos"
5 | WSMETHOD GET DESCRIPTION "Retorna os produtos" WSSYNTAX "/produtos/"
6 | END WSRESTFUL
7 |
8 | WSMETHOD GET WSSERVICE produtos
9 | Local nI := 1
10 |
11 | dbSelectArea("SB1")
12 | SB1->(dbGoTop())
13 |
14 | ::SetResponse('[')
15 |
16 | While SB1->(!EOF())
17 | If nI > 1
18 | ::SetResponse(',')
19 | Endif
20 | ::SetResponse('{')
21 | ::SetResponse('"filial":"' + alltrim(SB1->B1_FILIAL)+ '",')
22 | ::SetResponse('"codigo":"' + alltrim(SB1->B1_COD)+ '",')
23 | ::SetResponse('"descricao":"' + alltrim(SB1->B1_DESC)+ '"')
24 | ::SetResponse('}')
25 | nI++
26 | SB1->(dbSkip())
27 | End While
28 |
29 | ::SetResponse(']')
30 | Return .t.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # PROJETO DESATUALIZADO
3 |
4 | Esse projeto nao segue as boas praticas como por exemplo o uso da classe JsonObject
5 |
6 |
--------------------------------------------------------------------------------
/RecebeDadosInv.prw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielAlbuquerque/ADVPL-API-APP-ESTOQUE/f8c51639d7ef712508bb0e5d955d4d51f85109fb/RecebeDadosInv.prw
--------------------------------------------------------------------------------
/Util/JSON.prg:
--------------------------------------------------------------------------------
1 | /*----------------------------------------------------------------------*\
2 | * JSON for AdvPL
3 | * Copyright (C) 2013 Arthur Helfstein Fragoso
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published
7 | * by the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | *
18 | * This program includes the function JsonMinify that is a ported version
19 | * of JSONLint by Chris Dary. Here is his original license: (MIT License)
20 | *
21 | * Copyright (c) 2011 Chris Dary.
22 | *
23 | * Permission to use, copy, modify, and/or distribute this software for any
24 | * purpose with or without fee is hereby granted, provided that the above
25 | * copyright notice and this permission notice appear in all copies.
26 | *
27 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
28 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
29 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
30 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
31 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
32 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
33 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 | *
35 | *----------------------------------------------------------------------*
36 | *
37 | * How to use this program:
38 | *
39 | * 1 - Add the files JSON.prg and SHash.prg to your project.
40 | *
41 | * 2 - Compile JSON.prg and SHash.prg.
42 | *
43 | * 3 - Include the header files to any project you want to use it:
44 | *
45 | * #Include "aarray.ch"
46 | * #Include "json.ch"
47 | *
48 | * 4 - See the functions documentation, it's very easy to use it. ;)
49 | *
50 | *
51 | * Note: Thanks to the preprocessor we can call user functions without
52 | * the U_, look at the aarray.ch header file to understand it better.
53 | *
54 | \*----------------------------------------------------------------------*/
55 |
56 | #Include "aarray.ch"
57 | #Include "json.ch"
58 |
59 |
60 | /**
61 | * (User) Function: FromJson(cJstr)
62 | * Converts from a JSON string into any value it holds
63 | *
64 | * Example:
65 | * ----
66 | * cJSON := '{"Products": [{"Name": "Water", "Cost": 1.3}, {"Name": "Bread", "Cost": 4e-1}], "Users": [{"Name": "Arthur", "Comment": "Hello\" \\World"}]}'
67 | *
68 | * aaBusiness := FromJson(cJSON)
69 | *
70 | * alert(aaBusiness[#'Products'][1][#'Name']) // Returns -> Water
71 | *
72 | * alert(aaBusiness[#'Products'][2][#'Cost']) // Returns -> 0.4
73 | *
74 | * alert(aaBusiness[#'Users'][1][#'Comment']) // Returns -> Hello" \World
75 | * ----
76 | *
77 | * Additional Info:
78 | * * Numbers accept the Scientific E Notation
79 | * 234e-7 = 0.0000234
80 | * 57e3 = 57000
81 | * * I don't know how I can make an Unicode or UTF-8 character in AdvPL,
82 | * So, the json \uXXXX converts an ASCII code. Values outside the ASCII table becomes '?' (quotation marks).
83 | *
84 | * @param cJstr - The JSON string you want to convert from
85 | * @return - The converted JSON string, it can be any type. Or Nil in case of a bad formatted JSON string.
86 | **/
87 |
88 | Function FromJson(cJstr)
89 | Return GetJsonVal(cJstr)[1]
90 |
91 |
92 |
93 |
94 |
95 | /**
96 | * (User) Function: ToJson(uAnyVar)
97 | * Converts AdvPLs value into a JSON string
98 | * Accepted values: Strings, Numbers, Logicals, Nil, Arrays and Associative Arrays (SHash Objects)
99 | *
100 | * Example:
101 | * ----
102 | * aaBusiness := Array(#)
103 | * aaBusiness[#'Products'] := Array(2)
104 | * aaBusiness[#'Products'][1] := Array(#)
105 | * aaBusiness[#'Products'][1][#'Name'] := "Water"
106 | * aaBusiness[#'Products'][1][#'Cost'] := 1.3
107 | * aaBusiness[#'Products'][2] := Array(#)
108 | * aaBusiness[#'Products'][2][#'Name'] := "Bread"
109 | * aaBusiness[#'Products'][2][#'Cost'] := 0.4
110 | * aaBusiness[#'Users'] := Array(1)
111 | * aaBusiness[#'Users'][1] := Array(#)
112 | * aaBusiness[#'Users'][1][#'Name'] := "Arthur"
113 | * aaBusiness[#'Users'][1][#'Comment'] := 'Hello" \World'
114 | *
115 | *
116 | * alert( ToJson(aaBusiness) )
117 | *
118 | * // Returns:
119 | * {"Products": [{"Name": "Water", "Cost": 1.3}, {"Name": "Bread", "Cost": 0.4}], "Users": [{"Name": "Arthur", "Comment": "Hello\" \\World"}]}
120 | * ----
121 | *
122 | * @param uAnyVar - The value you want to convert to a JSON string
123 | * @return string - JSON string
124 | **/
125 |
126 | Function ToJson (uAnyVar)
127 | Local cRet, nI, cType, aAsKeys
128 |
129 | cType := valType(uAnyVar)
130 | DO CASE
131 | case cType == "C"
132 | return '"'+ EscpJsonStr(uAnyVar) +'"'
133 | case cType == "N"
134 | return CvalToChar(uAnyVar)
135 | case cType == "L"
136 | return if(uAnyVar,"true","false")
137 | case cType == "D"
138 | return '"'+ DtoS(uAnyVar) +'"'
139 | case cType == "U"
140 | return "null"
141 | case cType == "A"
142 | cRet := '['
143 | For nI := 1 to len(uAnyVar)
144 | if(nI != 1)
145 | cRet += ', '
146 | endif
147 | cRet += ToJson(uAnyVar[nI])
148 | Next
149 | return cRet + ']'
150 | case cType == "B"
151 | return '"Type Block"'
152 | case cType == "M"
153 | return '"Type Memo"'
154 | case cType =="O"
155 | if uAnyVar:cClassName == "SHASH"
156 | cRet := '{'
157 | For nI := 1 to len(uAnyVar:aData)
158 | if(nI != 1)
159 | cRet += ', '
160 | endif
161 | cRet += '"'+ EscpJsonStr(uAnyVar:aData[nI][SPROPERTY_KEY]) +'": '+ ToJson(uAnyVar:aData[nI][SPROPERTY_VALUE])
162 | Next
163 | return cRet + '}'
164 | endif
165 | return '"Type Object"'
166 | #IFDEF __HARBOUR__
167 | case cType =="H" //Harbour Associative Array
168 | aAsKeys := hb_hkeys(uAnyVar)
169 | cRet := '{'
170 | For nI := 1 to len(aAsKeys)
171 | if(nI != 1)
172 | cRet += ', '
173 | endif
174 | cRet += '"'+ EscpJsonStr(aAsKeys[nI]) +'": '+ ToJson(uAnyVar[aAsKeys[nI]])
175 | Next
176 | return cRet + '}'
177 | #ENDIF
178 | ENDCASE
179 | Return '"Unknown Data Type ('+ cType +')"'
180 |
181 |
182 | /**
183 | * (User) Function: EscpJsonStr(cJsStr)
184 | * Escapes string to a JSON string format
185 | * ToJson() Automatically escapes strings, there is no much use of this function unless
186 | * you want to write the JSON strings yourself.
187 | *
188 | * Example:
189 | * ----
190 | * cProdName := 'Cool" and \ cool"'
191 | *
192 | * cJSON := '{"Product": {"Name": "'+ EscpJsonStr(cProdName) +'"}}'
193 | *
194 | * alert( JsonPrettify(cJSON) ) // -> {"Product": {"Name": "Cool\" and \\ cool\""}}
195 | * ----
196 | *
197 | * @param cJsStr - The String you want to escape
198 | * @return cJsStr - Escaped JSON string
199 | **/
200 |
201 | Function EscpJsonStr(cJsStr)
202 | cJsStr := StrTran(cJsStr, '\', '\\') // we must escape \ first, so it won't bug the rest
203 | cJsStr := StrTran(cJsStr, '"', '\"')
204 | cJsStr := StrTran(cJsStr, CHR_FF, '\f')
205 | cJsStr := StrTran(cJsStr, CHR_LF, '\n')
206 | cJsStr := StrTran(cJsStr, CHR_CR, '\r')
207 | cJsStr := StrTran(cJsStr, CHR_HT, '\t')
208 | Return cJsStr
209 |
210 |
211 | /**
212 | * (User) Function: JsonPrettify(cJstr [,nTab])
213 | * Prettify a JSON string. It will indent and make it more readable
214 | *
215 | * Example:
216 | * -----
217 | * cJSON := '{"Products": [{"Name": "Water", "Cost": 1.30}, {"Name": "Bread", "Cost": 0.40}]}'
218 | *
219 | * alert( JsonPrettify(cJSON, 4) )
220 | *
221 | * Result:
222 | *
223 | * {
224 | * "Products": [
225 | * {
226 | * "Name": "Water",
227 | * "Cost": 1.30
228 | * },
229 | * {
230 | * "Name": "Bread",
231 | * "Cost": 0.40
232 | * }
233 | * ]
234 | * }
235 | * ----
236 | *
237 | * @param cJstr - The JSON string to prettify
238 | * @param nTab (opitional) - number of spaces for each indentation, -1 for tabs (\t) (Default: -1)
239 | * @return string - Prettified JSON string
240 | **/
241 |
242 | Function JsonPrettify(cJstr, nTab)
243 | Local nConta, cBefore, cTab
244 | Local cLetra := ""
245 | Local lInString := .F.
246 | Local cNewJsn := ""
247 | Local nIdentLev := 0
248 | Default nTab := -1
249 |
250 | if nTab > 0
251 | cTab := REPLICATE(" ", nTab)
252 | else
253 | cTab := CHR_HT
254 | endif
255 |
256 |
257 | For nConta:= 1 To Len(cJstr)
258 |
259 | cBefore := cLetra
260 | cLetra := SubStr(cJstr, nConta, 1)
261 |
262 | if cLetra == "{" .or. cLetra == "["
263 | if !lInString
264 | nIdentLev++
265 | cNewJsn += cLetra + CRLF + REPLICATE( cTab, nIdentLev)
266 | else
267 | cNewJsn += cLetra
268 | endif
269 | elseif cLetra == "}" .or. cLetra == "]"
270 | if !lInString
271 | nIdentLev--
272 | cNewJsn += CRLF + REPLICATE(cTab, nIdentLev) + cLetra
273 | else
274 | cNewJsn += cLetra
275 | endif
276 | elseif cLetra == ","
277 | if !lInString
278 | cNewJsn += cLetra + CRLF + REPLICATE(cTab, nIdentLev)
279 | else
280 | cNewJsn += cLetra
281 | endif
282 | elseif cLetra == ":"
283 | if !lInString
284 | cNewJsn += ": "
285 | else
286 | cNewJsn += cLetra
287 | endif
288 | elseif cLetra == " " .or. cLetra == CHR_LF .or. cLetra == CHR_HT
289 | if lInString
290 | cNewJsn += cLetra
291 | endif
292 | elseif cLetra == '"'
293 | if cBefore != "\"
294 | lInString := !lInString
295 | endif
296 | cNewJsn += cLetra
297 | else
298 | cNewJsn += cLetra
299 | endif
300 | Next
301 | Return cNewJsn
302 |
303 |
304 | /**
305 | * (User) Function: JsonMinify(cJstr)
306 | * Remove spaces, breaklines, and comments
307 | *
308 | * Comments are not allowed in the JSON specification, but we can remove them with this function.
309 | * Allowed comments:
310 | *
311 | * // Single line comment
312 | *
313 | * /* Multiple Lines
314 | * Multiple Lines
315 | * Multiple Lines */
316 | /*
317 | * Example:
318 | * -----
319 | * cJSON := '{' + CRLF
320 | * cJSON += ' // this is a comment' + CRLF
321 | * cJSON += ' "Products": [35, 50]' + CRLF
322 | * cJSON += '}'
323 | *
324 | * cJSON := JsonMinify(cJSON) // -> returns '{"Products":[35,50]}'
325 | * -----
326 | *
327 | * Function ported from Chris Dary's JSONLint:
328 | * http://jsonlint.com/c/js/jsl.format.js
329 | * https://github.com/arc90/jsonlintdotcom/blob/master/c/js/jsl.format.js
330 | *
331 | * A copy of his license should be at the top of this file.
332 | *
333 | * @param cJstr - The JSON string to Minify
334 | * @return string - Minified JSON string
335 | **/
336 |
337 | Function JsonMinify(cJstr)
338 | Local nConta, cBefore
339 | Local cLetra := ""
340 | Local lInString := .F.
341 | Local cNewJsn := ""
342 | Local lInLineCommt := .F.
343 | Local lMultLineCommt := .F.
344 |
345 | For nConta:= 1 To Len(cJstr)
346 |
347 | cBefore := cLetra
348 | cLetra := SubStr(cJstr, nConta, 1)
349 |
350 | // strip comments
351 | if lInLineCommt
352 | if cLetra == CHR_LF // \n
353 | lInLineCommt := .F.
354 | endif
355 | elseif lMultLineCommt
356 | if cBefore == "*" .and. cLetra == "/"
357 | lMultLineCommt := .F.
358 | endif
359 | elseif !lInString .and. cLetra == "/" .and. SubStr(cJstr, nConta+1, 1) == "/"
360 | lInLineCommt := .T.
361 | elseif !lInString .and. cLetra == "/" .and. SubStr(cJstr, nConta+1, 1) == "*"
362 | lMultLineCommt := .T.
363 |
364 | // real json
365 | elseif cLetra == "{" .or. cLetra == "["
366 | cNewJsn += cLetra
367 | elseif cLetra == "}" .or. cLetra == "]"
368 | cNewJsn += cLetra
369 | elseif cLetra == ","
370 | cNewJsn += cLetra
371 | elseif cLetra == ":"
372 | cNewJsn += cLetra
373 | elseif cLetra == " " .or. cLetra == CHR_LF .or. cLetra == CHR_HT .or. cLetra == CHR_CR
374 | if lInString
375 | cNewJsn += cLetra
376 | endif
377 | elseif cLetra == '"'
378 | if cBefore != "\"
379 | lInString := !lInString
380 | endif
381 | cNewJsn += cLetra
382 | else
383 | cNewJsn += cLetra
384 | endif
385 | Next
386 | Return cNewJsn
387 |
388 |
389 | /**
390 | * (User) Function: ReadJsonFile(cFileName [,lStripComments])
391 | * Reads JSON from a JSON file.
392 | *
393 | * Example:
394 | * -----
395 | * aaConf := ReadJsonFile("D:\TOTVS\Config.json")
396 | * alert(aaConf[#'Product'][35][#'name'])
397 | * -----
398 | *
399 | * @param cFileName - Filename
400 | * @param lStripComments (Optional) - .T. removes comments, .F. doesn't. (Default .T.)
401 | * @return AnyValue - Returns the value of the JSON file
402 | **/
403 |
404 | Function ReadJsonFile(cFileName, lStripComments)
405 | Default lStripComments := .T.
406 | if !File(cFileName)
407 | Return Nil
408 | endif
409 |
410 | if lStripComments
411 | Return FromJson(JsonMinify(MemoRead(cFileName, .F.)))
412 | else
413 | Return FromJson(MemoRead(cFileName, .F.))
414 | endif
415 | Return
416 |
417 |
418 |
419 | /// End of User Functions
420 |
421 |
422 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
423 | // Bellow there are only internal functions which are necessary for the FromJson function
424 |
425 | /// Begin of Internal Functions
426 |
427 |
428 |
429 | /**
430 | * Internal Function: GetJsonVal(cJstr)
431 | * Converts from a JSON string into any value it holds
432 | *
433 | * @param cJstr - The JSON string you want to convert from
434 | * @return array(
435 | * uVal, - Value of the converted JSON string, or Nil in case of a bad formatted JSON string.
436 | * nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
437 | * )
438 | **/
439 |
440 | Static Function GetJsonVal(cJstr)
441 | Local nConta
442 | Local cLetra := ""
443 | Local aTmp
444 |
445 | BEGIN SEQUENCE
446 |
447 | For nConta:= 1 To Len(cJstr)
448 |
449 | cLetra := SubStr(cJstr, nConta, 1)
450 |
451 | if cLetra == '"'
452 | aTmp := JsonStr(SubStr(cJstr, nConta))
453 | BREAK
454 | elseif at(cLetra, "0123456789.-") > 0
455 | aTmp := JsonNum(SubStr(cJstr, nConta))
456 | BREAK
457 | elseif cLetra == "["
458 | aTmp := JsonArr(SubStr(cJstr, nConta))
459 | BREAK
460 | elseif cLetra == "{"
461 | aTmp := JsonObj(SubStr(cJstr, nConta))
462 | BREAK
463 | elseif at(cLetra, "TtFfNn") > 0 //True, False or Null
464 | aTmp := JsonTFN(SubStr(cJstr, nConta))
465 | BREAK
466 | endif
467 |
468 | Next
469 |
470 | END SEQUENCE
471 |
472 | if len(aTmp) > 0
473 | if aTmp[2] < 0
474 | return {Nil, -1} // Error Code
475 | endif
476 |
477 | return {aTmp[1], nConta + aTmp[2] -1}
478 |
479 | endif
480 |
481 | Return {Nil, -1}
482 |
483 |
484 | /**
485 | * Internal Function: JsonArr(cJstr)
486 | * Converts from a JSON string containing only an Array into an Array
487 | *
488 | * @param cJstr - The JSON string you want to convert from
489 | * @return array(
490 | * aVal, - Value of the JSON array, or Nil in case of a bad formatted JSON string.
491 | * nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
492 | * )
493 | **/
494 |
495 | Static Function JsonArr(cJstr)
496 | Local nConta
497 | Local cLetra := ""
498 | Local lNeedComma := .F.
499 | Local aRet := {}
500 | Local aTmp
501 |
502 | BEGIN SEQUENCE
503 |
504 | For nConta:= 2 To Len(cJstr)
505 |
506 | cLetra := SubStr(cJstr, nConta, 1)
507 |
508 | if !lNeedComma .and. at(cLetra, '"{[0123456789.-') > 0
509 | aTmp := GetJsonVal(SubStr(cJstr, nConta))
510 | if aTmp[2] < 0
511 | return {Nil, -1} // Error Code
512 | endif
513 | AADD(aRet, aTmp[1])
514 | nConta := nConta + aTmp[2] -1 // -1 move to last character because the loop will add +1.
515 | lNeedComma := .T.
516 | elseif lNeedComma .and. cLetra == ','
517 | lNeedComma := .F.
518 | elseif cLetra == ']'
519 | return {aRet, nConta}
520 | endif
521 |
522 | Next
523 |
524 | END SEQUENCE
525 |
526 | Return {Nil, -1}
527 |
528 |
529 | /**
530 | * Internal Function: JsonObj(cJstr)
531 | * Converts from a JSON string containing only an Object into an Associative Array (SHash Object)
532 | *
533 | * @param cJstr - The JSON string you want to convert from
534 | * @return array(
535 | * aaVal, - Associative Array (SHash Object) of the JSON object, or Nil in case of a bad formatted JSON string.
536 | * nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
537 | * )
538 | **/
539 |
540 | Static Function JsonObj(cJstr)
541 | Local nConta
542 | Local cLetra := ""
543 | Local cTmpStr := ""
544 | Local nStep := 1
545 | Local aTmp
546 | Local aaRet := array(#)
547 |
548 | BEGIN SEQUENCE
549 |
550 | For nConta:= 2 To Len(cJstr)
551 |
552 | cLetra := SubStr(cJstr, nConta, 1)
553 |
554 | if nStep == 1 .and. cLetra == '"'
555 | aTmp := JsonStr(SubStr(cJstr, nConta))
556 | if aTmp[2] < 0
557 | return {Nil, -1} // Error Code
558 | endif
559 | nConta := nConta + aTmp[2] -1
560 | cTmpStr := aTmp[1]
561 | nStep := 2
562 |
563 | elseif nStep == 2 .and. cLetra == ':'
564 | nStep := 3
565 |
566 | elseif nStep == 3 .and. at(cLetra, '"{[0123456789.-TtFfNn') > 0
567 | aTmp := GetJsonVal(SubStr(cJstr, nConta))
568 | if aTmp[2] < 0
569 | return {Nil, -1} // Error Code
570 | endif
571 | nConta := nConta + aTmp[2] -1
572 | nStep := 4
573 | elseif nStep == 4 .and. cLetra == ','
574 | aaRet[#cTmpStr] := aTmp[1]
575 | nStep := 1
576 | elseif nStep == 4 .and. cLetra == '}'
577 | aaRet[#cTmpStr] := aTmp[1]
578 | return {aaRet, nConta}
579 | endif
580 |
581 | Next
582 |
583 | END SEQUENCE
584 |
585 | Return {Nil, -1}
586 |
587 |
588 | /**
589 | * Internal Function: JsonStr(cJstr)
590 | * Converts from a JSON string containing only a String into a String
591 | *
592 | * @param cJstr - The JSON string you want to convert from
593 | * @return array(
594 | * cVal, - Value of the JSON string, or Nil in case of a bad formatted JSON string.
595 | * nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
596 | * )
597 | **/
598 |
599 | Static Function JsonStr(cJstr)
600 | Local nConta
601 | Local cLetra := ""
602 | Local cTmpStr := ""
603 | Local nUnic
604 |
605 | BEGIN SEQUENCE
606 |
607 | For nConta:= 2 To Len(cJstr)
608 |
609 | cLetra := SubStr(cJstr, nConta, 1)
610 |
611 | if cLetra == "\"
612 | nConta++
613 | cLetra := SubStr(cJstr, nConta, 1)
614 | if cLetra == 'b'
615 | cTmpStr += CHR_BS
616 | elseif cLetra == 'f'
617 | cTmpStr += CHR_FF
618 | elseif cLetra == 'n'
619 | cTmpStr += CHR_LF
620 | elseif cLetra == 'r'
621 | cTmpStr += CHR_CR
622 | elseif cLetra == 't'
623 | cTmpStr += CHR_HT
624 | elseif cLetra == 'u'
625 | nUnic := CTON(UPPER(SubStr(cJstr, nConta+1, 4)),16)
626 | if nUnic <= 255
627 | cTmpStr += chr(nUnic)
628 | else
629 | cTmpStr += '?'
630 | endif
631 | nConta += 4
632 | else
633 | cTmpStr += cLetra //it will add the char if it doesn't have a special function
634 | endif
635 |
636 | elseif cLetra == '"'
637 | return {cTmpStr, nConta}
638 | else
639 | cTmpStr += cLetra
640 | endif
641 |
642 | Next
643 |
644 | END SEQUENCE
645 |
646 | Return {Nil, -1}
647 |
648 |
649 | /**
650 | * Internal Function: JsonNum(cJstr)
651 | * Converts from a JSON string containing only a Number into a Number
652 | * It accepts the (Scientific) E Notation
653 | *
654 | * @param cJstr - The JSON string you want to convert from
655 | * @return array(
656 | * nVal, - Value of the JSON number, or Nil in case of a bad formatted JSON string.
657 | * nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
658 | * )
659 | **/
660 |
661 | Static Function JsonNum(cJstr)
662 | Local nConta, nNum, aTmp
663 | Local cLetra := ""
664 | Local cTmpStr := ""
665 | Local lNegExp := .F.
666 |
667 | BEGIN SEQUENCE
668 |
669 | For nConta:= 1 To Len(cJstr)
670 |
671 | cLetra := SubStr(cJstr, nConta, 1)
672 |
673 | if at(cLetra, '0123456789.-') > 0
674 | cTmpStr += cLetra
675 |
676 | elseif len(cLetra) > 0 .and. UPPER(cLetra) == 'E'
677 | nNum := val(cTmpStr)
678 | cTmpStr := ""
679 | nConta++
680 | cLetra := SubStr(cJstr, nConta, 1)
681 | if cLetra == '-'
682 | lNegExp := .T.
683 | nConta++
684 | elseif cLetra == '+'
685 | nConta++
686 | endif
687 | cLetra := SubStr(cJstr, nConta, 1)
688 |
689 | while at(cLetra, '0123456789') > 0
690 | cTmpStr += cLetra
691 | nConta++
692 | cLetra := SubStr(cJstr, nConta, 1)
693 | end
694 |
695 | if lNegExp
696 | //nNum := nNum / val('1'+REPLICATE( '0', val(cTmpStr) ))
697 | if val(cTmpStr) != 0
698 | nNum := nNum * val('0.'+REPLICATE( '0', val(cTmpStr)-1) + '1')
699 | endif
700 | else
701 | nNum := nNum * val('1'+REPLICATE( '0', val(cTmpStr) ))
702 | endif
703 |
704 | return {nNum, nConta-1}
705 |
706 | elseif len(cLetra) > 0
707 | return {val(cTmpStr), nConta-1}
708 | endif
709 |
710 | Next
711 |
712 | END SEQUENCE
713 |
714 | Return {Nil, -1}
715 |
716 |
717 | /**
718 | * Internal Function: JsonTFN(cJstr)
719 | * Converts from a JSON string containing only a logical True, False or Null
720 | *
721 | * @param cJstr - The JSON string you want to convert from
722 | * @return array(
723 | * lVal, - Value of the JSON logical value, or Nil in case of Null or a bad formatted JSON string.
724 | * nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
725 | * )
726 | **/
727 |
728 | Static Function JsonTFN(cJstr)
729 | Local cTmpStr
730 |
731 | BEGIN SEQUENCE
732 |
733 | cTmpStr := lower(SubStr(cJstr, 1, 5))
734 |
735 | if cTmpStr == "false"
736 | return {.F., 5}
737 | endif
738 |
739 | cTmpStr := SubStr(cTmpStr, 1, 4)
740 |
741 | if cTmpStr == "true"
742 | return {.T., 4}
743 | elseif cTmpStr == "null"
744 | return {Nil, 4}
745 | endif
746 |
747 | END SEQUENCE
748 |
749 | Return {Nil, -1}
750 |
751 |
--------------------------------------------------------------------------------
/Util/RmvCharEsp.prw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielAlbuquerque/ADVPL-API-APP-ESTOQUE/f8c51639d7ef712508bb0e5d955d4d51f85109fb/Util/RmvCharEsp.prw
--------------------------------------------------------------------------------
/Util/SHash.prg:
--------------------------------------------------------------------------------
1 | /*----------------------------------------------------------------------*\
2 | * SHASH - A Simple Hash (Associative Array) for AdvPL
3 | * Copyright (C) 2013 Arthur Helfstein Fragoso
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published
7 | * by the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | *
18 | * This class is an adapted version of Marinaldo de Jesus' THASH Class:
19 | *
20 | * https://code.google.com/p/totvs-AdvPL-naldodj/source/browse/trunk/templates/P10/ndj_01/Projeto/NDJLib/NDJLIB022.prg
21 | *
22 | * See the aarray.ch header file for instruction on how to use it.
23 | *
24 | \*----------------------------------------------------------------------*/
25 |
26 | #include "msobject.ch"
27 | #include "shash.ch"
28 |
29 | /*/
30 | CLASS: SHASH
31 | Autor: Marinaldo de Jesus
32 | Adaptado por: Arthur Helfstein Fragoso
33 | Descricao: Simple Hash, Associative Array
34 | Sintaxe: SHASH():New() -> Objeto do Tipo SHASH
35 | /*/
36 | CLASS SHASH
37 |
38 | DATA aData
39 | DATA cClassName
40 |
41 | METHOD NEW() CONSTRUCTOR
42 |
43 | METHOD ClassName()
44 |
45 | METHOD GetAt( uPropertyKey )
46 | METHOD Get( uPropertyKey , uDefaultValue )
47 | METHOD Set( uPropertyKey , uValue )
48 | METHOD Remove( uPropertyKey )
49 | METHOD GetAll( )
50 |
51 | ENDCLASS
52 |
53 | User Function SHASH()
54 | Return( SHASH():New() )
55 |
56 | /*/
57 | METHOD: New
58 | Autor: Marinaldo de Jesus
59 | Data: 04/12/2011
60 | Descricao: CONSTRUCTOR
61 | Sintaxe: SHASH():New() -> Self
62 | /*/
63 | METHOD New() CLASS SHASH
64 |
65 | Self:aData := Array( 0 )
66 | Self:cClassName := "SHASH"
67 |
68 | Return( Self )
69 |
70 | /*/
71 | METHOD: ClassName
72 | Autor: Marinaldo de Jesus
73 | Data: 04/12/2011
74 | Descricao: Retornar o Nome da Classe
75 | Sintaxe: SHASH():ClassName() -> cClassName
76 | /*/
77 | METHOD ClassName() CLASS SHASH
78 | Return( Self:cClassName )
79 |
80 | /*/
81 | METHOD: GetAt
82 | Autor: Marinaldo de Jesus
83 | Data: 04/12/2011
84 | Descricao: Obter a Posicao da Propriedade Passada por parametro e de acordo com a Secao
85 | Sintaxe: SHASH():GetAt( uPropertyKey ) -> nATProperty
86 | /*/
87 | METHOD GetAt( uPropertyKey ) CLASS SHASH
88 |
89 | Local nATProperty := 0
90 |
91 | BEGIN SEQUENCE
92 |
93 | nATProperty := aScan( Self:aData, { |aValues| ( Compare( aValues[ SPROPERTY_KEY ] , uPropertyKey ) ) } )
94 |
95 | END SEQUENCE
96 |
97 | Return( nATProperty )
98 |
99 | /*/
100 | METHOD: Get
101 | Autor: Marinaldo de Jesus
102 | Data: 04/12/2011
103 | Descricao: Obter o valor da Propriedade Passada por parametro e de acordo com a Secao
104 | Sintaxe: SHASH():Get( uPropertyKey , uDefaultValue ) -> uPropertyValue
105 | /*/
106 | METHOD Get( uPropertyKey , uDefaultValue ) CLASS SHASH
107 |
108 | Local uPropertyValue := "@__PROPERTY_NOT_FOUND__@"
109 |
110 | Local nProperty
111 |
112 | BEGIN SEQUENCE
113 |
114 | nProperty := Self:GetAt( @uPropertyKey )
115 | IF ( nProperty == 0 )
116 | BREAK
117 | EndIF
118 |
119 | uPropertyValue := Self:aData[ nProperty ][ SPROPERTY_VALUE ]
120 |
121 | END SEQUENCE
122 |
123 | IF ( Compare( uPropertyValue , "@__PROPERTY_NOT_FOUND__@" ) )
124 | IF !Empty( uDefaultValue )
125 | uPropertyValue := uDefaultValue
126 | Else
127 | uPropertyValue := NIL
128 | EndIF
129 | EndIF
130 |
131 | Return( uPropertyValue )
132 |
133 | /*/
134 | METHOD: AddNewProperty
135 | Autor: Marinaldo de Jesus
136 | Data: 04/12/2011
137 | Descricao: Adiciona ou Edita uma propriedade
138 | Sintaxe: SHASH():Set( uPropertyKey , uValue ) -> lSuccess
139 | /*/
140 | METHOD Set( uPropertyKey , uValue ) CLASS SHASH
141 |
142 | Local lSuccess := .F.
143 |
144 | Local nProperty
145 |
146 | BEGIN SEQUENCE
147 |
148 | nProperty := Self:GetAt( @uPropertyKey )
149 |
150 | IF ( nProperty == 0 )
151 | aAdd( Self:aData , Array( SPROPERTY_ELEMENTS ) )
152 | nProperty := Len( Self:aData )
153 | EndIF
154 |
155 | Self:aData[ nProperty ][ SPROPERTY_KEY ] := uPropertyKey
156 | Self:aData[ nProperty ][ SPROPERTY_VALUE ] := uValue
157 |
158 | lSuccess := .T.
159 |
160 | END SEQUENCE
161 |
162 | Return( lSuccess )
163 |
164 | /*/
165 | METHOD: Remove
166 | Autor: Marinaldo de Jesus
167 | Data: 04/12/2011
168 | Descricao: Remover Determinada Propriedade
169 | Sintaxe: SHASH():Remove( uPropertyKey ) -> lSuccess
170 | /*/
171 | METHOD Remove( uPropertyKey ) CLASS SHASH
172 |
173 | Local lSuccess := .F.
174 |
175 | Local nProperty
176 |
177 | BEGIN SEQUENCE
178 |
179 | nProperty := Self:GetAt( @uPropertyKey )
180 | IF ( nProperty == 0 )
181 | BREAK
182 | EndIF
183 |
184 | lSuccess := .T.
185 |
186 | aDel( Self:aData , nProperty )
187 | aSize( Self:aData , Len( Self:aData[ nSession ][ SPROPERTY_POSITION ] ) - 1 )
188 |
189 | END SEQUENCE
190 |
191 | Return( lSuccess )
192 |
193 | /*/
194 | METHOD: GetAll
195 | Autor: Marinaldo de Jesus
196 | Data: 04/12/2011
197 | Descricao: Retornar todas as propriedades
198 | Sintaxe: SHASH():GetAll( ) -> aAllProperties
199 | /*/
200 | METHOD GetAll() CLASS SHASH
201 | Return( Self:aData )
202 |
203 |
204 |
--------------------------------------------------------------------------------